aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker1996-05-03 18:45:04 +0000
committerGeoff Voelker1996-05-03 18:45:04 +0000
commit69cddef069c6cc9d2ebdd284936606c69654c90d (patch)
tree151a2d396e94a7f83bca69c7669fb622a8241027 /src
parentf79eea00ad1d33725d75c0e7c5966825003df13e (diff)
downloademacs-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.c145
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