(Fselect_frame, Fset_frame_selected_window)
[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 /* Include the terminating NULL character in the source of
134 conversion. */
135 nbytes = SBYTES (string) + 1;
136 src = SDATA (string);
137 dst = src;
138
139 /* We need to know how many lines there are, since we need CRLF line
140 termination for compatibility with other Windows Programs.
141 avoid using strchr because it recomputes the length every time */
142 while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
143 {
144 nlines++;
145 dst++;
146 }
147
148 {
149 /* Since we are now handling multilingual text, we must consider
150 encoding text for the clipboard. */
151 int charset_info = find_charset_in_text (src, SCHARS (string),
152 nbytes, NULL, Qnil);
153
154 if (charset_info == 0)
155 {
156 /* No multibyte character in OBJ. We need not encode it. */
157
158 /* Need to know final size after CR chars are inserted (the
159 standard CF_TEXT clipboard format uses CRLF line endings,
160 while Emacs uses just LF internally). */
161
162 truelen = nbytes + nlines;
163
164 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
165 goto error;
166
167 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
168 goto error;
169
170 /* convert to CRLF line endings expected by clipboard */
171 while (1)
172 {
173 unsigned char *next;
174 /* copy next line or remaining bytes including '\0' */
175 next = _memccpy (dst, src, '\n', nbytes);
176 if (next)
177 {
178 /* copied one line ending with '\n' */
179 int copied = next - dst;
180 nbytes -= copied;
181 src += copied;
182 /* insert '\r' before '\n' */
183 next[-1] = '\r';
184 next[0] = '\n';
185 dst = next + 1;
186 }
187 else
188 /* copied remaining partial line -> now finished */
189 break;
190 }
191
192 GlobalUnlock (htext);
193
194 Vlast_coding_system_used = Qraw_text;
195 }
196 else
197 {
198 /* We must encode contents of OBJ to the selection coding
199 system. */
200 int bufsize;
201 struct coding_system coding;
202 HANDLE htext2;
203
204 if (NILP (Vnext_selection_coding_system))
205 Vnext_selection_coding_system = Vselection_coding_system;
206 setup_coding_system
207 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
208 if (SYMBOLP (coding.pre_write_conversion)
209 && !NILP (Ffboundp (coding.pre_write_conversion)))
210 {
211 string = run_pre_post_conversion_on_str (string, &coding, 1);
212 src = SDATA (string);
213 /* Include the terminating NULL character in the source of
214 conversion. */
215 nbytes = SBYTES (string) + 1;
216 }
217 coding.src_multibyte = 1;
218 coding.dst_multibyte = 0;
219 /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
220 encode_coding_iso2022 trying to dereference a null pointer. */
221 coding.composing = COMPOSITION_DISABLED;
222 if (coding.type == coding_type_iso2022)
223 coding.flags |= CODING_FLAG_ISO_SAFE;
224 Vnext_selection_coding_system = Qnil;
225 coding.mode |= CODING_MODE_LAST_BLOCK;
226 bufsize = encoding_buffer_size (&coding, nbytes);
227 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL)
228 goto error;
229 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
230 goto error;
231 encode_coding (&coding, src, dst, nbytes, bufsize);
232 Vlast_coding_system_used = coding.symbol;
233
234 /* If clipboard sequence numbers are not supported, keep a copy for
235 later comparison. */
236 if (!clipboard_sequence_fn)
237 {
238 /* Stash away the data we are about to put into the
239 clipboard, so we could later check inside
240 Fw32_get_clipboard_data whether the clipboard still
241 holds our data. */
242 if (clipboard_storage_size < coding.produced)
243 {
244 clipboard_storage_size = coding.produced + 100;
245 last_clipboard_text = (char *) xrealloc (last_clipboard_text,
246 clipboard_storage_size);
247 }
248 if (last_clipboard_text)
249 memcpy (last_clipboard_text, dst, coding.produced);
250 }
251
252 GlobalUnlock (htext);
253
254 /* Shrink data block to actual size. */
255 htext2 = GlobalReAlloc (htext, coding.produced,
256 GMEM_MOVEABLE | GMEM_DDESHARE);
257 if (htext2 != NULL) htext = htext2;
258 }
259 }
260
261 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
262 goto error;
263
264 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
265
266 CloseClipboard ();
267
268 /* Common sense says to read the sequence number inside the
269 OpenClipboard/ CloseClipboard block to avoid race conditions
270 where another app puts something on the clipboard straight after
271 us. But experience suggests that the sequence number from the
272 SetClipboardData is not allocated until we close the clipboard!
273 Since clipboard operations are normally user-driven, the race
274 condition is probably not going to really happen. */
275 if (clipboard_sequence_fn)
276 last_clipboard_sequence_number = clipboard_sequence_fn ();
277
278 if (ok) goto done;
279
280 error:
281
282 ok = FALSE;
283 if (htext) GlobalFree (htext);
284 if (last_clipboard_text)
285 *last_clipboard_text = '\0';
286
287 last_clipboard_sequence_number = 0;
288
289 done:
290 UNBLOCK_INPUT;
291
292 return (ok ? string : Qnil);
293 }
294
295 DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
296 Sw32_get_clipboard_data, 0, 1, 0,
297 doc: /* This gets the clipboard data in text format. */)
298 (frame)
299 Lisp_Object frame;
300 {
301 HANDLE htext;
302 Lisp_Object ret = Qnil;
303
304 if (!NILP (frame))
305 CHECK_LIVE_FRAME (frame);
306
307 BLOCK_INPUT;
308
309 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
310 goto done;
311
312 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
313 goto closeclip;
314
315 {
316 unsigned char *src;
317 unsigned char *dst;
318 int nbytes;
319 int truelen;
320 int require_decoding = 0;
321
322 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
323 goto closeclip;
324
325 nbytes = strlen (src);
326
327 /* If the text in clipboard is identical to what we put there
328 last time w32_set_clipboard_data was called, pretend there's no
329 data in the clipboard. This is so we don't pass our own text
330 from the clipboard (which might be troublesome if the killed
331 text includes null characters). */
332 if ((clipboard_sequence_fn
333 && clipboard_sequence_fn () == last_clipboard_sequence_number)
334 || (last_clipboard_text
335 && clipboard_storage_size >= nbytes
336 && memcmp(last_clipboard_text, src, nbytes) == 0))
337 goto closeclip;
338
339 {
340 /* If the clipboard data contains any non-ascii code, we
341 need to decode it. */
342 int i;
343
344 for (i = 0; i < nbytes; i++)
345 {
346 if (src[i] >= 0x80)
347 {
348 require_decoding = 1;
349 break;
350 }
351 }
352 }
353
354 if (require_decoding)
355 {
356 int bufsize;
357 unsigned char *buf;
358 struct coding_system coding;
359
360 if (NILP (Vnext_selection_coding_system))
361 Vnext_selection_coding_system = Vselection_coding_system;
362 setup_coding_system
363 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
364 coding.src_multibyte = 0;
365 coding.dst_multibyte = 1;
366 Vnext_selection_coding_system = Qnil;
367 coding.mode |= CODING_MODE_LAST_BLOCK;
368 /* We explicitely disable composition handling because
369 selection data should not contain any composition
370 sequence. */
371 coding.composing = COMPOSITION_DISABLED;
372 bufsize = decoding_buffer_size (&coding, nbytes);
373 buf = (unsigned char *) xmalloc (bufsize);
374 decode_coding (&coding, src, buf, nbytes, bufsize);
375 Vlast_coding_system_used = coding.symbol;
376 ret = make_string_from_bytes ((char *) buf,
377 coding.produced_char, coding.produced);
378 xfree (buf);
379 if (SYMBOLP (coding.post_read_conversion)
380 && !NILP (Ffboundp (coding.post_read_conversion)))
381 ret = run_pre_post_conversion_on_str (ret, &coding, 0);
382 }
383 else
384 {
385 /* Need to know final size after CR chars are removed because we
386 can't change the string size manually, and doing an extra
387 copy is silly. Note that we only remove CR when it appears
388 as part of CRLF. */
389
390 truelen = nbytes;
391 dst = src;
392 /* avoid using strchr because it recomputes the length everytime */
393 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
394 {
395 if (dst[1] == '\n') /* safe because of trailing '\0' */
396 truelen--;
397 dst++;
398 }
399
400 ret = make_uninit_string (truelen);
401
402 /* Convert CRLF line endings (the standard CF_TEXT clipboard
403 format) to LF endings as used internally by Emacs. */
404
405 dst = SDATA (ret);
406 while (1)
407 {
408 unsigned char *next;
409 /* copy next line or remaining bytes excluding '\0' */
410 next = _memccpy (dst, src, '\r', nbytes);
411 if (next)
412 {
413 /* copied one line ending with '\r' */
414 int copied = next - dst;
415 nbytes -= copied;
416 dst += copied;
417 src += copied;
418 if (*src == '\n')
419 dst--; /* overwrite '\r' with '\n' */
420 }
421 else
422 /* copied remaining partial line -> now finished */
423 break;
424 }
425
426 Vlast_coding_system_used = Qraw_text;
427 }
428
429 GlobalUnlock (htext);
430 }
431
432 closeclip:
433 CloseClipboard ();
434
435 done:
436 UNBLOCK_INPUT;
437
438 return (ret);
439 }
440
441 /* Support checking for a clipboard selection. */
442
443 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
444 0, 1, 0,
445 doc: /* Whether there is an owner for the given X Selection.
446 The arg should be the name of the selection in question, typically one of
447 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
448 \(Those are literal upper-case symbol names, since that's what X expects.)
449 For convenience, the symbol nil is the same as `PRIMARY',
450 and t is the same as `SECONDARY'. */)
451 (selection)
452 Lisp_Object selection;
453 {
454 CHECK_SYMBOL (selection);
455
456 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
457 if the clipboard currently has valid text format contents. */
458
459 if (EQ (selection, QCLIPBOARD))
460 {
461 Lisp_Object val = Qnil;
462
463 if (OpenClipboard (NULL))
464 {
465 int format = 0;
466 while (format = EnumClipboardFormats (format))
467 if (format == CF_TEXT)
468 {
469 val = Qt;
470 break;
471 }
472 CloseClipboard ();
473 }
474 return val;
475 }
476 return Qnil;
477 }
478
479 void
480 syms_of_w32select ()
481 {
482 #if 0
483 defsubr (&Sw32_open_clipboard);
484 defsubr (&Sw32_empty_clipboard);
485 defsubr (&Sw32_close_clipboard);
486 #endif
487 defsubr (&Sw32_set_clipboard_data);
488 defsubr (&Sw32_get_clipboard_data);
489 defsubr (&Sx_selection_exists_p);
490
491 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
492 doc: /* Coding system for communicating with other programs.
493 When sending or receiving text via cut_buffer, selection, and clipboard,
494 the text is encoded or decoded by this coding system.
495 The default value is `iso-latin-1-dos'. */);
496 Vselection_coding_system = intern ("iso-latin-1-dos");
497
498 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
499 doc: /* Coding system for the next communication with other programs.
500 Usually, `selection-coding-system' is used for communicating with
501 other programs. But, if this variable is set, it is used for the
502 next communication only. After the communication, this variable is
503 set to nil. */);
504 Vnext_selection_coding_system = Qnil;
505
506 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
507 }
508
509 /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af
510 (do not change this comment) */