1 /* Selection processing for Emacs on the Microsoft W32 API.
2 Copyright (C) 1993, 1994 Free Software Foundation.
4 This file is part of GNU Emacs.
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)
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.
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. */
21 /* Written by Kevin Gallo */
25 #include "w32term.h" /* for all of the w32 includes */
26 #include "dispextern.h" /* frame.h seems to want this */
28 #include "frame.h" /* Need this to get the X window of selected_frame */
29 #include "blockinput.h"
34 Lisp_Object QCLIPBOARD
;
36 /* Coding system for communicating with other Windows programs via the
38 static Lisp_Object Vselection_coding_system
;
40 /* Coding system for the next communicating with other Windows programs. */
41 static Lisp_Object Vnext_selection_coding_system
;
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;
53 DEFUN ("w32-open-clipboard", Fw32_open_clipboard
, Sw32_open_clipboard
, 0, 1, 0,
54 "This opens the clipboard with the given frame pointer.")
61 CHECK_LIVE_FRAME (frame
, 0);
65 ok
= OpenClipboard ((!NILP (frame
) && FRAME_W32_P (XFRAME (frame
))) ? FRAME_W32_WINDOW (XFRAME (frame
)) : NULL
);
69 return (ok
? frame
: Qnil
);
72 DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard
, Sw32_empty_clipboard
, 0, 0, 0,
73 "This empties the clipboard and assigns ownership to the window which opened the clipboard.")
80 ok
= EmptyClipboard ();
84 return (ok
? Qt
: Qnil
);
87 DEFUN ("w32-close-clipboard", Fw32_close_clipboard
, Sw32_close_clipboard
, 0, 0, 0,
88 "This closes the clipboard.")
95 ok
= CloseClipboard ();
99 return (ok
? Qt
: Qnil
);
104 DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data
, Sw32_set_clipboard_data
, 1, 2, 0,
105 "This sets the clipboard data to the given text.")
107 Lisp_Object string
, frame
;
112 int truelen
, nlines
= 0;
116 CHECK_STRING (string
, 0);
119 CHECK_LIVE_FRAME (frame
, 0);
123 nbytes
= STRING_BYTES (XSTRING (string
)) + 1;
124 src
= XSTRING (string
)->data
;
127 /* We need to know how many lines there are, since we need CRLF line
128 termination for compatibility with other Windows Programs.
129 avoid using strchr because it recomputes the length every time */
130 while ((dst
= memchr (dst
, '\n', nbytes
- (dst
- src
))) != NULL
)
137 /* Since we are now handling multilingual text, we must consider
138 encoding text for the clipboard. */
139 int charset_info
= find_charset_in_text (src
, XSTRING (string
)->size
,
142 if (charset_info
== 0)
144 /* No multibyte character in OBJ. We need not encode it. */
146 /* Need to know final size after CR chars are inserted (the
147 standard CF_TEXT clipboard format uses CRLF line endings,
148 while Emacs uses just LF internally). */
150 truelen
= nbytes
+ nlines
;
152 if ((htext
= GlobalAlloc (GMEM_MOVEABLE
| GMEM_DDESHARE
, truelen
)) == NULL
)
155 if ((dst
= (unsigned char *) GlobalLock (htext
)) == NULL
)
158 /* convert to CRLF line endings expected by clipboard */
162 /* copy next line or remaining bytes including '\0' */
163 next
= _memccpy (dst
, src
, '\n', nbytes
);
166 /* copied one line ending with '\n' */
167 int copied
= next
- dst
;
170 /* insert '\r' before '\n' */
176 /* copied remaining partial line -> now finished */
180 GlobalUnlock (htext
);
182 Vlast_coding_system_used
= Qraw_text
;
186 /* We must encode contents of OBJ to the selection coding
189 struct coding_system coding
;
192 if (NILP (Vnext_selection_coding_system
))
193 Vnext_selection_coding_system
= Vselection_coding_system
;
195 (Fcheck_coding_system (Vnext_selection_coding_system
), &coding
);
196 coding
.src_multibyte
= 1;
197 coding
.dst_multibyte
= 0;
198 Vnext_selection_coding_system
= Qnil
;
199 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
200 bufsize
= encoding_buffer_size (&coding
, nbytes
);
201 if ((htext
= GlobalAlloc (GMEM_MOVEABLE
| GMEM_DDESHARE
, bufsize
)) == NULL
)
203 if ((dst
= (unsigned char *) GlobalLock (htext
)) == NULL
)
205 encode_coding (&coding
, src
, dst
, nbytes
, bufsize
);
206 Vlast_coding_system_used
= coding
.symbol
;
208 /* Stash away the data we are about to put into the clipboard, so we
209 could later check inside Fw32_get_clipboard_data whether
210 the clipboard still holds our data. */
211 if (clipboard_storage_size
< coding
.produced
)
213 clipboard_storage_size
= coding
.produced
+ 100;
214 last_clipboard_text
= (char *) xrealloc (last_clipboard_text
,
215 clipboard_storage_size
);
217 if (last_clipboard_text
)
218 memcpy (last_clipboard_text
, dst
, coding
.produced
);
220 GlobalUnlock (htext
);
222 /* Shrink data block to actual size. */
223 htext2
= GlobalReAlloc (htext
, coding
.produced
,
224 GMEM_MOVEABLE
| GMEM_DDESHARE
);
225 if (htext2
!= NULL
) htext
= htext2
;
229 if (!OpenClipboard ((!NILP (frame
) && FRAME_W32_P (XFRAME (frame
))) ? FRAME_W32_WINDOW (XFRAME (frame
)) : NULL
))
232 ok
= EmptyClipboard () && SetClipboardData (CF_TEXT
, htext
);
241 if (htext
) GlobalFree (htext
);
242 if (last_clipboard_text
)
243 *last_clipboard_text
= '\0';
248 return (ok
? string
: Qnil
);
251 DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data
, Sw32_get_clipboard_data
, 0, 1, 0,
252 "This gets the clipboard data in text format.")
257 Lisp_Object ret
= Qnil
;
260 CHECK_LIVE_FRAME (frame
, 0);
264 if (!OpenClipboard ((!NILP (frame
) && FRAME_W32_P (XFRAME (frame
))) ? FRAME_W32_WINDOW (XFRAME (frame
)) : NULL
))
267 if ((htext
= GetClipboardData (CF_TEXT
)) == NULL
)
275 int require_decoding
= 0;
277 if ((src
= (unsigned char *) GlobalLock (htext
)) == NULL
)
280 nbytes
= strlen (src
);
282 /* If the text in clipboard is identical to what we put there
283 last time w32_set_clipboard_data was called, pretend there's no
284 data in the clipboard. This is so we don't pass our own text
285 from the clipboard (which might be troublesome if the killed
286 text includes null characters). */
287 if (last_clipboard_text
288 && clipboard_storage_size
>= nbytes
289 && memcmp(last_clipboard_text
, src
, nbytes
) == 0)
296 ! NILP (buffer_defaults
.enable_multibyte_characters
)
300 /* If the clipboard data contains any non-ascii code, we
301 need to decode it. */
304 for (i
= 0; i
< nbytes
; i
++)
308 require_decoding
= 1;
314 if (require_decoding
)
318 struct coding_system coding
;
320 if (NILP (Vnext_selection_coding_system
))
321 Vnext_selection_coding_system
= Vselection_coding_system
;
323 (Fcheck_coding_system (Vnext_selection_coding_system
), &coding
);
324 coding
.src_multibyte
= 0;
325 coding
.dst_multibyte
= 1;
326 Vnext_selection_coding_system
= Qnil
;
327 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
328 bufsize
= decoding_buffer_size (&coding
, nbytes
);
329 buf
= (unsigned char *) xmalloc (bufsize
);
330 decode_coding (&coding
, src
, buf
, nbytes
, bufsize
);
331 Vlast_coding_system_used
= coding
.symbol
;
332 ret
= make_string_from_bytes ((char *) buf
,
333 coding
.produced_char
, coding
.produced
);
338 /* Need to know final size after CR chars are removed because we
339 can't change the string size manually, and doing an extra
340 copy is silly. Note that we only remove CR when it appears
345 /* avoid using strchr because it recomputes the length everytime */
346 while ((dst
= memchr (dst
, '\r', nbytes
- (dst
- src
))) != NULL
)
348 if (dst
[1] == '\n') /* safe because of trailing '\0' */
353 ret
= make_uninit_string (truelen
);
355 /* Convert CRLF line endings (the standard CF_TEXT clipboard
356 format) to LF endings as used internally by Emacs. */
358 dst
= XSTRING (ret
)->data
;
362 /* copy next line or remaining bytes excluding '\0' */
363 next
= _memccpy (dst
, src
, '\r', nbytes
);
366 /* copied one line ending with '\r' */
367 int copied
= next
- dst
;
372 dst
--; /* overwrite '\r' with '\n' */
375 /* copied remaining partial line -> now finished */
379 Vlast_coding_system_used
= Qraw_text
;
382 GlobalUnlock (htext
);
394 /* Support checking for a clipboard selection. */
396 DEFUN ("x-selection-exists-p", Fx_selection_exists_p
, Sx_selection_exists_p
,
398 "Whether there is an owner for the given X Selection.\n\
399 The arg should be the name of the selection in question, typically one of\n\
400 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
401 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
402 For convenience, the symbol nil is the same as `PRIMARY',\n\
403 and t is the same as `SECONDARY'.")
405 Lisp_Object selection
;
407 CHECK_SYMBOL (selection
, 0);
409 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
410 if the clipboard currently has valid text format contents. */
412 if (EQ (selection
, QCLIPBOARD
))
414 Lisp_Object val
= Qnil
;
416 if (OpenClipboard (NULL
))
419 while (format
= EnumClipboardFormats (format
))
420 if (format
== CF_TEXT
)
436 defsubr (&Sw32_open_clipboard
);
437 defsubr (&Sw32_empty_clipboard
);
438 defsubr (&Sw32_close_clipboard
);
440 defsubr (&Sw32_set_clipboard_data
);
441 defsubr (&Sw32_get_clipboard_data
);
442 defsubr (&Sx_selection_exists_p
);
444 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system
,
445 "Coding system for communicating with other X clients.\n\
446 When sending or receiving text via cut_buffer, selection, and clipboard,\n\
447 the text is encoded or decoded by this coding system.\n\
448 A default value is `compound-text'");
449 Vselection_coding_system
=intern ("iso-latin-1-dos");
451 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system
,
452 "Coding system for the next communication with other X clients.\n\
453 Usually, `selection-coding-system' is used for communicating with\n\
454 other X clients. But, if this variable is set, it is used for the\n\
455 next communication only. After the communication, this variable is\n\
457 Vnext_selection_coding_system
= Qnil
;
459 QCLIPBOARD
= intern ("CLIPBOARD"); staticpro (&QCLIPBOARD
);