diff options
| author | Geoff Voelker | 1996-05-03 18:45:04 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1996-05-03 18:45:04 +0000 |
| commit | 69cddef069c6cc9d2ebdd284936606c69654c90d (patch) | |
| tree | 151a2d396e94a7f83bca69c7669fb622a8241027 /src | |
| parent | f79eea00ad1d33725d75c0e7c5966825003df13e (diff) | |
| download | emacs-69cddef069c6cc9d2ebdd284936606c69654c90d.tar.gz emacs-69cddef069c6cc9d2ebdd284936606c69654c90d.zip | |
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Calculate exact size of clipboard string with CRs removed or inserted.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32select.c | 145 |
1 files changed, 87 insertions, 58 deletions
diff --git a/src/w32select.c b/src/w32select.c index e7bb0c94007..b99e94a6472 100644 --- a/src/w32select.c +++ b/src/w32select.c | |||
| @@ -86,6 +86,10 @@ DEFUN ("win32-set-clipboard-data", Fwin32_set_clipboard_data, Swin32_set_clipboa | |||
| 86 | { | 86 | { |
| 87 | BOOL ok = TRUE; | 87 | BOOL ok = TRUE; |
| 88 | HANDLE htext; | 88 | HANDLE htext; |
| 89 | int nbytes; | ||
| 90 | int truelen; | ||
| 91 | unsigned char *src; | ||
| 92 | unsigned char *dst; | ||
| 89 | 93 | ||
| 90 | CHECK_STRING (string, 0); | 94 | CHECK_STRING (string, 0); |
| 91 | 95 | ||
| @@ -93,40 +97,52 @@ DEFUN ("win32-set-clipboard-data", Fwin32_set_clipboard_data, Swin32_set_clipboa | |||
| 93 | CHECK_LIVE_FRAME (frame, 0); | 97 | CHECK_LIVE_FRAME (frame, 0); |
| 94 | 98 | ||
| 95 | BLOCK_INPUT; | 99 | BLOCK_INPUT; |
| 96 | 100 | ||
| 97 | /* Allocate twice the amount so we can convert lf to cr-lf */ | 101 | nbytes = XSTRING (string)->size + 1; |
| 98 | 102 | src = XSTRING (string)->data; | |
| 99 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, (2 * XSTRING (string)->size) + 1)) == NULL) | 103 | |
| 104 | /* need to know final size after '\r' chars are inserted (the | ||
| 105 | standard CF_TEXT clipboard format uses CRLF line endings, | ||
| 106 | while Emacs uses just LF internally) */ | ||
| 107 | |||
| 108 | truelen = nbytes; | ||
| 109 | dst = src; | ||
| 110 | /* avoid using strchr because it recomputes the length everytime */ | ||
| 111 | while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL) | ||
| 112 | { | ||
| 113 | truelen++; | ||
| 114 | dst++; | ||
| 115 | } | ||
| 116 | |||
| 117 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) | ||
| 118 | goto error; | ||
| 119 | |||
| 120 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) | ||
| 100 | goto error; | 121 | goto error; |
| 101 | |||
| 102 | { | ||
| 103 | unsigned char *lptext; | ||
| 104 | 122 | ||
| 105 | if ((lptext = (unsigned char *)GlobalLock (htext)) == NULL) | 123 | /* convert to CRLF line endings expected by clipboard */ |
| 106 | goto error; | 124 | while (1) |
| 107 | |||
| 108 | { | 125 | { |
| 109 | int i = XSTRING (string)->size; | 126 | unsigned char *next; |
| 110 | int newsize = XSTRING (string)->size; | 127 | /* copy next line or remaining bytes including '\0' */ |
| 111 | register char *p1 = XSTRING (string)->data; | 128 | next = _memccpy (dst, src, '\n', nbytes); |
| 112 | register char *p2 = lptext; | 129 | if (next) |
| 113 | |||
| 114 | while (i--) | ||
| 115 | { | 130 | { |
| 116 | if (*p1 == '\n') | 131 | /* copied one line ending with '\n' */ |
| 117 | { | 132 | int copied = next - dst; |
| 118 | newsize++; | 133 | nbytes -= copied; |
| 119 | *p2++ = '\r'; | 134 | src += copied; |
| 120 | } | 135 | /* insert '\r' before '\n' */ |
| 121 | 136 | next[-1] = '\r'; | |
| 122 | *p2++ = *p1++; | 137 | next[0] = '\n'; |
| 123 | } | 138 | dst = next + 1; |
| 124 | 139 | } | |
| 125 | *p2 = 0; | 140 | else |
| 141 | /* copied remaining partial line -> now finished */ | ||
| 142 | break; | ||
| 126 | } | 143 | } |
| 127 | 144 | ||
| 128 | GlobalUnlock (htext); | 145 | GlobalUnlock (htext); |
| 129 | } | ||
| 130 | 146 | ||
| 131 | if (!OpenClipboard ((!NILP (frame) && FRAME_WIN32_P (XFRAME (frame))) ? FRAME_WIN32_WINDOW (XFRAME (frame)) : NULL)) | 147 | if (!OpenClipboard ((!NILP (frame) && FRAME_WIN32_P (XFRAME (frame))) ? FRAME_WIN32_WINDOW (XFRAME (frame)) : NULL)) |
| 132 | goto error; | 148 | goto error; |
| @@ -167,41 +183,54 @@ DEFUN ("win32-get-clipboard-data", Fwin32_get_clipboard_data, Swin32_get_clipboa | |||
| 167 | if ((htext = GetClipboardData (CF_TEXT)) == NULL) | 183 | if ((htext = GetClipboardData (CF_TEXT)) == NULL) |
| 168 | goto closeclip; | 184 | goto closeclip; |
| 169 | 185 | ||
| 170 | |||
| 171 | { | 186 | { |
| 172 | unsigned char *lptext; | 187 | unsigned char *src; |
| 188 | unsigned char *dst; | ||
| 173 | int nbytes; | 189 | int nbytes; |
| 190 | int truelen; | ||
| 174 | 191 | ||
| 175 | if ((lptext = (unsigned char *)GlobalLock (htext)) == NULL) | 192 | if ((src = (unsigned char *) GlobalLock (htext)) == NULL) |
| 176 | goto closeclip; | 193 | goto closeclip; |
| 177 | 194 | ||
| 178 | nbytes = strlen (lptext); | 195 | nbytes = strlen (src); |
| 179 | 196 | ||
| 180 | { | 197 | /* need to know final size after '\r' chars are removed because |
| 181 | char *buf = (char *) xmalloc (nbytes); | 198 | we can't change the string size manually, and doing an extra |
| 182 | register char *p1 = lptext; | 199 | copy is silly */ |
| 183 | register char *p2 = buf; | 200 | |
| 184 | int i = nbytes; | 201 | truelen = nbytes; |
| 185 | 202 | dst = src; | |
| 186 | if (buf == NULL) goto closeclip; | 203 | /* avoid using strchr because it recomputes the length everytime */ |
| 187 | 204 | while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL) | |
| 188 | while (i--) | 205 | { |
| 189 | { | 206 | truelen--; |
| 190 | if (p1[0] == '\r' && i && p1[1] == '\n') | 207 | dst++; |
| 191 | { | 208 | } |
| 192 | p1++; | 209 | |
| 193 | i--; | 210 | ret = make_uninit_string (truelen); |
| 194 | nbytes--; | 211 | |
| 195 | } | 212 | /* convert CRLF line endings (the standard CF_TEXT clipboard |
| 196 | 213 | format) to LF endings as used internally by Emacs */ | |
| 197 | *p2++ = *p1++; | 214 | |
| 198 | } | 215 | dst = XSTRING (ret)->data; |
| 199 | 216 | while (1) | |
| 200 | ret = make_string (buf, nbytes); | 217 | { |
| 201 | 218 | unsigned char *next; | |
| 202 | xfree (buf); | 219 | /* copy next line or remaining bytes excluding '\0' */ |
| 203 | } | 220 | next = _memccpy (dst, src, '\r', nbytes); |
| 204 | 221 | if (next) | |
| 222 | { | ||
| 223 | /* copied one line ending with '\r' */ | ||
| 224 | int copied = next - dst; | ||
| 225 | nbytes -= copied; | ||
| 226 | dst += copied - 1; /* overwrite '\r' */ | ||
| 227 | src += copied; | ||
| 228 | } | ||
| 229 | else | ||
| 230 | /* copied remaining partial line -> now finished */ | ||
| 231 | break; | ||
| 232 | } | ||
| 233 | |||
| 205 | GlobalUnlock (htext); | 234 | GlobalUnlock (htext); |
| 206 | } | 235 | } |
| 207 | 236 | ||