(Fw32_get_clipboard_data): Disable composition handling.
[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
34 Lisp_Object QCLIPBOARD;
35
36 /* Coding system for communicating with other Windows programs via the
37 clipboard. */
38 static Lisp_Object Vselection_coding_system;
39
40 /* Coding system for the next communicating with other Windows programs. */
41 static Lisp_Object Vnext_selection_coding_system;
42
43 /* The last text we put into the clipboard. This is used to prevent
44 passing back our own text from the clipboard, instead of using the
45 kill ring. The former is undesirable because the clipboard data
46 could be MULEtilated by inappropriately chosen
47 (next-)selection-coding-system. For this reason, we must store the
48 text *after* it was encoded/Unix-to-DOS-converted. */
49 static unsigned char *last_clipboard_text = NULL;
50 static size_t clipboard_storage_size = 0;
51
52 #if 0
53 DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0,
54 doc: /* This opens the clipboard with the given frame pointer. */)
55 (frame)
56 Lisp_Object frame;
57 {
58 BOOL ok = FALSE;
59
60 if (!NILP (frame))
61 CHECK_LIVE_FRAME (frame);
62
63 BLOCK_INPUT;
64
65 ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL);
66
67 UNBLOCK_INPUT;
68
69 return (ok ? frame : Qnil);
70 }
71
72 DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard,
73 Sw32_empty_clipboard, 0, 0, 0,
74 doc: /* Empty the clipboard.
75 Assigns ownership of the clipboard to the window which opened it. */)
76 ()
77 {
78 BOOL ok = FALSE;
79
80 BLOCK_INPUT;
81
82 ok = EmptyClipboard ();
83
84 UNBLOCK_INPUT;
85
86 return (ok ? Qt : Qnil);
87 }
88
89 DEFUN ("w32-close-clipboard", Fw32_close_clipboard,
90 Sw32_close_clipboard, 0, 0, 0,
91 doc: /* Close the clipboard. */)
92 ()
93 {
94 BOOL ok = FALSE;
95
96 BLOCK_INPUT;
97
98 ok = CloseClipboard ();
99
100 UNBLOCK_INPUT;
101
102 return (ok ? Qt : Qnil);
103 }
104
105 #endif
106
107 DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
108 Sw32_set_clipboard_data, 1, 2, 0,
109 doc: /* This sets the clipboard data to the given text. */)
110 (string, frame)
111 Lisp_Object string, frame;
112 {
113 BOOL ok = TRUE;
114 HANDLE htext;
115 int nbytes;
116 int truelen, nlines = 0;
117 unsigned char *src;
118 unsigned char *dst;
119
120 CHECK_STRING (string);
121
122 if (!NILP (frame))
123 CHECK_LIVE_FRAME (frame);
124
125 BLOCK_INPUT;
126
127 nbytes = STRING_BYTES (XSTRING (string)) + 1;
128 src = XSTRING (string)->data;
129 dst = src;
130
131 /* We need to know how many lines there are, since we need CRLF line
132 termination for compatibility with other Windows Programs.
133 avoid using strchr because it recomputes the length every time */
134 while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
135 {
136 nlines++;
137 dst++;
138 }
139
140 {
141 /* Since we are now handling multilingual text, we must consider
142 encoding text for the clipboard. */
143 int charset_info = find_charset_in_text (src, XSTRING (string)->size,
144 nbytes, NULL, Qnil);
145
146 if (charset_info == 0)
147 {
148 /* No multibyte character in OBJ. We need not encode it. */
149
150 /* Need to know final size after CR chars are inserted (the
151 standard CF_TEXT clipboard format uses CRLF line endings,
152 while Emacs uses just LF internally). */
153
154 truelen = nbytes + nlines;
155
156 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
157 goto error;
158
159 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
160 goto error;
161
162 /* convert to CRLF line endings expected by clipboard */
163 while (1)
164 {
165 unsigned char *next;
166 /* copy next line or remaining bytes including '\0' */
167 next = _memccpy (dst, src, '\n', nbytes);
168 if (next)
169 {
170 /* copied one line ending with '\n' */
171 int copied = next - dst;
172 nbytes -= copied;
173 src += copied;
174 /* insert '\r' before '\n' */
175 next[-1] = '\r';
176 next[0] = '\n';
177 dst = next + 1;
178 }
179 else
180 /* copied remaining partial line -> now finished */
181 break;
182 }
183
184 GlobalUnlock (htext);
185
186 Vlast_coding_system_used = Qraw_text;
187 }
188 else
189 {
190 /* We must encode contents of OBJ to the selection coding
191 system. */
192 int bufsize;
193 struct coding_system coding;
194 HANDLE htext2;
195
196 if (NILP (Vnext_selection_coding_system))
197 Vnext_selection_coding_system = Vselection_coding_system;
198 setup_coding_system
199 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
200 if (SYMBOLP (coding.pre_write_conversion)
201 && !NILP (Ffboundp (coding.pre_write_conversion)))
202 {
203 string = run_pre_post_conversion_on_str (string, &coding, 1);
204 src = XSTRING (string)->data;
205 nbytes = STRING_BYTES (XSTRING (string));
206 }
207 coding.src_multibyte = 1;
208 coding.dst_multibyte = 0;
209 Vnext_selection_coding_system = Qnil;
210 coding.mode |= CODING_MODE_LAST_BLOCK;
211 bufsize = encoding_buffer_size (&coding, nbytes);
212 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL)
213 goto error;
214 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
215 goto error;
216 encode_coding (&coding, src, dst, nbytes, bufsize);
217 Vlast_coding_system_used = coding.symbol;
218
219 /* Stash away the data we are about to put into the clipboard, so we
220 could later check inside Fw32_get_clipboard_data whether
221 the clipboard still holds our data. */
222 if (clipboard_storage_size < coding.produced)
223 {
224 clipboard_storage_size = coding.produced + 100;
225 last_clipboard_text = (char *) xrealloc (last_clipboard_text,
226 clipboard_storage_size);
227 }
228 if (last_clipboard_text)
229 memcpy (last_clipboard_text, dst, coding.produced);
230
231 GlobalUnlock (htext);
232
233 /* Shrink data block to actual size. */
234 htext2 = GlobalReAlloc (htext, coding.produced,
235 GMEM_MOVEABLE | GMEM_DDESHARE);
236 if (htext2 != NULL) htext = htext2;
237 }
238 }
239
240 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
241 goto error;
242
243 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
244
245 CloseClipboard ();
246
247 if (ok) goto done;
248
249 error:
250
251 ok = FALSE;
252 if (htext) GlobalFree (htext);
253 if (last_clipboard_text)
254 *last_clipboard_text = '\0';
255
256 done:
257 UNBLOCK_INPUT;
258
259 return (ok ? string : Qnil);
260 }
261
262 DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
263 Sw32_get_clipboard_data, 0, 1, 0,
264 doc: /* This gets the clipboard data in text format. */)
265 (frame)
266 Lisp_Object frame;
267 {
268 HANDLE htext;
269 Lisp_Object ret = Qnil;
270
271 if (!NILP (frame))
272 CHECK_LIVE_FRAME (frame);
273
274 BLOCK_INPUT;
275
276 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
277 goto done;
278
279 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
280 goto closeclip;
281
282 {
283 unsigned char *src;
284 unsigned char *dst;
285 int nbytes;
286 int truelen;
287 int require_decoding = 0;
288
289 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
290 goto closeclip;
291
292 nbytes = strlen (src);
293
294 /* If the text in clipboard is identical to what we put there
295 last time w32_set_clipboard_data was called, pretend there's no
296 data in the clipboard. This is so we don't pass our own text
297 from the clipboard (which might be troublesome if the killed
298 text includes null characters). */
299 if (last_clipboard_text
300 && clipboard_storage_size >= nbytes
301 && memcmp(last_clipboard_text, src, nbytes) == 0)
302 goto closeclip;
303
304 {
305 /* If the clipboard data contains any non-ascii code, we
306 need to decode it. */
307 int i;
308
309 for (i = 0; i < nbytes; i++)
310 {
311 if (src[i] >= 0x80)
312 {
313 require_decoding = 1;
314 break;
315 }
316 }
317 }
318
319 if (require_decoding)
320 {
321 int bufsize;
322 unsigned char *buf;
323 struct coding_system coding;
324
325 if (NILP (Vnext_selection_coding_system))
326 Vnext_selection_coding_system = Vselection_coding_system;
327 setup_coding_system
328 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
329 coding.src_multibyte = 0;
330 coding.dst_multibyte = 1;
331 Vnext_selection_coding_system = Qnil;
332 coding.mode |= CODING_MODE_LAST_BLOCK;
333 /* We explicitely disable composition handling because
334 selection data should not contain any composition
335 sequence. */
336 coding.composing = COMPOSITION_DISABLED;
337 bufsize = decoding_buffer_size (&coding, nbytes);
338 buf = (unsigned char *) xmalloc (bufsize);
339 decode_coding (&coding, src, buf, nbytes, bufsize);
340 Vlast_coding_system_used = coding.symbol;
341 ret = make_string_from_bytes ((char *) buf,
342 coding.produced_char, coding.produced);
343 xfree (buf);
344 if (SYMBOLP (coding.post_read_conversion)
345 && !NILP (Ffboundp (coding.post_read_conversion)))
346 ret = run_pre_post_conversion_on_str (ret, &coding, 0);
347 }
348 else
349 {
350 /* Need to know final size after CR chars are removed because we
351 can't change the string size manually, and doing an extra
352 copy is silly. Note that we only remove CR when it appears
353 as part of CRLF. */
354
355 truelen = nbytes;
356 dst = src;
357 /* avoid using strchr because it recomputes the length everytime */
358 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
359 {
360 if (dst[1] == '\n') /* safe because of trailing '\0' */
361 truelen--;
362 dst++;
363 }
364
365 ret = make_uninit_string (truelen);
366
367 /* Convert CRLF line endings (the standard CF_TEXT clipboard
368 format) to LF endings as used internally by Emacs. */
369
370 dst = XSTRING (ret)->data;
371 while (1)
372 {
373 unsigned char *next;
374 /* copy next line or remaining bytes excluding '\0' */
375 next = _memccpy (dst, src, '\r', nbytes);
376 if (next)
377 {
378 /* copied one line ending with '\r' */
379 int copied = next - dst;
380 nbytes -= copied;
381 dst += copied;
382 src += copied;
383 if (*src == '\n')
384 dst--; /* overwrite '\r' with '\n' */
385 }
386 else
387 /* copied remaining partial line -> now finished */
388 break;
389 }
390
391 Vlast_coding_system_used = Qraw_text;
392 }
393
394 GlobalUnlock (htext);
395 }
396
397 closeclip:
398 CloseClipboard ();
399
400 done:
401 UNBLOCK_INPUT;
402
403 return (ret);
404 }
405
406 /* Support checking for a clipboard selection. */
407
408 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
409 0, 1, 0,
410 doc: /* Whether there is an owner for the given X Selection.
411 The arg should be the name of the selection in question, typically one of
412 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
413 \(Those are literal upper-case symbol names, since that's what X expects.)
414 For convenience, the symbol nil is the same as `PRIMARY',
415 and t is the same as `SECONDARY'. */)
416 (selection)
417 Lisp_Object selection;
418 {
419 CHECK_SYMBOL (selection);
420
421 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
422 if the clipboard currently has valid text format contents. */
423
424 if (EQ (selection, QCLIPBOARD))
425 {
426 Lisp_Object val = Qnil;
427
428 if (OpenClipboard (NULL))
429 {
430 int format = 0;
431 while (format = EnumClipboardFormats (format))
432 if (format == CF_TEXT)
433 {
434 val = Qt;
435 break;
436 }
437 CloseClipboard ();
438 }
439 return val;
440 }
441 return Qnil;
442 }
443
444 void
445 syms_of_w32select ()
446 {
447 #if 0
448 defsubr (&Sw32_open_clipboard);
449 defsubr (&Sw32_empty_clipboard);
450 defsubr (&Sw32_close_clipboard);
451 #endif
452 defsubr (&Sw32_set_clipboard_data);
453 defsubr (&Sw32_get_clipboard_data);
454 defsubr (&Sx_selection_exists_p);
455
456 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
457 doc: /* Coding system for communicating with other programs.
458 When sending or receiving text via cut_buffer, selection, and clipboard,
459 the text is encoded or decoded by this coding system. */);
460 Vselection_coding_system=intern ("iso-latin-1-dos");
461
462 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
463 doc: /* Coding system for the next communication with other programs.
464 Usually, `selection-coding-system' is used for communicating with
465 other programs. But, if this variable is set, it is used for the
466 next communication only. After the communication, this variable is
467 set to nil. */);
468 Vnext_selection_coding_system = Qnil;
469
470 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
471 }