On 5/18/07, Gary Johnson <[EMAIL PROTECTED]> wrote:
On 2007-05-17, Gary Johnson <[EMAIL PROTECTED]> wrote:
> On 2007-02-15, Frodak Baksik <[EMAIL PROTECTED]> wrote:
> > On 2/15/07, Chris Sutcliffe wrote:
> > > > > Also, is there anything I can do to help get the original
> > > > > patch accepted?
> > > >
> > > > Ask a few people to try it out and report their results here.
> > >
> > > I'll give it a shot. Is there somewhere I can grab the patch from, or
> > > should I go through the list archives to find it?
>
> > Here are all the changes in a single patch.
> > I'm also posting this to the cygwin-apps mailing list, so if anyone
> > over there could try it out would be nice.
>
> I just applied this patch to the 7.1 source. The patch to
> proto/os_mswin.pro failed, but it was easy to fix manually. The
> problem was that the extern prefix has been removed from the 7.1
> declarations. Hunk #2 of the patch to os_win32.c failed, apparently
> because that change was already made to the 7.1 source, so I left
> that file with only hunk #1 applied.
It looks like I goofed when applying the patch that way. I just
applied the patch to another system, but edited the patch first to
get rid of the failures instead of trying to edit the files
afterwards. All I had to do to the proto/winclip.pro section was to
remove "extern " from the start of all the lines. While editing the
os_win32.c section, I discovered that 'patch' was missing the first
hunk in the target and applying the first hunk of the patch to the
second hunk in the target, causing the application of the second
hunk of the patch to fail. This was cause by the reformatting of a
comment from 7.0 to 7.1. I changed the comment in the patch to
match the comment in the 7.1 source and the entire patch applied
successfully.
Regards,
Gary
--
Gary Johnson | Agilent Technologies
[EMAIL PROTECTED] | Mobile Broadband Division
| Spokane, Washington, USA
I've updated the patch to work with version 7.1. Specifically the
first patch was against version 212 of
https://svn.sourceforge.net/svnroot/vim/vim7. I checked this out,
applied the patch, updated to revision 296, and fixed the conflicts
you mentioned.
Thanks,
Frodak
Index: term.c
===================================================================
--- term.c (revision 296)
+++ term.c (working copy)
@@ -1921,7 +1921,9 @@
# ifdef FEAT_GUI
if (!gui.in_use)
# endif
+# ifndef FEAT_CYGWIN_WIN32_CLIPBOARD
clip_init(FALSE);
+# endif
# endif
if (term_is_xterm)
{
Index: Make_cyg.mak
===================================================================
--- Make_cyg.mak (revision 296)
+++ Make_cyg.mak (working copy)
@@ -420,6 +420,7 @@
$(OUTDIR)/option.o \
$(OUTDIR)/os_win32.o \
$(OUTDIR)/os_mswin.o \
+ $(OUTDIR)/winclip.o \
$(OUTDIR)/pathdef.o \
$(OUTDIR)/popupmnu.o \
$(OUTDIR)/quickfix.o \
Index: configure.in
===================================================================
--- configure.in (revision 296)
+++ configure.in (working copy)
@@ -1969,7 +1969,22 @@
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
if test "x$GUITYPE" = "xNONE"; then
Index: Make_ming.mak
===================================================================
--- Make_ming.mak (revision 296)
+++ Make_ming.mak (working copy)
@@ -388,6 +388,7 @@
$(OUTDIR)/option.o \
$(OUTDIR)/os_win32.o \
$(OUTDIR)/os_mswin.o \
+ $(OUTDIR)/winclip.o \
$(OUTDIR)/pathdef.o \
$(OUTDIR)/popupmnu.o \
$(OUTDIR)/quickfix.o \
Index: proto/winclip.pro
===================================================================
--- proto/winclip.pro (revision 0)
+++ proto/winclip.pro (revision 0)
@@ -0,0 +1,13 @@
+/* winclip.c */
+int utf8_to_ucs2 __ARGS((char_u *instr, int inlen, short_u *outstr,
int *unconvlenp));
+int ucs2_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));
+short_u *enc_to_ucs2 __ARGS((char_u *str, int *lenp));
+char_u *ucs2_to_enc __ARGS((short_u *str, int *lenp));
+void clip_mch_request_selection __ARGS((VimClipboard *cbd));
+void acp_to_enc __ARGS((char_u *str, int str_size, char_u **out, int *outlen));
+void clip_mch_set_selection __ARGS((VimClipboard *cbd));
+/* vim: set ft=c : */
Index: proto/os_mswin.pro
===================================================================
--- proto/os_mswin.pro (revision 296)
+++ proto/os_mswin.pro (working copy)
@@ -22,17 +22,6 @@
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_ucs2 __ARGS((char_u *instr, int inlen, short_u *outstr,
int *unconvlenp));
-int ucs2_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));
-short_u *enc_to_ucs2 __ARGS((char_u *str, int *lenp));
-char_u *ucs2_to_enc __ARGS((short_u *str, int *lenp));
-void clip_mch_request_selection __ARGS((VimClipboard *cbd));
-void acp_to_enc __ARGS((char_u *str, int str_size, char_u **out, int *outlen));
-void clip_mch_set_selection __ARGS((VimClipboard *cbd));
void DumpPutS __ARGS((const char *psz));
int mch_get_winpos __ARGS((int *x, int *y));
void mch_set_winpos __ARGS((int x, int y));
Index: vim.h
===================================================================
--- vim.h (revision 296)
+++ vim.h (working copy)
@@ -1739,7 +1739,7 @@
GdkAtom gtk_sel_atom; /* PRIMARY/CLIPBOARD selection ID */
# endif
-# ifdef MSWIN
+# 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
Index: Make_w16.mak
===================================================================
--- Make_w16.mak (revision 296)
+++ Make_w16.mak (working copy)
@@ -107,6 +107,7 @@
$(INTDIR)\os_win16.obj\
$(INTDIR)\os_msdos.obj\
$(INTDIR)\os_mswin.obj\
+ $(INTDIR)\winclip.obj\
$(INTDIR)\popupmnu.obj\
$(INTDIR)\quickfix.obj\
$(INTDIR)\regexp.obj\
Index: Make_bc5.mak
===================================================================
--- Make_bc5.mak (revision 296)
+++ Make_bc5.mak (working copy)
@@ -638,7 +638,7 @@
!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
Index: feature.h
===================================================================
--- feature.h (revision 296)
+++ feature.h (working copy)
@@ -1050,6 +1050,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
Index: proto.h
===================================================================
--- proto.h (revision 296)
+++ proto.h (working copy)
@@ -47,10 +47,12 @@
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));
Index: Makefile
===================================================================
--- Makefile (revision 296)
+++ Makefile (working copy)
@@ -1534,7 +1534,7 @@
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 os_riscos.pro $(PERL_PRO)
+ os_mswin.pro winclip.pro os_beos.pro os_vms.pro os_riscos.pro
$(PERL_PRO)
# Default target is making the executable and tools
all: $(VIMTARGET) $(TOOLS) languages $(GUI_BUNDLE)
@@ -1675,6 +1675,10 @@
cproto $(PFLAGS) -DWIN16 -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
echo "/* vim: set ft=c : */" >> proto/$@
+winclip.pro: winclip.c
+ cproto $(PFLAGS) -DWIN16 -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
+ echo "/* vim: set ft=c : */" >> proto/$@
+
os_beos.pro: os_beos.c
cproto $(PFLAGS) -D__BEOS__ -UHAVE_CONFIG_H $< > proto/$@
echo "/* vim: set ft=c : */" >> proto/$@
@@ -2472,6 +2476,12 @@
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
@@ -2795,6 +2805,10 @@
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 \
Index: config.h.in
===================================================================
--- config.h.in (revision 296)
+++ config.h.in (working copy)
@@ -372,3 +372,6 @@
/* Define if you want XSMP interaction as well as vanilla swapfile safety */
#undef USE_XSMP_INTERACT
+
+/* Define if you want Cygwin to use the WIN32 clipboard, not
compatible with X11*/
+#undef FEAT_CYGWIN_WIN32_CLIPBOARD
Index: mbyte.c
===================================================================
--- mbyte.c (revision 296)
+++ mbyte.c (working copy)
@@ -585,7 +585,7 @@
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
@@ -3127,7 +3127,7 @@
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.
@@ -4414,7 +4414,7 @@
/* If 'imdisable' is set, XIM is never active. */
if (p_imdisable)
active = FALSE;
-#if !defined (FEAT_GUI_GTK)
+#if !defined(FEAT_GUI_GTK)
else if (input_style & XIMPreeditPosition)
/* There is a problem in switching XIM off when preediting is used,
* and it is not clear how this can be solved. For now, keep XIM on
Index: os_unix.c
===================================================================
--- os_unix.c (revision 296)
+++ os_unix.c (working copy)
@@ -1125,6 +1125,9 @@
#ifdef MACOS_CONVERT
mac_conv_init();
#endif
+#ifdef FEAT_CYGWIN_WIN32_CLIPBOARD
+ win_clip_init();
+#endif
}
static void
Index: os_mswin.c
===================================================================
--- os_mswin.c (revision 296)
+++ os_mswin.c (working copy)
@@ -892,693 +892,8 @@
}
#endif
-#if defined(FEAT_MBYTE) || defined(PROTO)
-/*
- * Convert an UTF-8 string to UCS-2.
- * "instr[inlen]" is the input. "inlen" is in bytes.
- * When "outstr" is NULL only return the number of UCS-2 words produced.
- * Otherwise "outstr" must be a buffer of sufficient size.
- * Returns the number of UCS-2 words produced.
- */
- int
-utf8_to_ucs2(char_u *instr, int inlen, short_u *outstr, int *unconvlenp)
-{
- int outlen = 0;
- char_u *p = instr;
- int todo = inlen;
- int l;
- 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;
- }
-
- if (outstr != NULL)
- *outstr++ = utf_ptr2char(p);
- ++outlen;
- p += l;
- todo -= l;
- }
-
- return outlen;
-}
-
/*
- * Convert an UCS-2 string to UTF-8.
- * The input is "instr[inlen]" with "inlen" in number of ucs-2 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
-ucs2_to_utf8(short_u *instr, int inlen, char_u *outstr)
-{
- int outlen = 0;
- int todo = inlen;
- short_u *p = instr;
- int l;
-
- while (todo > 0)
- {
- if (outstr != NULL)
- {
- l = utf_char2bytes(*p, outstr);
- outstr += l;
- }
- else
- l = utf_char2len(*p);
- ++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;
-}
-
-#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 UCS-2.
- * 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_ucs2(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### -> UCS-2 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_ucs2(str, *lenp, NULL, NULL);
- ret = (WCHAR *)alloc((unsigned)((length + 1) * sizeof(WCHAR)));
- if (ret != NULL)
- {
- utf8_to_ucs2(str, *lenp, (short_u *)ret, NULL);
- ret[length] = 0;
- }
-
- vim_free(allocbuf);
- }
-
- *lenp = length;
- return (short_u *)ret;
-}
-
-/*
- * Convert an UCS-2 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 *
-ucs2_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 UCS-2 -> 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(ucs2_to_utf8(str, *lenp == 0 ? 1 : *lenp, NULL));
- if (utf8_str != NULL)
- {
- *lenp = ucs2_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 */
-
-/*
- * 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 (!OpenClipboard(NULL))
- 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 = ucs2_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 UCS-2. */
- 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 guess it. */
- if (metadata.type == -1)
- metadata.type = (vim_strchr(str, '\n') == NULL) ? MCHAR : MLINE;
-
- /* 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
-}
-
-#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 = ucs2_to_enc((short_u *)widestr, outlen);
- vim_free(widestr);
- }
-}
-#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 UCS-2. This is put on the clipboard as
- * CF_UNICODETEXT. */
- out = (WCHAR *)enc_to_ucs2(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 UCS-2 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 (OpenClipboard(NULL))
- {
- 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 */
-
-
-/*
* Debugging helper: expose the MCH_WRITE_DUMP stuff to other modules
*/
/*ARGSUSED*/
Index: os_win32.c
===================================================================
--- os_win32.c (revision 296)
+++ os_win32.c (working copy)
@@ -1677,16 +1677,7 @@
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");
+ win_clip_init();
#endif
}
@@ -2169,16 +2160,7 @@
#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");
+ win_clip_init();
#endif
/* This will be NULL on anything but NT 4.0 */
Index: Make_ivc.mak
===================================================================
--- Make_ivc.mak (revision 296)
+++ Make_ivc.mak (working copy)
@@ -240,6 +240,7 @@
"$(INTDIR)/ops.obj" \
"$(INTDIR)/option.obj" \
"$(INTDIR)/os_mswin.obj" \
+ "$(INTDIR)/winclip.obj" \
"$(INTDIR)/os_win32.obj" \
"$(INTDIR)/popupmnu.obj" \
"$(INTDIR)/quickfix.obj" \
@@ -594,6 +595,10 @@
# 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
Index: Make_mvc.mak
===================================================================
--- Make_mvc.mak (revision 296)
+++ Make_mvc.mak (working copy)
@@ -417,6 +417,7 @@
$(OUTDIR)\ops.obj \
$(OUTDIR)\option.obj \
$(OUTDIR)\os_mswin.obj \
+ $(OUTDIR)\winclip.obj \
$(OUTDIR)\os_win32.obj \
$(OUTDIR)\pathdef.obj \
$(OUTDIR)\popupmnu.obj \
@@ -908,6 +909,8 @@
$(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)
@@ -1007,6 +1010,7 @@
proto/ops.pro \
proto/option.pro \
proto/os_mswin.pro \
+ proto/winclip.pro \
proto/os_win32.pro \
proto/popupmnu.pro \
proto/quickfix.pro \
Index: auto/configure
===================================================================
--- auto/configure (revision 296)
+++ auto/configure (working copy)
@@ -9265,7 +9265,30 @@
+echo "$as_me:$LINENO: checking for CYGWIN environment" >&5
+echo $ECHO_N "checking for CYGWIN environment... $ECHO_C" >&6
+case `uname` in
+ CYGWIN*) CYGWIN=yes; echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ echo "$as_me:$LINENO: checking for CYGWIN clipboard
support" >&5
+echo $ECHO_N "checking for CYGWIN clipboard support... $ECHO_C" >&6
+ if test "x$with_x" = "xno" ; then
+ OS_EXTRA_SRC=winclip.c; OS_EXTRA_OBJ=objects/winclip.o
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ cat >>confdefs.h <<\_ACEOF
+#define FEAT_CYGWIN_WIN32_CLIPBOARD 1
+_ACEOF
+ else
+ echo "$as_me:$LINENO: result: no - using X11" >&5
+echo "${ECHO_T}no - using X11" >&6
+ fi ;;
+
+ *) CYGWIN=no; echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6;;
+esac
+
if test "$enable_hangulinput" = "yes"; then
if test "x$GUITYPE" = "xNONE"; then
echo "$as_me:$LINENO: result: no GUI selected; hangul input has
been disabled" >&5
Index: winclip.c
===================================================================
--- winclip.c (revision 0)
+++ winclip.c (revision 0)
@@ -0,0 +1,737 @@
+/* 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.
+ */
+
+#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 "proto/winclip.pro"
+#endif
+
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Convert an UTF-8 string to UCS-2.
+ * "instr[inlen]" is the input. "inlen" is in bytes.
+ * When "outstr" is NULL only return the number of UCS-2 words produced.
+ * Otherwise "outstr" must be a buffer of sufficient size.
+ * Returns the number of UCS-2 words produced.
+ */
+ int
+utf8_to_ucs2(char_u *instr, int inlen, short_u *outstr, int *unconvlenp)
+{
+ int outlen = 0;
+ char_u *p = instr;
+ int todo = inlen;
+ int l;
+
+ 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;
+ }
+
+ if (outstr != NULL)
+ *outstr++ = utf_ptr2char(p);
+ ++outlen;
+ p += l;
+ todo -= l;
+ }
+
+ return outlen;
+}
+
+/*
+ * Convert an UCS-2 string to UTF-8.
+ * The input is "instr[inlen]" with "inlen" in number of ucs-2 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
+ucs2_to_utf8(short_u *instr, int inlen, char_u *outstr)
+{
+ int outlen = 0;
+ int todo = inlen;
+ short_u *p = instr;
+ int l;
+
+ while (todo > 0)
+ {
+ if (outstr != NULL)
+ {
+ l = utf_char2bytes(*p, outstr);
+ outstr += l;
+ }
+ else
+ l = utf_char2len(*p);
+ ++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;
+}
+
+#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 UCS-2.
+ * 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_ucs2(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### -> UCS-2 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_ucs2(str, *lenp, NULL, NULL);
+ ret = (WCHAR *)alloc((unsigned)((length + 1) * sizeof(WCHAR)));
+ if (ret != NULL)
+ {
+ utf8_to_ucs2(str, *lenp, (short_u *)ret, NULL);
+ ret[length] = 0;
+ }
+
+ vim_free(allocbuf);
+ }
+
+ *lenp = length;
+ return (short_u *)ret;
+}
+
+/*
+ * Convert an UCS-2 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 *
+ucs2_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 UCS-2 -> 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(ucs2_to_utf8(str, *lenp == 0 ? 1 : *lenp, NULL));
+ if (utf8_str != NULL)
+ {
+ *lenp = ucs2_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 */
+
+/*
+ * 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 (!OpenClipboard(NULL))
+ 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 = ucs2_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 UCS-2. */
+ 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 guess it. */
+ if (metadata.type == -1)
+ metadata.type = (vim_strchr(str, '\n') == NULL) ? MCHAR : MLINE;
+
+ /* 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
+}
+
+#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 = ucs2_to_enc((short_u *)widestr, outlen);
+ vim_free(widestr);
+ }
+}
+#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 UCS-2. This is put on the clipboard as
+ * CF_UNICODETEXT. */
+ out = (WCHAR *)enc_to_ucs2(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 UCS-2 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 (OpenClipboard(NULL))
+ {
+ 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 */
Index: globals.h
===================================================================
--- globals.h (revision 296)
+++ globals.h (working copy)
@@ -764,7 +764,7 @@
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);