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, &regs); 349 __dpmi_int(0x2f, &regs);
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 */