diff options
| author | Eli Zaretskii | 1998-07-09 14:02:15 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 1998-07-09 14:02:15 +0000 |
| commit | 583f5d53e6ec09f57efdb4f74fbf8be794883e41 (patch) | |
| tree | 63db476990f8d28717dd697aa73eb9f42a382948 /src/w16select.c | |
| parent | fea4012025820908a43514e824d730ee6b6f1de3 (diff) | |
| download | emacs-583f5d53e6ec09f57efdb4f74fbf8be794883e41.tar.gz emacs-583f5d53e6ec09f57efdb4f74fbf8be794883e41.zip | |
(Vclipboard_coding_system): New variable.
(set_clipboard_data, set_clipboard_data): New parameter Raw
determines whether CRLF <-> NL translation needs to be done. All
callers changed.
(Fw16_set_clipboard_data): Encode the text using
Vclipboard_coding_system, if necessary.
(Fw16_get_clipboard_data): Decode the text using
Vclipboard_coding_system, if necessary.
(syms_of_win16select): DEFVAR Vclipboard_coding_system and
staticpro it.
Diffstat (limited to 'src/w16select.c')
| -rw-r--r-- | src/w16select.c | 166 |
1 files changed, 137 insertions, 29 deletions
diff --git a/src/w16select.c b/src/w16select.c index a181c8466b6..769835e1562 100644 --- a/src/w16select.c +++ b/src/w16select.c | |||
| @@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */ | |||
| 37 | #include "dispextern.h" /* frame.h seems to want this */ | 37 | #include "dispextern.h" /* frame.h seems to want this */ |
| 38 | #include "frame.h" /* Need this to get the X window of selected_frame */ | 38 | #include "frame.h" /* Need this to get the X window of selected_frame */ |
| 39 | #include "blockinput.h" | 39 | #include "blockinput.h" |
| 40 | #include "buffer.h" | ||
| 41 | #include "charset.h" | ||
| 42 | #include "coding.h" | ||
| 40 | 43 | ||
| 41 | /* If ever some function outside this file will need to call any | 44 | /* If ever some function outside this file will need to call any |
| 42 | clipboard-related function, the following prototypes and constants | 45 | clipboard-related function, the following prototypes and constants |
| @@ -57,14 +60,18 @@ Boston, MA 02111-1307, USA. */ | |||
| 57 | unsigned identify_winoldap_version (void); | 60 | unsigned identify_winoldap_version (void); |
| 58 | unsigned open_clipboard (void); | 61 | unsigned open_clipboard (void); |
| 59 | unsigned empty_clipboard (void); | 62 | unsigned empty_clipboard (void); |
| 60 | unsigned set_clipboard_data (unsigned, void *, unsigned); | 63 | unsigned set_clipboard_data (unsigned, void *, unsigned, int); |
| 61 | unsigned get_clipboard_data_size (unsigned); | 64 | unsigned get_clipboard_data_size (unsigned); |
| 62 | unsigned get_clipboard_data (unsigned, void *, unsigned); | 65 | unsigned get_clipboard_data (unsigned, void *, unsigned, int); |
| 63 | unsigned close_clipboard (void); | 66 | unsigned close_clipboard (void); |
| 64 | unsigned clipboard_compact (unsigned); | 67 | unsigned clipboard_compact (unsigned); |
| 65 | 68 | ||
| 66 | Lisp_Object QCLIPBOARD, QPRIMARY; | 69 | Lisp_Object QCLIPBOARD, QPRIMARY; |
| 67 | 70 | ||
| 71 | /* Coding system for communicating with other Windows programs via the | ||
| 72 | clipboard. */ | ||
| 73 | static Lisp_Object Vclipboard_coding_system; | ||
| 74 | |||
| 68 | /* The segment address and the size of the buffer in low | 75 | /* The segment address and the size of the buffer in low |
| 69 | memory used to move data between us and WinOldAp module. */ | 76 | memory used to move data between us and WinOldAp module. */ |
| 70 | 77 | ||
| @@ -216,10 +223,11 @@ free_xfer_buf () | |||
| 216 | 223 | ||
| 217 | /* Copy data into the clipboard, return non-zero if successfull. */ | 224 | /* Copy data into the clipboard, return non-zero if successfull. */ |
| 218 | unsigned | 225 | unsigned |
| 219 | set_clipboard_data (Format, Data, Size) | 226 | set_clipboard_data (Format, Data, Size, Raw) |
| 220 | unsigned Format; | 227 | unsigned Format; |
| 221 | void *Data; | 228 | void *Data; |
| 222 | unsigned Size; | 229 | unsigned Size; |
| 230 | int Raw; | ||
| 223 | { | 231 | { |
| 224 | __dpmi_regs regs; | 232 | __dpmi_regs regs; |
| 225 | unsigned truelen; | 233 | unsigned truelen; |
| @@ -233,11 +241,15 @@ set_clipboard_data (Format, Data, Size) | |||
| 233 | standard CF_TEXT clipboard format uses CRLF line endings, | 241 | standard CF_TEXT clipboard format uses CRLF line endings, |
| 234 | while Emacs uses just LF internally). */ | 242 | while Emacs uses just LF internally). */ |
| 235 | truelen = Size; | 243 | truelen = Size; |
| 236 | /* avoid using strchr because it recomputes the length everytime */ | 244 | |
| 237 | while ((dp = memchr (dp, '\n', Size - (dp - dstart))) != 0) | 245 | if (!Raw) |
| 238 | { | 246 | { |
| 239 | truelen++; | 247 | /* avoid using strchr because it recomputes the length everytime */ |
| 240 | dp++; | 248 | while ((dp = memchr (dp, '\n', Size - (dp - dstart))) != 0) |
| 249 | { | ||
| 250 | truelen++; | ||
| 251 | dp++; | ||
| 252 | } | ||
| 241 | } | 253 | } |
| 242 | 254 | ||
| 243 | if (clipboard_compact (truelen) < truelen) | 255 | if (clipboard_compact (truelen) < truelen) |
| @@ -246,15 +258,20 @@ set_clipboard_data (Format, Data, Size) | |||
| 246 | if ((xbuf_addr = alloc_xfer_buf (truelen)) == 0) | 258 | if ((xbuf_addr = alloc_xfer_buf (truelen)) == 0) |
| 247 | return 0; | 259 | return 0; |
| 248 | 260 | ||
| 249 | /* Move the buffer into the low memory, convert LF into CR-LF pairs. */ | 261 | /* Move the buffer into the low memory, convert LF into CR-LF if needed. */ |
| 250 | dp = Data; | 262 | if (Raw) |
| 251 | buf_offset = xbuf_addr; | 263 | dosmemput (Data, truelen, __tb); |
| 252 | _farsetsel (_dos_ds); | 264 | else |
| 253 | while (Size--) | ||
| 254 | { | 265 | { |
| 255 | if (*dp == '\n') | 266 | dp = Data; |
| 256 | _farnspokeb (buf_offset++, '\r'); | 267 | buf_offset = xbuf_addr; |
| 257 | _farnspokeb (buf_offset++, *dp++); | 268 | _farsetsel (_dos_ds); |
| 269 | while (Size--) | ||
| 270 | { | ||
| 271 | if (*dp == '\n') | ||
| 272 | _farnspokeb (buf_offset++, '\r'); | ||
| 273 | _farnspokeb (buf_offset++, *dp++); | ||
| 274 | } | ||
| 258 | } | 275 | } |
| 259 | 276 | ||
| 260 | /* Calls Int 2Fh/AX=1703h with: | 277 | /* Calls Int 2Fh/AX=1703h with: |
| @@ -299,10 +316,11 @@ get_clipboard_data_size (Format) | |||
| 299 | Warning: this doesn't check whether DATA has enough space to hold | 316 | Warning: this doesn't check whether DATA has enough space to hold |
| 300 | SIZE bytes. */ | 317 | SIZE bytes. */ |
| 301 | unsigned | 318 | unsigned |
| 302 | get_clipboard_data (Format, Data, Size) | 319 | get_clipboard_data (Format, Data, Size, Raw) |
| 303 | unsigned Format; | 320 | unsigned Format; |
| 304 | void *Data; | 321 | void *Data; |
| 305 | unsigned Size; | 322 | unsigned Size; |
| 323 | int Raw; | ||
| 306 | { | 324 | { |
| 307 | __dpmi_regs regs; | 325 | __dpmi_regs regs; |
| 308 | unsigned datalen = 0; | 326 | unsigned datalen = 0; |
| @@ -331,13 +349,14 @@ get_clipboard_data (Format, Data, Size) | |||
| 331 | __dpmi_int(0x2f, ®s); | 349 | __dpmi_int(0x2f, ®s); |
| 332 | if (regs.x.ax != 0) | 350 | if (regs.x.ax != 0) |
| 333 | { | 351 | { |
| 334 | /* Copy data from low memory, remove CR characters if before LF. */ | 352 | /* Copy data from low memory, remove CR |
| 353 | characters before LF if needed. */ | ||
| 335 | _farsetsel (_dos_ds); | 354 | _farsetsel (_dos_ds); |
| 336 | while (Size--) | 355 | while (Size--) |
| 337 | { | 356 | { |
| 338 | register unsigned char c = _farnspeekb (xbuf_addr++); | 357 | register unsigned char c = _farnspeekb (xbuf_addr++); |
| 339 | 358 | ||
| 340 | if ((*dp++ = c) == '\r' && _farnspeekb (xbuf_addr) == '\n') | 359 | if ((*dp++ = c) == '\r' && !Raw && _farnspeekb (xbuf_addr) == '\n') |
| 341 | { | 360 | { |
| 342 | dp--; | 361 | dp--; |
| 343 | *dp++ = '\n'; | 362 | *dp++ = '\n'; |
| @@ -401,7 +420,10 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat | |||
| 401 | { | 420 | { |
| 402 | int ok = 1, ok1 = 1; | 421 | int ok = 1, ok1 = 1; |
| 403 | int nbytes; | 422 | int nbytes; |
| 404 | unsigned char *src; | 423 | unsigned char *src, *dst = NULL; |
| 424 | int charsets[MAX_CHARSET + 1]; | ||
| 425 | int num; | ||
| 426 | int no_crlf_conversion; | ||
| 405 | 427 | ||
| 406 | CHECK_STRING (string, 0); | 428 | CHECK_STRING (string, 0); |
| 407 | 429 | ||
| @@ -414,14 +436,50 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat | |||
| 414 | 436 | ||
| 415 | BLOCK_INPUT; | 437 | BLOCK_INPUT; |
| 416 | 438 | ||
| 417 | nbytes = XSTRING (string)->size + 1; | 439 | nbytes = STRING_BYTES (XSTRING (string)) + 1; |
| 418 | src = XSTRING (string)->data; | 440 | src = XSTRING (string)->data; |
| 419 | 441 | ||
| 442 | /* Since we are now handling multilingual text, we must consider | ||
| 443 | encoding text for the clipboard. */ | ||
| 444 | |||
| 445 | bzero (charsets, (MAX_CHARSET + 1) * sizeof (int)); | ||
| 446 | num = ((nbytes <= 2 /* Check the possibility of short cut. */ | ||
| 447 | || NILP (buffer_defaults.enable_multibyte_characters)) | ||
| 448 | ? 0 | ||
| 449 | : find_charset_in_str (src, nbytes, charsets, Qnil, 1)); | ||
| 450 | |||
| 451 | if (!num || (num == 1 && charsets[CHARSET_ASCII])) | ||
| 452 | { | ||
| 453 | /* No multibyte character in OBJ. We need not encode it, but we | ||
| 454 | will have to convert it to DOS CR-LF style. */ | ||
| 455 | no_crlf_conversion = 0; | ||
| 456 | } | ||
| 457 | else | ||
| 458 | { | ||
| 459 | /* We must encode contents of STRING according to what | ||
| 460 | clipboard-coding-system specifies. */ | ||
| 461 | int bufsize; | ||
| 462 | struct coding_system coding; | ||
| 463 | unsigned char *htext2; | ||
| 464 | |||
| 465 | setup_coding_system | ||
| 466 | (Fcheck_coding_system (Vclipboard_coding_system), &coding); | ||
| 467 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 468 | Vlast_coding_system_used = coding.symbol; | ||
| 469 | bufsize = encoding_buffer_size (&coding, nbytes); | ||
| 470 | dst = (unsigned char *) xmalloc (bufsize); | ||
| 471 | encode_coding (&coding, src, dst, nbytes, bufsize); | ||
| 472 | no_crlf_conversion = 1; | ||
| 473 | } | ||
| 474 | |||
| 420 | if (!open_clipboard ()) | 475 | if (!open_clipboard ()) |
| 421 | goto error; | 476 | goto error; |
| 422 | 477 | ||
| 423 | ok = empty_clipboard () && (ok1 = set_clipboard_data (CF_TEXT, src, nbytes)); | 478 | ok = empty_clipboard () |
| 424 | 479 | && (ok1 = set_clipboard_data (CF_TEXT, src, nbytes, no_crlf_conversion)); | |
| 480 | |||
| 481 | if (!no_crlf_conversion) | ||
| 482 | Vlast_coding_system_used = Qraw_text; | ||
| 425 | close_clipboard (); | 483 | close_clipboard (); |
| 426 | 484 | ||
| 427 | if (ok) goto unblock; | 485 | if (ok) goto unblock; |
| @@ -431,6 +489,8 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat | |||
| 431 | ok = 0; | 489 | ok = 0; |
| 432 | 490 | ||
| 433 | unblock: | 491 | unblock: |
| 492 | if (dst) | ||
| 493 | xfree (dst); | ||
| 434 | UNBLOCK_INPUT; | 494 | UNBLOCK_INPUT; |
| 435 | 495 | ||
| 436 | /* Notify user if the text is too large to fit into DOS memory. | 496 | /* Notify user if the text is too large to fit into DOS memory. |
| @@ -457,10 +517,9 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat | |||
| 457 | unsigned data_size, truelen; | 517 | unsigned data_size, truelen; |
| 458 | unsigned char *htext; | 518 | unsigned char *htext; |
| 459 | Lisp_Object ret = Qnil; | 519 | Lisp_Object ret = Qnil; |
| 460 | 520 | int no_crlf_conversion; | |
| 461 | if (!NILP (frame)) | 521 | int require_encoding = 0; |
| 462 | CHECK_LIVE_FRAME (frame, 0); | 522 | |
| 463 | |||
| 464 | if (NILP (frame)) | 523 | if (NILP (frame)) |
| 465 | frame = Fselected_frame (); | 524 | frame = Fselected_frame (); |
| 466 | 525 | ||
| @@ -480,10 +539,51 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat | |||
| 480 | /* need to know final size after '\r' chars are removed because | 539 | /* need to know final size after '\r' chars are removed because |
| 481 | we can't change the string size manually, and doing an extra | 540 | we can't change the string size manually, and doing an extra |
| 482 | copy is silly */ | 541 | copy is silly */ |
| 483 | if ((truelen = get_clipboard_data (CF_TEXT, htext, data_size)) == 0) | 542 | if ((truelen = get_clipboard_data (CF_TEXT, htext, data_size, 0)) == 0) |
| 484 | goto closeclip; | 543 | goto closeclip; |
| 485 | 544 | ||
| 486 | ret = make_string (htext, truelen); | 545 | /* Do we need to decode it? */ |
| 546 | if (! NILP (buffer_defaults.enable_multibyte_characters)) | ||
| 547 | { | ||
| 548 | /* If the clipboard data contains any 8-bit Latin-1 code, we | ||
| 549 | need to decode it. */ | ||
| 550 | int i; | ||
| 551 | |||
| 552 | for (i = 0; i < truelen; i++) | ||
| 553 | { | ||
| 554 | if (htext[i] >= 0x80) | ||
| 555 | { | ||
| 556 | require_encoding = 1; | ||
| 557 | break; | ||
| 558 | } | ||
| 559 | } | ||
| 560 | } | ||
| 561 | if (require_encoding) | ||
| 562 | { | ||
| 563 | int bufsize; | ||
| 564 | unsigned char *buf; | ||
| 565 | struct coding_system coding; | ||
| 566 | |||
| 567 | setup_coding_system | ||
| 568 | (Fcheck_coding_system (Vclipboard_coding_system), &coding); | ||
| 569 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 570 | truelen = get_clipboard_data (CF_TEXT, htext, data_size, 1); | ||
| 571 | bufsize = decoding_buffer_size (&coding, truelen); | ||
| 572 | buf = (unsigned char *) xmalloc (bufsize); | ||
| 573 | decode_coding (&coding, htext, buf, truelen, bufsize); | ||
| 574 | truelen = (coding.fake_multibyte | ||
| 575 | ? multibyte_chars_in_text (buf, coding.produced) | ||
| 576 | : coding.produced_char); | ||
| 577 | ret = make_string_from_bytes ((char *) buf, truelen, coding.produced); | ||
| 578 | xfree (buf); | ||
| 579 | Vlast_coding_system_used = coding.symbol; | ||
| 580 | } | ||
| 581 | else | ||
| 582 | { | ||
| 583 | ret = make_unibyte_string ((char *) htext, truelen); | ||
| 584 | Vlast_coding_system_used = Qraw_text; | ||
| 585 | } | ||
| 586 | |||
| 487 | xfree (htext); | 587 | xfree (htext); |
| 488 | 588 | ||
| 489 | closeclip: | 589 | closeclip: |
| @@ -549,6 +649,14 @@ syms_of_win16select () | |||
| 549 | defsubr (&Sw16_get_clipboard_data); | 649 | defsubr (&Sw16_get_clipboard_data); |
| 550 | defsubr (&Sx_selection_exists_p); | 650 | defsubr (&Sx_selection_exists_p); |
| 551 | 651 | ||
| 652 | DEFVAR_LISP ("clipboard-coding-system", &Vclipboard_coding_system, | ||
| 653 | "Coding system for communicating with other X clients.\n\ | ||
| 654 | When sending or receiving text via cut_buffer, selection, and clipboard,\n\ | ||
| 655 | the text is encoded or decoded by this coding system.\n\ | ||
| 656 | A default value is `iso-latin-1-dos'"); | ||
| 657 | Vclipboard_coding_system=intern ("iso-latin-1-dos"); | ||
| 658 | staticpro(&Vclipboard_coding_system); | ||
| 659 | |||
| 552 | QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY); | 660 | QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY); |
| 553 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); | 661 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); |
| 554 | } | 662 | } |