Mercurial > emacs
comparison src/w16select.c @ 22729:3537e1563a66
(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.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Thu, 09 Jul 1998 14:02:15 +0000 |
parents | 64adf1f4d54d |
children | 14bde44d261c |
comparison
equal
deleted
inserted
replaced
22728:4596d7f197d8 | 22729:3537e1563a66 |
---|---|
35 #include <sys/farptr.h> | 35 #include <sys/farptr.h> |
36 #include "lisp.h" | 36 #include "lisp.h" |
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 |
43 should be put on a header file. Right now, nobody else uses them. */ | 46 should be put on a header file. Right now, nobody else uses them. */ |
44 | 47 |
55 #define CF_DSPBITMAP 0x82 | 58 #define CF_DSPBITMAP 0x82 |
56 | 59 |
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; |
70 | |
71 /* Coding system for communicating with other Windows programs via the | |
72 clipboard. */ | |
73 static Lisp_Object Vclipboard_coding_system; | |
67 | 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 |
71 static struct { | 78 static struct { |
214 } | 221 } |
215 } | 222 } |
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; |
226 unsigned long xbuf_addr, buf_offset; | 234 unsigned long xbuf_addr, buf_offset; |
227 unsigned char *dp = Data, *dstart = dp; | 235 unsigned char *dp = Data, *dstart = dp; |
231 | 239 |
232 /* need to know final size after '\r' chars are inserted (the | 240 /* need to know final size after '\r' chars are inserted (the |
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) |
244 return 0; | 256 return 0; |
245 | 257 |
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--) | 265 { |
254 { | 266 dp = Data; |
255 if (*dp == '\n') | 267 buf_offset = xbuf_addr; |
256 _farnspokeb (buf_offset++, '\r'); | 268 _farsetsel (_dos_ds); |
257 _farnspokeb (buf_offset++, *dp++); | 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: |
261 DX = WinOldAp-Supported Clipboard format | 278 DX = WinOldAp-Supported Clipboard format |
262 ES:BX = Pointer to data | 279 ES:BX = Pointer to data |
297 | 314 |
298 /* Get clipboard data, return its length. | 315 /* Get clipboard data, return its length. |
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; |
309 unsigned long xbuf_addr; | 327 unsigned long xbuf_addr; |
310 unsigned char *dp = Data; | 328 unsigned char *dp = Data; |
329 regs.x.es = xbuf_addr >> 4; | 347 regs.x.es = xbuf_addr >> 4; |
330 regs.x.bx = xbuf_addr & 15; | 348 regs.x.bx = xbuf_addr & 15; |
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'; |
344 xbuf_addr++; | 363 xbuf_addr++; |
345 } | 364 } |
399 (string, frame) | 418 (string, frame) |
400 Lisp_Object string, frame; | 419 Lisp_Object string, frame; |
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 |
408 if (NILP (frame)) | 430 if (NILP (frame)) |
409 frame = Fselected_frame (); | 431 frame = Fselected_frame (); |
412 if ( !FRAME_MSDOS_P (XFRAME (frame))) | 434 if ( !FRAME_MSDOS_P (XFRAME (frame))) |
413 goto done; | 435 goto done; |
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; |
428 | 486 |
429 error: | 487 error: |
430 | 488 |
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. |
437 (This will happen somewhere after 600K bytes (470K in DJGPP v1.x), | 497 (This will happen somewhere after 600K bytes (470K in DJGPP v1.x), |
438 depending on user system configuration.) If we just silently | 498 depending on user system configuration.) If we just silently |
455 Lisp_Object frame; | 515 Lisp_Object frame; |
456 { | 516 { |
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 |
467 CHECK_LIVE_FRAME (frame, 0); | 526 CHECK_LIVE_FRAME (frame, 0); |
468 if ( !FRAME_MSDOS_P (XFRAME (frame))) | 527 if ( !FRAME_MSDOS_P (XFRAME (frame))) |
478 goto closeclip; | 537 goto closeclip; |
479 | 538 |
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: |
490 close_clipboard (); | 590 close_clipboard (); |
491 | 591 |
547 { | 647 { |
548 defsubr (&Sw16_set_clipboard_data); | 648 defsubr (&Sw16_set_clipboard_data); |
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 } |
555 | 663 |
556 #endif /* MSDOS */ | 664 #endif /* MSDOS */ |