Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-15
[bpt/emacs.git] / src / w32select.c
1 /* Selection processing for Emacs on the Microsoft W32 API.
2 Copyright (C) 1993, 1994 Free Software Foundation.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 /* Written by Kevin Gallo */
22
23 #include <config.h>
24 #include "lisp.h"
25 #include "w32term.h" /* for all of the w32 includes */
26 #include "dispextern.h" /* frame.h seems to want this */
27 #include "keyboard.h"
28 #include "frame.h" /* Need this to get the X window of selected_frame */
29 #include "blockinput.h"
30 #include "buffer.h"
31 #include "charset.h"
32 #include "coding.h"
33 #include "composite.h"
34
35 Lisp_Object QCLIPBOARD;
36
37 /* Coding system for communicating with other Windows programs via the
38 clipboard. */
39 static Lisp_Object Vselection_coding_system;
40
41 /* Coding system for the next communicating with other Windows programs. */
42 static Lisp_Object Vnext_selection_coding_system;
43
44 /* Sequence number, used where possible to detect when we are pasting
45 our own text. */
46 static DWORD last_clipboard_sequence_number;
47 extern ClipboardSequence_Proc clipboard_sequence_fn;
48
49 /* The last text we put into the clipboard. This is used when the OS
50 does not support sequence numbers (NT4, 95). It is undesirable to
51 use data put on the clipboard by Emacs because the clipboard data
52 could be MULEtilated by inappropriately chosen
53 (next-)selection-coding-system. For this reason, we must store the
54 text *after* it was encoded/Unix-to-DOS-converted. */
55 static unsigned char *last_clipboard_text = NULL;
56 static size_t clipboard_storage_size = 0;
57
58 #if 0
59 DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0,
60 doc: /* This opens the clipboard with the given frame pointer. */)
61 (frame)
62 Lisp_Object frame;
63 {
64 BOOL ok = FALSE;
65
66 if (!NILP (frame))
67 CHECK_LIVE_FRAME (frame);
68
69 BLOCK_INPUT;
70
71 ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL);
72
73 UNBLOCK_INPUT;
74
75 return (ok ? frame : Qnil);
76 }
77
78 DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard,
79 Sw32_empty_clipboard, 0, 0, 0,
80 doc: /* Empty the clipboard.
81 Assigns ownership of the clipboard to the window which opened it. */)
82 ()
83 {
84 BOOL ok = FALSE;
85
86 BLOCK_INPUT;
87
88 ok = EmptyClipboard ();
89
90 UNBLOCK_INPUT;
91
92 return (ok ? Qt : Qnil);
93 }
94
95 DEFUN ("w32-close-clipboard", Fw32_close_clipboard,
96 Sw32_close_clipboard, 0, 0, 0,
97 doc: /* Close the clipboard. */)
98 ()
99 {
100 BOOL ok = FALSE;
101
102 BLOCK_INPUT;
103
104 ok = CloseClipboard ();
105
106 UNBLOCK_INPUT;
107
108 return (ok ? Qt : Qnil);
109 }
110
111 #endif
112
113 DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
114 Sw32_set_clipboard_data, 1, 2, 0,
115 doc: /* This sets the clipboard data to the given text. */)
116 (string, frame)
117 Lisp_Object string, frame;
118 {
119 BOOL ok = TRUE;
120 HANDLE htext;
121 int nbytes;
122 int truelen, nlines = 0;
123 unsigned char *src;
124 unsigned char *dst;
125
126 CHECK_STRING (string);
127
128 if (!NILP (frame))
129 CHECK_LIVE_FRAME (frame);
130
131 BLOCK_INPUT;
132
133 nbytes = SBYTES (string) + 1;
134 src = SDATA (string);
135 dst = src;
136
137 /* We need to know how many lines there are, since we need CRLF line
138 termination for compatibility with other Windows Programs.
139 avoid using strchr because it recomputes the length every time */
140 while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
141 {
142 nlines++;
143 dst++;
144 }
145
146 {
147 /* Since we are now handling multilingual text, we must consider
148 encoding text for the clipboard. */
149 int result = string_xstring_p (string);
150
151 if (result == 0)
152 {
153 /* No multibyte character in OBJ. We need not encode it. */
154
155 /* Need to know final size after CR chars are inserted (the
156 standard CF_TEXT clipboard format uses CRLF line endings,
157 while Emacs uses just LF internally). */
158
159 truelen = nbytes + nlines;
160
161 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
162 goto error;
163
164 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
165 goto error;
166
167 /* convert to CRLF line endings expected by clipboard */
168 while (1)
169 {
170 unsigned char *next;
171 /* copy next line or remaining bytes including '\0' */
172 next = _memccpy (dst, src, '\n', nbytes);
173 if (next)
174 {
175 /* copied one line ending with '\n' */
176 int copied = next - dst;
177 nbytes -= copied;
178 src += copied;
179 /* insert '\r' before '\n' */
180 next[-1] = '\r';
181 next[0] = '\n';
182 dst = next + 1;
183 }
184 else
185 /* copied remaining partial line -> now finished */
186 break;
187 }
188
189 GlobalUnlock (htext);
190
191 Vlast_coding_system_used = Qraw_text;
192 }
193 else
194 {
195 /* We must encode contents of OBJ to the selection coding
196 system. */
197 struct coding_system coding;
198 HANDLE htext2;
199
200 if (NILP (Vnext_selection_coding_system))
201 Vnext_selection_coding_system = Vselection_coding_system;
202 setup_coding_system
203 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
204 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
205
206 Vnext_selection_coding_system = Qnil;
207
208 /* We suppress producing escape sequences for composition. */
209 coding.common_flags &= ~CODING_ANNOTATION_MASK;
210 coding.dst_bytes = SCHARS (string) * 2;
211 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.dst_bytes)) == NULL)
212 goto error;
213 if ((coding.destination = (unsigned char *) GlobalLock (htext)) == NULL)
214 goto error;
215 encode_coding_object (&coding, string, 0, 0,
216 SCHARS (string), SBYTES (string), Qnil);
217 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
218
219 /* If clipboard sequence numbers are not supported, keep a copy for
220 later comparison. */
221 if (!clipboard_sequence_fn)
222 {
223 /* Stash away the data we are about to put into the
224 clipboard, so we could later check inside
225 Fw32_get_clipboard_data whether the clipboard still
226 holds our data. */
227 if (clipboard_storage_size < coding.produced)
228 {
229 clipboard_storage_size = coding.produced + 100;
230 last_clipboard_text = (char *) xrealloc (last_clipboard_text,
231 clipboard_storage_size);
232 }
233 if (last_clipboard_text)
234 memcpy (last_clipboard_text, coding.destination,
235 coding.produced);
236 }
237
238 GlobalUnlock (htext);
239
240 /* Shrink data block to actual size. */
241 htext2 = GlobalReAlloc (htext, coding.produced,
242 GMEM_MOVEABLE | GMEM_DDESHARE);
243 if (htext2 != NULL) htext = htext2;
244 }
245 }
246
247 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
248 goto error;
249
250 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
251
252 CloseClipboard ();
253
254 /* Common sense says to read the sequence number inside the
255 OpenClipboard/ CloseClipboard block to avoid race conditions
256 where another app puts something on the clipboard straight after
257 us. But experience suggests that the sequence number from the
258 SetClipboardData is not allocated until we close the clipboard!
259 Since clipboard operations are normally user-driven, the race
260 condition is probably not going to really happen. */
261 if (clipboard_sequence_fn)
262 last_clipboard_sequence_number = clipboard_sequence_fn ();
263
264 if (ok) goto done;
265
266 error:
267
268 ok = FALSE;
269 if (htext) GlobalFree (htext);
270 if (last_clipboard_text)
271 *last_clipboard_text = '\0';
272
273 last_clipboard_sequence_number = 0;
274
275 done:
276 UNBLOCK_INPUT;
277
278 return (ok ? string : Qnil);
279 }
280
281 DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
282 Sw32_get_clipboard_data, 0, 1, 0,
283 doc: /* This gets the clipboard data in text format. */)
284 (frame)
285 Lisp_Object frame;
286 {
287 HANDLE htext;
288 Lisp_Object ret = Qnil;
289
290 if (!NILP (frame))
291 CHECK_LIVE_FRAME (frame);
292
293 BLOCK_INPUT;
294
295 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
296 goto done;
297
298 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
299 goto closeclip;
300
301 {
302 unsigned char *src;
303 unsigned char *dst;
304 int nbytes;
305 int truelen;
306 int require_decoding = 0;
307
308 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
309 goto closeclip;
310
311 nbytes = strlen (src);
312
313 /* If the text in clipboard is identical to what we put there
314 last time w32_set_clipboard_data was called, pretend there's no
315 data in the clipboard. This is so we don't pass our own text
316 from the clipboard (which might be troublesome if the killed
317 text includes null characters). */
318 if ((clipboard_sequence_fn
319 && clipboard_sequence_fn () == last_clipboard_sequence_number)
320 || (last_clipboard_text
321 && clipboard_storage_size >= nbytes
322 && memcmp(last_clipboard_text, src, nbytes) == 0))
323 goto closeclip;
324
325 {
326 /* If the clipboard data contains any non-ascii code, we
327 need to decode it. */
328 int i;
329
330 for (i = 0; i < nbytes; i++)
331 {
332 if (src[i] >= 0x80)
333 {
334 require_decoding = 1;
335 break;
336 }
337 }
338 }
339
340 if (require_decoding)
341 {
342 struct coding_system coding;
343
344 if (NILP (Vnext_selection_coding_system))
345 Vnext_selection_coding_system = Vselection_coding_system;
346 setup_coding_system
347 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
348 coding.src_multibyte = 0;
349 coding.dst_multibyte = 1;
350 Vnext_selection_coding_system = Qnil;
351 coding.mode |= CODING_MODE_LAST_BLOCK;
352 /* We explicitly disable composition handling because
353 selection data should not contain any composition
354 sequence. */
355 coding.common_flags &= ~CODING_ANNOTATION_MASK;
356 coding.dst_bytes = nbytes * 2;
357 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
358 decode_coding_c_string (&coding, src, nbytes, Qnil);
359 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
360 ret = make_string_from_bytes ((char *) coding.destination,
361 coding.produced_char, coding.produced);
362 xfree (coding.destination);
363 }
364 else
365 {
366 /* Need to know final size after CR chars are removed because we
367 can't change the string size manually, and doing an extra
368 copy is silly. Note that we only remove CR when it appears
369 as part of CRLF. */
370
371 truelen = nbytes;
372 dst = src;
373 /* avoid using strchr because it recomputes the length everytime */
374 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
375 {
376 if (dst[1] == '\n') /* safe because of trailing '\0' */
377 truelen--;
378 dst++;
379 }
380
381 ret = make_uninit_string (truelen);
382
383 /* Convert CRLF line endings (the standard CF_TEXT clipboard
384 format) to LF endings as used internally by Emacs. */
385
386 dst = SDATA (ret);
387 while (1)
388 {
389 unsigned char *next;
390 /* copy next line or remaining bytes excluding '\0' */
391 next = _memccpy (dst, src, '\r', nbytes);
392 if (next)
393 {
394 /* copied one line ending with '\r' */
395 int copied = next - dst;
396 nbytes -= copied;
397 dst += copied;
398 src += copied;
399 if (*src == '\n')
400 dst--; /* overwrite '\r' with '\n' */
401 }
402 else
403 /* copied remaining partial line -> now finished */
404 break;
405 }
406
407 Vlast_coding_system_used = Qraw_text;
408 }
409
410 GlobalUnlock (htext);
411 }
412
413 closeclip:
414 CloseClipboard ();
415
416 done:
417 UNBLOCK_INPUT;
418
419 return (ret);
420 }
421
422 /* Support checking for a clipboard selection. */
423
424 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
425 0, 1, 0,
426 doc: /* Whether there is an owner for the given X Selection.
427 The arg should be the name of the selection in question, typically one of
428 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
429 \(Those are literal upper-case symbol names, since that's what X expects.)
430 For convenience, the symbol nil is the same as `PRIMARY',
431 and t is the same as `SECONDARY'. */)
432 (selection)
433 Lisp_Object selection;
434 {
435 CHECK_SYMBOL (selection);
436
437 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
438 if the clipboard currently has valid text format contents. */
439
440 if (EQ (selection, QCLIPBOARD))
441 {
442 Lisp_Object val = Qnil;
443
444 if (OpenClipboard (NULL))
445 {
446 int format = 0;
447 while (format = EnumClipboardFormats (format))
448 if (format == CF_TEXT)
449 {
450 val = Qt;
451 break;
452 }
453 CloseClipboard ();
454 }
455 return val;
456 }
457 return Qnil;
458 }
459
460 void
461 syms_of_w32select ()
462 {
463 #if 0
464 defsubr (&Sw32_open_clipboard);
465 defsubr (&Sw32_empty_clipboard);
466 defsubr (&Sw32_close_clipboard);
467 #endif
468 defsubr (&Sw32_set_clipboard_data);
469 defsubr (&Sw32_get_clipboard_data);
470 defsubr (&Sx_selection_exists_p);
471
472 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
473 doc: /* Coding system for communicating with other programs.
474 When sending or receiving text via cut_buffer, selection, and clipboard,
475 the text is encoded or decoded by this coding system.
476 The default value is `iso-latin-1-dos'. */);
477 Vselection_coding_system = intern ("iso-latin-1-dos");
478
479 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
480 doc: /* Coding system for the next communication with other programs.
481 Usually, `selection-coding-system' is used for communicating with
482 other programs. But, if this variable is set, it is used for the
483 next communication only. After the communication, this variable is
484 set to nil. */);
485 Vnext_selection_coding_system = Qnil;
486
487 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
488 }
489
490 /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af
491 (do not change this comment) */