diff options
| author | Andrew Innes | 1998-06-22 17:43:15 +0000 |
|---|---|---|
| committer | Andrew Innes | 1998-06-22 17:43:15 +0000 |
| commit | bbb059f3909548abe29e41578fe854c1530f704a (patch) | |
| tree | da3269c4d3d024b95ead5acaec731268514c0c03 /src/w32select.c | |
| parent | 375fcc095fc5a4417fed9cbe2816db214350513b (diff) | |
| download | emacs-bbb059f3909548abe29e41578fe854c1530f704a.tar.gz emacs-bbb059f3909548abe29e41578fe854c1530f704a.zip | |
Include buffer.h, charset.h, and coding.h.
(Vclipboard_coding_system): New variable.
(syms_of_w32select): DEF_VAR it.
(Fw32_set_clipboard_data): Encode string using
Vclipboard_coding_system if necessary.
(Fw32_get_clipboard_data): Decode clipboard contents using
Vclipboard_coding_system if necessary.
Diffstat (limited to 'src/w32select.c')
| -rw-r--r-- | src/w32select.c | 212 |
1 files changed, 145 insertions, 67 deletions
diff --git a/src/w32select.c b/src/w32select.c index 23a0b5deaa0..883a6292183 100644 --- a/src/w32select.c +++ b/src/w32select.c | |||
| @@ -26,9 +26,16 @@ Boston, MA 02111-1307, USA. */ | |||
| 26 | #include "dispextern.h" /* frame.h seems to want this */ | 26 | #include "dispextern.h" /* frame.h seems to want this */ |
| 27 | #include "frame.h" /* Need this to get the X window of selected_frame */ | 27 | #include "frame.h" /* Need this to get the X window of selected_frame */ |
| 28 | #include "blockinput.h" | 28 | #include "blockinput.h" |
| 29 | #include "buffer.h" | ||
| 30 | #include "charset.h" | ||
| 31 | #include "coding.h" | ||
| 29 | 32 | ||
| 30 | Lisp_Object QCLIPBOARD; | 33 | Lisp_Object QCLIPBOARD; |
| 31 | 34 | ||
| 35 | /* Coding system for communicating with other Windows programs via the | ||
| 36 | clipboard. */ | ||
| 37 | static Lisp_Object Vclipboard_coding_system; | ||
| 38 | |||
| 32 | #if 0 | 39 | #if 0 |
| 33 | DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0, | 40 | DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0, |
| 34 | "This opens the clipboard with the given frame pointer.") | 41 | "This opens the clipboard with the given frame pointer.") |
| @@ -100,51 +107,93 @@ DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, Sw32_set_clipboard_dat | |||
| 100 | 107 | ||
| 101 | BLOCK_INPUT; | 108 | BLOCK_INPUT; |
| 102 | 109 | ||
| 103 | nbytes = XSTRING (string)->size + 1; | 110 | nbytes = STRING_BYTES (XSTRING (string)) + 1; |
| 104 | src = XSTRING (string)->data; | 111 | src = XSTRING (string)->data; |
| 105 | 112 | ||
| 106 | /* need to know final size after '\r' chars are inserted (the | 113 | { |
| 107 | standard CF_TEXT clipboard format uses CRLF line endings, | 114 | /* Since we are now handling multilingual text, we must consider |
| 108 | while Emacs uses just LF internally) */ | 115 | encoding text for the clipboard. */ |
| 116 | int charsets[MAX_CHARSET + 1]; | ||
| 117 | int num; | ||
| 118 | |||
| 119 | bzero (charsets, (MAX_CHARSET + 1) * sizeof (int)); | ||
| 120 | num = ((nbytes <= 2 /* Check the possibility of short cut. */ | ||
| 121 | || NILP (buffer_defaults.enable_multibyte_characters)) | ||
| 122 | ? 0 | ||
| 123 | : find_charset_in_str (src, nbytes, charsets, Qnil, 1)); | ||
| 124 | |||
| 125 | if (!num || (num == 1 && charsets[CHARSET_ASCII])) | ||
| 126 | { | ||
| 127 | /* No multibyte character in OBJ. We need not encode it. */ | ||
| 109 | 128 | ||
| 110 | truelen = nbytes; | 129 | /* need to know final size after '\r' chars are inserted (the |
| 111 | dst = src; | 130 | standard CF_TEXT clipboard format uses CRLF line endings, |
| 112 | /* avoid using strchr because it recomputes the length everytime */ | 131 | while Emacs uses just LF internally) */ |
| 113 | while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL) | ||
| 114 | { | ||
| 115 | truelen++; | ||
| 116 | dst++; | ||
| 117 | } | ||
| 118 | 132 | ||
| 119 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) | 133 | truelen = nbytes; |
| 120 | goto error; | 134 | dst = src; |
| 135 | /* avoid using strchr because it recomputes the length everytime */ | ||
| 136 | while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL) | ||
| 137 | { | ||
| 138 | truelen++; | ||
| 139 | dst++; | ||
| 140 | } | ||
| 121 | 141 | ||
| 122 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) | 142 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) |
| 123 | goto error; | 143 | goto error; |
| 144 | |||
| 145 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) | ||
| 146 | goto error; | ||
| 124 | 147 | ||
| 125 | /* convert to CRLF line endings expected by clipboard */ | 148 | /* convert to CRLF line endings expected by clipboard */ |
| 126 | while (1) | 149 | while (1) |
| 127 | { | 150 | { |
| 128 | unsigned char *next; | 151 | unsigned char *next; |
| 129 | /* copy next line or remaining bytes including '\0' */ | 152 | /* copy next line or remaining bytes including '\0' */ |
| 130 | next = _memccpy (dst, src, '\n', nbytes); | 153 | next = _memccpy (dst, src, '\n', nbytes); |
| 131 | if (next) | 154 | if (next) |
| 132 | { | 155 | { |
| 133 | /* copied one line ending with '\n' */ | 156 | /* copied one line ending with '\n' */ |
| 134 | int copied = next - dst; | 157 | int copied = next - dst; |
| 135 | nbytes -= copied; | 158 | nbytes -= copied; |
| 136 | src += copied; | 159 | src += copied; |
| 137 | /* insert '\r' before '\n' */ | 160 | /* insert '\r' before '\n' */ |
| 138 | next[-1] = '\r'; | 161 | next[-1] = '\r'; |
| 139 | next[0] = '\n'; | 162 | next[0] = '\n'; |
| 140 | dst = next + 1; | 163 | dst = next + 1; |
| 141 | } | 164 | } |
| 142 | else | 165 | else |
| 143 | /* copied remaining partial line -> now finished */ | 166 | /* copied remaining partial line -> now finished */ |
| 144 | break; | 167 | break; |
| 145 | } | 168 | } |
| 146 | 169 | ||
| 147 | GlobalUnlock (htext); | 170 | GlobalUnlock (htext); |
| 171 | } | ||
| 172 | else | ||
| 173 | { | ||
| 174 | /* We must encode contents of OBJ to compound text format. | ||
| 175 | The format is compatible with what the target `STRING' | ||
| 176 | expects if OBJ contains only ASCII and Latin-1 | ||
| 177 | characters. */ | ||
| 178 | int bufsize; | ||
| 179 | struct coding_system coding; | ||
| 180 | HANDLE htext2; | ||
| 181 | |||
| 182 | setup_coding_system | ||
| 183 | (Fcheck_coding_system (Vclipboard_coding_system), &coding); | ||
| 184 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 185 | bufsize = encoding_buffer_size (&coding, nbytes); | ||
| 186 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL) | ||
| 187 | goto error; | ||
| 188 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) | ||
| 189 | goto error; | ||
| 190 | encode_coding (&coding, src, dst, nbytes, bufsize); | ||
| 191 | GlobalUnlock (htext); | ||
| 192 | /* Shrink data block to actual size. */ | ||
| 193 | htext2 = GlobalReAlloc (htext, coding.produced, GMEM_MOVEABLE | GMEM_DDESHARE); | ||
| 194 | if (htext2 != NULL) htext = htext2; | ||
| 195 | } | ||
| 196 | } | ||
| 148 | 197 | ||
| 149 | if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) | 198 | if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) |
| 150 | goto error; | 199 | goto error; |
| @@ -196,41 +245,62 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, Sw32_get_clipboard_dat | |||
| 196 | 245 | ||
| 197 | nbytes = strlen (src); | 246 | nbytes = strlen (src); |
| 198 | 247 | ||
| 199 | /* need to know final size after '\r' chars are removed because | 248 | if (! NILP (buffer_defaults.enable_multibyte_characters)) |
| 200 | we can't change the string size manually, and doing an extra | ||
| 201 | copy is silly */ | ||
| 202 | |||
| 203 | truelen = nbytes; | ||
| 204 | dst = src; | ||
| 205 | /* avoid using strchr because it recomputes the length everytime */ | ||
| 206 | while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL) | ||
| 207 | { | 249 | { |
| 208 | truelen--; | 250 | int bufsize; |
| 209 | dst++; | 251 | unsigned char *buf; |
| 252 | struct coding_system coding; | ||
| 253 | |||
| 254 | setup_coding_system | ||
| 255 | (Fcheck_coding_system(Vclipboard_coding_system), &coding); | ||
| 256 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 257 | bufsize = decoding_buffer_size (&coding, nbytes); | ||
| 258 | buf = (unsigned char *) xmalloc (bufsize); | ||
| 259 | decode_coding (&coding, src, buf, nbytes, bufsize); | ||
| 260 | truelen = (coding.fake_multibyte | ||
| 261 | ? multibyte_chars_in_text (buf, coding.produced) | ||
| 262 | : coding.produced_char); | ||
| 263 | ret = make_string_from_bytes ((char *) buf, truelen, coding.produced); | ||
| 264 | xfree (buf); | ||
| 210 | } | 265 | } |
| 266 | else | ||
| 267 | { | ||
| 268 | /* need to know final size after '\r' chars are removed because | ||
| 269 | we can't change the string size manually, and doing an extra | ||
| 270 | copy is silly */ | ||
| 271 | |||
| 272 | truelen = nbytes; | ||
| 273 | dst = src; | ||
| 274 | /* avoid using strchr because it recomputes the length everytime */ | ||
| 275 | while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL) | ||
| 276 | { | ||
| 277 | truelen--; | ||
| 278 | dst++; | ||
| 279 | } | ||
| 211 | 280 | ||
| 212 | ret = make_uninit_string (truelen); | 281 | ret = make_uninit_string (truelen); |
| 213 | 282 | ||
| 214 | /* convert CRLF line endings (the standard CF_TEXT clipboard | 283 | /* convert CRLF line endings (the standard CF_TEXT clipboard |
| 215 | format) to LF endings as used internally by Emacs */ | 284 | format) to LF endings as used internally by Emacs */ |
| 216 | 285 | ||
| 217 | dst = XSTRING (ret)->data; | 286 | dst = XSTRING (ret)->data; |
| 218 | while (1) | 287 | while (1) |
| 219 | { | ||
| 220 | unsigned char *next; | ||
| 221 | /* copy next line or remaining bytes excluding '\0' */ | ||
| 222 | next = _memccpy (dst, src, '\r', nbytes); | ||
| 223 | if (next) | ||
| 224 | { | 288 | { |
| 225 | /* copied one line ending with '\r' */ | 289 | unsigned char *next; |
| 226 | int copied = next - dst; | 290 | /* copy next line or remaining bytes excluding '\0' */ |
| 227 | nbytes -= copied; | 291 | next = _memccpy (dst, src, '\r', nbytes); |
| 228 | dst += copied - 1; /* overwrite '\r' */ | 292 | if (next) |
| 229 | src += copied; | 293 | { |
| 230 | } | 294 | /* copied one line ending with '\r' */ |
| 231 | else | 295 | int copied = next - dst; |
| 232 | /* copied remaining partial line -> now finished */ | 296 | nbytes -= copied; |
| 233 | break; | 297 | dst += copied - 1; /* overwrite '\r' */ |
| 298 | src += copied; | ||
| 299 | } | ||
| 300 | else | ||
| 301 | /* copied remaining partial line -> now finished */ | ||
| 302 | break; | ||
| 303 | } | ||
| 234 | } | 304 | } |
| 235 | 305 | ||
| 236 | GlobalUnlock (htext); | 306 | GlobalUnlock (htext); |
| @@ -295,5 +365,13 @@ syms_of_w32select () | |||
| 295 | defsubr (&Sw32_get_clipboard_data); | 365 | defsubr (&Sw32_get_clipboard_data); |
| 296 | defsubr (&Sx_selection_exists_p); | 366 | defsubr (&Sx_selection_exists_p); |
| 297 | 367 | ||
| 368 | DEFVAR_LISP ("clipboard-coding-system", &Vclipboard_coding_system, | ||
| 369 | "Coding system for communicating with other X clients.\n\ | ||
| 370 | When sending or receiving text via cut_buffer, selection, and clipboard,\n\ | ||
| 371 | the text is encoded or decoded by this coding system.\n\ | ||
| 372 | A default value is `compound-text'"); | ||
| 373 | Vclipboard_coding_system=intern ("iso-latin-1-dos"); | ||
| 374 | staticpro(&Vclipboard_coding_system); | ||
| 375 | |||
| 298 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); | 376 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); |
| 299 | } | 377 | } |