This source file includes following definitions.
- identify_winoldap_version
- open_clipboard
- empty_clipboard
- alloc_xfer_buf
- free_xfer_buf
- set_clipboard_data
- get_clipboard_data_size
- get_clipboard_data
- close_clipboard
- clipboard_compact
- DEFUN
- syms_of_win16select
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #ifdef MSDOS
30
31 #include <config.h>
32 #include <dpmi.h>
33 #include <go32.h>
34 #include <sys/farptr.h>
35 #include "lisp.h"
36 #include "dispextern.h"
37 #include "frame.h"
38 #include "blockinput.h"
39 #include "character.h"
40 #include "buffer.h"
41 #include "coding.h"
42 #include "composite.h"
43
44
45
46
47
48 #define CF_TEXT 0x01
49 #define CF_BITMAP 0x02
50 #define CF_METAFILE 0x03
51 #define CF_SYLK 0x04
52 #define CF_DIF 0x05
53 #define CF_TIFF 0x06
54 #define CF_OEMTEXT 0x07
55 #define CF_DIBBITMAP 0x08
56 #define CF_WINWRITE 0x80
57 #define CF_DSPTEXT 0x81
58 #define CF_DSPBITMAP 0x82
59
60 unsigned identify_winoldap_version (void);
61 unsigned open_clipboard (void);
62 unsigned empty_clipboard (void);
63 unsigned set_clipboard_data (unsigned, void *, unsigned, int);
64 unsigned get_clipboard_data_size (unsigned);
65 unsigned get_clipboard_data (unsigned, void *, unsigned, int);
66 unsigned close_clipboard (void);
67 unsigned clipboard_compact (unsigned);
68
69
70
71 static struct {
72 unsigned long size;
73 unsigned short rm_segment;
74 } clipboard_xfer_buf_info;
75
76
77
78
79
80
81
82 static unsigned char *last_clipboard_text;
83
84
85 static size_t clipboard_storage_size;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 unsigned
102 identify_winoldap_version (void)
103 {
104 __dpmi_regs regs;
105
106
107
108
109
110 regs.x.ax = 0x1700;
111 __dpmi_int (0x2f, ®s);
112 return regs.x.ax;
113 }
114
115
116 unsigned
117 open_clipboard (void)
118 {
119 __dpmi_regs regs;
120
121
122
123
124
125
126
127 if (identify_winoldap_version () == 0x1700)
128 return 0;
129
130
131
132
133 regs.x.ax = 0x1701;
134 __dpmi_int (0x2f, ®s);
135 return regs.x.ax;
136 }
137
138
139 unsigned
140 empty_clipboard (void)
141 {
142 __dpmi_regs regs;
143
144
145
146
147 regs.x.ax = 0x1702;
148 __dpmi_int (0x2f, ®s);
149 return regs.x.ax;
150 }
151
152
153
154 static unsigned long
155 alloc_xfer_buf (unsigned want_size)
156 {
157 __dpmi_regs regs;
158
159
160 if (want_size <= _go32_info_block.size_of_transfer_buffer)
161 return __tb & 0xfffff;
162
163
164
165 if (want_size > 0xfffff)
166 return 0;
167
168
169
170 clipboard_xfer_buf_info.size = (want_size + 15) >> 4;
171
172
173
174 regs.h.ah = 0x48;
175 regs.x.bx = clipboard_xfer_buf_info.size;
176 __dpmi_int (0x21, ®s);
177 if (regs.x.flags & 1)
178 {
179 clipboard_xfer_buf_info.size = 0;
180 return 0;
181 }
182
183 clipboard_xfer_buf_info.rm_segment = regs.x.ax;
184 return (((int)clipboard_xfer_buf_info.rm_segment) << 4) & 0xfffff;
185 }
186
187
188
189
190
191 static void
192 free_xfer_buf (void)
193 {
194
195 if (clipboard_xfer_buf_info.size)
196 {
197 __dpmi_regs regs;
198
199
200
201 regs.h.ah = 0x49;
202 regs.x.es = clipboard_xfer_buf_info.rm_segment;
203 __dpmi_int (0x21, ®s);
204 clipboard_xfer_buf_info.size = 0;
205 }
206 }
207
208
209 unsigned
210 set_clipboard_data (unsigned Format, void *Data, unsigned Size, int Raw)
211 {
212 __dpmi_regs regs;
213 unsigned truelen;
214 unsigned long xbuf_addr, buf_offset;
215 unsigned char *dp = Data, *dstart = dp;
216
217 if (Format != CF_OEMTEXT)
218 return 3;
219
220
221
222
223 truelen = Size + 1;
224
225 if (!Raw)
226 {
227
228 while ((dp = memchr (dp, '\n', Size - (dp - dstart))) != 0)
229 {
230 truelen++;
231 dp++;
232 }
233 }
234
235 if (clipboard_compact (truelen) < truelen)
236 return 1;
237
238 if ((xbuf_addr = alloc_xfer_buf (truelen)) == 0)
239 return 1;
240
241
242 if (Raw)
243 {
244 dosmemput (Data, Size, xbuf_addr);
245
246
247
248 _farpokeb (_dos_ds, xbuf_addr + Size, '\0');
249 }
250 else
251 {
252 dp = Data;
253 buf_offset = xbuf_addr;
254 _farsetsel (_dos_ds);
255 while (Size--)
256 {
257
258
259 if (*dp == '\0')
260 return 2;
261 if (*dp == '\n')
262 _farnspokeb (buf_offset++, '\r');
263 _farnspokeb (buf_offset++, *dp++);
264 }
265
266
267
268 _farnspokeb (buf_offset, '\0');
269 }
270
271
272
273
274 if (clipboard_storage_size < truelen)
275 {
276 clipboard_storage_size = truelen + 100;
277 last_clipboard_text =
278 (char *) xrealloc (last_clipboard_text, clipboard_storage_size);
279 }
280 if (last_clipboard_text)
281 dosmemget (xbuf_addr, truelen, last_clipboard_text);
282
283
284
285
286
287
288
289 regs.x.ax = 0x1703;
290 regs.x.dx = Format;
291 regs.x.si = truelen >> 16;
292 regs.x.cx = truelen & 0xffff;
293 regs.x.es = xbuf_addr >> 4;
294 regs.x.bx = xbuf_addr & 15;
295 __dpmi_int (0x2f, ®s);
296
297 free_xfer_buf ();
298
299
300 if (regs.x.ax == 0)
301 *last_clipboard_text = '\0';
302
303
304 return regs.x.ax > 0 ? 0 : 3;
305 }
306
307
308 unsigned
309 get_clipboard_data_size (unsigned Format)
310 {
311 __dpmi_regs regs;
312
313
314
315
316
317
318
319 regs.x.ax = 0x1704;
320 regs.x.dx = Format;
321 __dpmi_int (0x2f, ®s);
322 return ( (((unsigned)regs.x.dx) << 16) | regs.x.ax);
323 }
324
325
326
327
328 unsigned
329 get_clipboard_data (unsigned Format, void *Data, unsigned Size, int Raw)
330 {
331 __dpmi_regs regs;
332 unsigned long xbuf_addr;
333 unsigned char *dp = Data;
334
335 if (Format != CF_OEMTEXT)
336 return 0;
337
338 if (Size == 0)
339 return 0;
340
341 if ((xbuf_addr = alloc_xfer_buf (Size)) == 0)
342 return 0;
343
344
345
346
347
348
349
350 regs.x.ax = 0x1705;
351 regs.x.dx = Format;
352 regs.x.es = xbuf_addr >> 4;
353 regs.x.bx = xbuf_addr & 15;
354 __dpmi_int (0x2f, ®s);
355 if (regs.x.ax != 0)
356 {
357 unsigned char null_char = '\0';
358 unsigned long xbuf_beg = xbuf_addr;
359
360
361
362 register unsigned char *lcdp =
363 last_clipboard_text == NULL ? &null_char : last_clipboard_text;
364
365
366
367 _farsetsel (_dos_ds);
368 while (Size--)
369 {
370 register unsigned char c = _farnspeekb (xbuf_addr++);
371
372 if (*lcdp == c)
373 lcdp++;
374
375 if ((*dp++ = c) == '\r' && !Raw && _farnspeekb (xbuf_addr) == '\n')
376 {
377 dp--;
378 *dp++ = '\n';
379 xbuf_addr++;
380 if (*lcdp == '\n')
381 lcdp++;
382 }
383
384
385
386
387 else if (c == '\0')
388 break;
389 }
390
391
392
393
394
395
396 if (last_clipboard_text &&
397 xbuf_addr - xbuf_beg == (long)(lcdp - last_clipboard_text))
398 dp = (unsigned char *)Data + 1;
399 }
400
401 free_xfer_buf ();
402
403 return (unsigned) (dp - (unsigned char *)Data - 1);
404 }
405
406
407 unsigned
408 close_clipboard (void)
409 {
410 __dpmi_regs regs;
411
412
413
414
415 regs.x.ax = 0x1708;
416 __dpmi_int (0x2f, ®s);
417 return regs.x.ax;
418 }
419
420
421 unsigned
422 clipboard_compact (unsigned Size)
423 {
424 __dpmi_regs regs;
425
426
427
428
429
430 regs.x.ax = 0x1709;
431 regs.x.si = Size >> 16;
432 regs.x.cx = Size & 0xffff;
433 __dpmi_int (0x2f, ®s);
434 return ((unsigned)regs.x.dx << 16) | regs.x.ax;
435 }
436
437 static char no_mem_msg[] =
438 "(Not enough DOS memory to put saved text into clipboard.)";
439 static char binary_msg[] =
440 "(Binary characters in saved text; clipboard data not set.)";
441 static char system_error_msg[] =
442 "(Clipboard interface failure; clipboard data not set.)";
443
444 DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_data, 1, 2, 0,
445 doc: )
446 (Lisp_Object string, Lisp_Object frame)
447 {
448 unsigned ok = 1, put_status = 0;
449 int nbytes, no_crlf_conversion;
450 unsigned char *src, *dst = NULL;
451
452 CHECK_STRING (string);
453
454 if (!FRAME_MSDOS_P (decode_live_frame (frame)))
455 goto done;
456
457 block_input ();
458
459 if (!open_clipboard ())
460 goto error;
461
462 nbytes = SBYTES (string);
463 src = SDATA (string);
464
465
466 for (dst = src; dst < src + nbytes; dst++)
467 {
468 if (*dst == '\0' || *dst >= 0x80)
469 break;
470 }
471 if (dst >= src + nbytes)
472 {
473
474
475 no_crlf_conversion = 0;
476 Vlast_coding_system_used = Qraw_text;
477 dst = NULL;
478 }
479 else
480 {
481
482
483 struct coding_system coding;
484 Lisp_Object coding_system =
485 NILP (Vnext_selection_coding_system) ?
486 Vselection_coding_system : Vnext_selection_coding_system;
487
488 setup_coding_system (Fcheck_coding_system (coding_system), &coding);
489 coding.dst_bytes = nbytes * 4;
490 coding.destination = xmalloc (coding.dst_bytes);
491 Vnext_selection_coding_system = Qnil;
492 coding.mode |= CODING_MODE_LAST_BLOCK;
493 dst = coding.destination;
494 encode_coding_object (&coding, string, 0, 0,
495 SCHARS (string), nbytes, Qnil);
496 no_crlf_conversion = 1;
497 nbytes = coding.produced;
498 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
499 src = dst;
500 }
501
502 ok = empty_clipboard ()
503 && ((put_status
504 = set_clipboard_data (CF_OEMTEXT, src, nbytes, no_crlf_conversion))
505 == 0);
506
507 if (!no_crlf_conversion)
508 close_clipboard ();
509
510 if (ok) goto unblock;
511
512 error:
513
514 ok = 0;
515
516 unblock:
517 xfree (dst);
518 unblock_input ();
519
520
521
522
523
524
525 if (put_status)
526 {
527 switch (put_status)
528 {
529 case 1:
530 message3 (make_unibyte_string (no_mem_msg, sizeof (no_mem_msg) - 1));
531 break;
532 case 2:
533 message3 (make_unibyte_string (binary_msg, sizeof (binary_msg) - 1));
534 break;
535 case 3:
536 message3 (make_unibyte_string (system_error_msg, sizeof (system_error_msg) - 1));
537 break;
538 }
539 sit_for (make_fixnum (2), 0, 2);
540 }
541
542 done:
543
544 return (ok && put_status == 0 ? string : Qnil);
545 }
546
547 DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_data, 0, 1, 0,
548 doc: )
549 (Lisp_Object frame)
550 {
551 unsigned data_size, truelen;
552 unsigned char *htext = NULL;
553 Lisp_Object ret = Qnil;
554 int require_decoding = 0;
555
556 if (!FRAME_MSDOS_P (decode_live_frame (frame)))
557 goto done;
558
559 block_input ();
560
561 if (!open_clipboard ())
562 goto unblock;
563
564 if ((data_size = get_clipboard_data_size (CF_OEMTEXT)) == 0 ||
565 (htext = xmalloc (data_size)) == 0)
566 goto closeclip;
567
568
569
570
571 if ((truelen = get_clipboard_data (CF_OEMTEXT, htext, data_size, 0)) == 0)
572 goto closeclip;
573
574
575 {
576
577
578 int i;
579
580 for (i = 0; i < truelen; i++)
581 {
582 if (htext[i] >= 0x80)
583 {
584 require_decoding = 1;
585 break;
586 }
587 }
588 }
589 if (require_decoding)
590 {
591 struct coding_system coding;
592 Lisp_Object coding_system = Vnext_selection_coding_system;
593
594 truelen = get_clipboard_data (CF_OEMTEXT, htext, data_size, 1);
595 if (NILP (coding_system))
596 coding_system = Vselection_coding_system;
597 setup_coding_system (Fcheck_coding_system (coding_system), &coding);
598 coding.source = htext;
599 coding.mode |= CODING_MODE_LAST_BLOCK;
600
601
602 coding.common_flags &= ~CODING_ANNOTATION_MASK;
603 decode_coding_object (&coding, Qnil, 0, 0, truelen, truelen, Qt);
604 ret = coding.dst_object;
605 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
606 }
607 else
608 {
609 ret = make_unibyte_string ((char *) htext, truelen);
610 Vlast_coding_system_used = Qraw_text;
611 }
612
613 xfree (htext);
614 Vnext_selection_coding_system = Qnil;
615
616 closeclip:
617 close_clipboard ();
618
619 unblock:
620 unblock_input ();
621
622 done:
623
624 return (ret);
625 }
626
627
628
629 DEFUN ("w16-selection-exists-p", Fw16_selection_exists_p, Sw16_selection_exists_p,
630 0, 2, 0,
631 doc:
632
633
634
635
636
637
638
639 )
640 (Lisp_Object selection, Lisp_Object terminal)
641 {
642 CHECK_SYMBOL (selection);
643
644
645
646
647
648
649
650
651
652
653
654 if ((NILP (selection) || EQ (selection, QPRIMARY))
655 && ! NILP (Fsymbol_value (Fintern_soft (build_string ("kill-ring"),
656 Qnil))))
657 return Qt;
658
659 if (EQ (selection, QCLIPBOARD))
660 {
661 Lisp_Object val = Qnil;
662
663 if (open_clipboard ())
664 {
665 if (get_clipboard_data_size (CF_OEMTEXT))
666 val = Qt;
667 close_clipboard ();
668 }
669 return val;
670 }
671 return Qnil;
672 }
673
674 void
675 syms_of_win16select (void)
676 {
677 defsubr (&Sw16_set_clipboard_data);
678 defsubr (&Sw16_get_clipboard_data);
679 defsubr (&Sw16_selection_exists_p);
680
681 DEFVAR_LISP ("selection-coding-system", Vselection_coding_system,
682 doc: );
683 Vselection_coding_system = intern ("iso-latin-1-dos");
684
685 DEFVAR_LISP ("next-selection-coding-system", Vnext_selection_coding_system,
686 doc: );
687 Vnext_selection_coding_system = Qnil;
688
689 DEFSYM (QCLIPBOARD, "CLIPBOARD");
690 }
691
692 #endif