To: vim-dev@vim.org Subject: Patch 6.2.345 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.345 (extra) Problem: Win32: Copy/paste between two Vims fails if 'encoding' is not set properly or there are illegal bytes. Solution: Use a raw byte format. Always set it when copying. When pasting use the raw format if 'encoding' is the same. Files: src/os_mswin.c, src/os_win16.c, src/os_win32.c, src/vim.h *** ../vim-6.2.344/src/os_mswin.c Tue Mar 9 14:24:17 2004 --- src/os_mswin.c Wed Mar 10 21:11:19 2004 *************** *** 929,934 **** --- 929,936 ---- 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; /* *************** *** 1123,1137 **** void clip_mch_request_selection(VimClipboard *cbd) { ! VimClipType_t metadata = { -1, -1, -1 }; HGLOBAL hMem = NULL; char_u *str = NULL; #if defined(FEAT_MBYTE) && defined(WIN3264) char_u *to_free = NULL; #endif char_u *hMemStr = NULL; int str_size = 0; int maxlen; /* * Don't pass GetActiveWindow() as an argument to OpenClipboard() because --- 1125,1143 ---- 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 char_u *hMemStr = NULL; int str_size = 0; int maxlen; + size_t n; /* * Don't pass GetActiveWindow() as an argument to OpenClipboard() because *************** *** 1151,1162 **** if ((meta_h = GetClipboardData(cbd->format)) != NULL && (meta_p = (VimClipType_t *)GlobalLock(meta_h)) != NULL) { ! if (GlobalSize(meta_h) >= sizeof(VimClipType_t)) ! memcpy(&metadata, meta_p, sizeof(metadata)); GlobalUnlock(meta_h); } } #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) --- 1157,1201 ---- 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 = 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) *************** *** 1231,1236 **** --- 1270,1278 ---- #endif } } + #ifdef FEAT_MBYTE + } + #endif if (str != NULL && *str != NUL) { *************** *** 1250,1257 **** } /* unlock the global object */ ! if (hMemStr != NULL) GlobalUnlock(hMem); CloseClipboard(); #if defined(FEAT_MBYTE) && defined(WIN3264) vim_free(to_free); --- 1292,1303 ---- } /* 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); *************** *** 1267,1272 **** --- 1313,1319 ---- 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) *************** *** 1284,1289 **** --- 1331,1359 ---- 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 = 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) { *************** *** 1385,1390 **** --- 1455,1462 ---- 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) *** ../vim-6.2.344/src/os_win16.c Sat May 24 17:19:47 2003 --- src/os_win16.c Wed Mar 10 18:32:17 2004 *************** *** 179,184 **** --- 179,185 ---- * character to specify MCHAR, MLINE or MBLOCK. */ clip_star.format = RegisterClipboardFormat("VimClipboard2"); + clip_star.format_raw = RegisterClipboardFormat("VimRawBytes"); #endif } *** ../vim-6.2.344/src/os_win32.c Sun Mar 7 17:03:27 2004 --- src/os_win32.c Wed Mar 10 18:26:06 2004 *************** *** 1540,1545 **** --- 1540,1546 ---- * character to specify MCHAR, MLINE or MBLOCK. */ clip_star.format = RegisterClipboardFormat("VimClipboard2"); + clip_star.format_raw = RegisterClipboardFormat("VimRawBytes"); #endif } *************** *** 2038,2043 **** --- 2039,2045 ---- * 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 */ *** ../vim-6.2.344/src/vim.h Mon Mar 8 12:27:39 2004 --- src/vim.h Wed Mar 10 18:28:34 2004 *************** *** 1520,1525 **** --- 1520,1526 ---- # ifdef MSWIN int_u format; /* Vim's own special clipboard format */ + int_u format_raw; /* Vim's raw text clipboard format */ # endif # ifdef FEAT_GUI_BEOS /* no clipboard at the moment */ *** ../vim-6.2.344/src/version.c Thu Mar 11 20:59:13 2004 --- src/version.c Thu Mar 11 21:01:16 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 345, /**/ -- hundred-and-one symptoms of being an internet addict: 7. You finally do take that vacation, but only after buying a cellular modem and a laptop. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///