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