*** empty log message ***
[emacs.git] / src / w32select.c
blob2877e1657cc23b1772bb61e431f774ecb220e89b
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)
9 any later version.
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 */
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 "frame.h" /* Need this to get the X window of selected_frame */
28 #include "blockinput.h"
29 #include "buffer.h"
30 #include "charset.h"
31 #include "coding.h"
33 Lisp_Object QCLIPBOARD;
35 /* Coding system for communicating with other Windows programs via the
36 clipboard. */
37 static Lisp_Object Vselection_coding_system;
39 /* Coding system for the next communicating with other X clients. */
40 static Lisp_Object Vnext_selection_coding_system;
42 #if 0
43 DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0,
44 "This opens the clipboard with the given frame pointer.")
45 (frame)
46 Lisp_Object frame;
48 BOOL ok = FALSE;
50 if (!NILP (frame))
51 CHECK_LIVE_FRAME (frame, 0);
53 BLOCK_INPUT;
55 ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL);
57 UNBLOCK_INPUT;
59 return (ok ? frame : Qnil);
62 DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard, Sw32_empty_clipboard, 0, 0, 0,
63 "This empties the clipboard and assigns ownership to the window which opened the clipboard.")
66 BOOL ok = FALSE;
68 BLOCK_INPUT;
70 ok = EmptyClipboard ();
72 UNBLOCK_INPUT;
74 return (ok ? Qt : Qnil);
77 DEFUN ("w32-close-clipboard", Fw32_close_clipboard, Sw32_close_clipboard, 0, 0, 0,
78 "This closes the clipboard.")
81 BOOL ok = FALSE;
83 BLOCK_INPUT;
85 ok = CloseClipboard ();
87 UNBLOCK_INPUT;
89 return (ok ? Qt : Qnil);
92 #endif
94 DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, Sw32_set_clipboard_data, 1, 2, 0,
95 "This sets the clipboard data to the given text.")
96 (string, frame)
97 Lisp_Object string, frame;
99 BOOL ok = TRUE;
100 HANDLE htext;
101 int nbytes;
102 int truelen, nlines = 0;
103 unsigned char *src;
104 unsigned char *dst;
106 CHECK_STRING (string, 0);
108 if (!NILP (frame))
109 CHECK_LIVE_FRAME (frame, 0);
111 BLOCK_INPUT;
113 nbytes = STRING_BYTES (XSTRING (string)) + 1;
114 src = XSTRING (string)->data;
115 dst = src;
117 /* We need to know how many lines there are, since we need CRLF line
118 termination for compatibility with other Windows Programs.
119 avoid using strchr because it recomputes the length every time */
120 while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
122 nlines++;
123 dst++;
127 /* Since we are now handling multilingual text, we must consider
128 encoding text for the clipboard. */
129 int charset_info = find_charset_in_text (src, XSTRING (string)->size,
130 nbytes, NULL, Qnil);
132 if (charset_info == 0)
134 /* No multibyte character in OBJ. We need not encode it. */
136 /* Need to know final size after CR chars are inserted (the
137 standard CF_TEXT clipboard format uses CRLF line endings,
138 while Emacs uses just LF internally). */
140 truelen = nbytes + nlines;
142 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
143 goto error;
145 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
146 goto error;
148 /* convert to CRLF line endings expected by clipboard */
149 while (1)
151 unsigned char *next;
152 /* copy next line or remaining bytes including '\0' */
153 next = _memccpy (dst, src, '\n', nbytes);
154 if (next)
156 /* copied one line ending with '\n' */
157 int copied = next - dst;
158 nbytes -= copied;
159 src += copied;
160 /* insert '\r' before '\n' */
161 next[-1] = '\r';
162 next[0] = '\n';
163 dst = next + 1;
165 else
166 /* copied remaining partial line -> now finished */
167 break;
170 GlobalUnlock (htext);
172 Vlast_coding_system_used = Qraw_text;
174 else
176 /* We must encode contents of OBJ to compound text format.
177 The format is compatible with what the target `STRING'
178 expects if OBJ contains only ASCII and Latin-1
179 characters. */
180 int bufsize;
181 struct coding_system coding;
182 HANDLE htext2;
184 if (NILP (Vnext_selection_coding_system))
185 Vnext_selection_coding_system = Vselection_coding_system;
186 setup_coding_system
187 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
188 coding.src_multibyte = 1;
189 coding.dst_multibyte = 0;
190 Vnext_selection_coding_system = Qnil;
191 coding.mode |= CODING_MODE_LAST_BLOCK;
192 bufsize = encoding_buffer_size (&coding, nbytes);
193 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL)
194 goto error;
195 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
196 goto error;
197 encode_coding (&coding, src, dst, nbytes, bufsize);
198 Vlast_coding_system_used = coding.symbol;
199 GlobalUnlock (htext);
200 /* Shrink data block to actual size. */
201 htext2 = GlobalReAlloc (htext, coding.produced, GMEM_MOVEABLE | GMEM_DDESHARE);
202 if (htext2 != NULL) htext = htext2;
206 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
207 goto error;
209 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
211 CloseClipboard ();
213 if (ok) goto done;
215 error:
217 ok = FALSE;
218 if (htext) GlobalFree (htext);
220 done:
221 UNBLOCK_INPUT;
223 return (ok ? string : Qnil);
226 DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, Sw32_get_clipboard_data, 0, 1, 0,
227 "This gets the clipboard data in text format.")
228 (frame)
229 Lisp_Object frame;
231 HANDLE htext;
232 Lisp_Object ret = Qnil;
234 if (!NILP (frame))
235 CHECK_LIVE_FRAME (frame, 0);
237 BLOCK_INPUT;
239 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
240 goto done;
242 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
243 goto closeclip;
246 unsigned char *src;
247 unsigned char *dst;
248 int nbytes;
249 int truelen;
250 int require_decoding = 0;
252 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
253 goto closeclip;
255 nbytes = strlen (src);
257 if (
258 #if 1
260 #else
261 ! NILP (buffer_defaults.enable_multibyte_characters)
262 #endif
265 /* If the clipboard data contains any non-ascii code, we
266 need to decode it. */
267 int i;
269 for (i = 0; i < nbytes; i++)
271 if (src[i] >= 0x80)
273 require_decoding = 1;
274 break;
279 if (require_decoding)
281 int bufsize;
282 unsigned char *buf;
283 struct coding_system coding;
285 if (NILP (Vnext_selection_coding_system))
286 Vnext_selection_coding_system = Vselection_coding_system;
287 setup_coding_system
288 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
289 coding.src_multibyte = 0;
290 coding.dst_multibyte = 1;
291 Vnext_selection_coding_system = Qnil;
292 coding.mode |= CODING_MODE_LAST_BLOCK;
293 bufsize = decoding_buffer_size (&coding, nbytes);
294 buf = (unsigned char *) xmalloc (bufsize);
295 decode_coding (&coding, src, buf, nbytes, bufsize);
296 Vlast_coding_system_used = coding.symbol;
297 ret = make_string_from_bytes ((char *) buf,
298 coding.produced_char, coding.produced);
299 xfree (buf);
301 else
303 /* Need to know final size after CR chars are removed because we
304 can't change the string size manually, and doing an extra
305 copy is silly. Note that we only remove CR when it appears
306 as part of CRLF. */
308 truelen = nbytes;
309 dst = src;
310 /* avoid using strchr because it recomputes the length everytime */
311 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
313 if (dst[1] == '\n') /* safe because of trailing '\0' */
314 truelen--;
315 dst++;
318 ret = make_uninit_string (truelen);
320 /* Convert CRLF line endings (the standard CF_TEXT clipboard
321 format) to LF endings as used internally by Emacs. */
323 dst = XSTRING (ret)->data;
324 while (1)
326 unsigned char *next;
327 /* copy next line or remaining bytes excluding '\0' */
328 next = _memccpy (dst, src, '\r', nbytes);
329 if (next)
331 /* copied one line ending with '\r' */
332 int copied = next - dst;
333 nbytes -= copied;
334 dst += copied;
335 src += copied;
336 if (*src == '\n')
337 dst--; /* overwrite '\r' with '\n' */
339 else
340 /* copied remaining partial line -> now finished */
341 break;
344 Vlast_coding_system_used = Qraw_text;
347 GlobalUnlock (htext);
350 closeclip:
351 CloseClipboard ();
353 done:
354 UNBLOCK_INPUT;
356 return (ret);
359 /* Support checking for a clipboard selection. */
361 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
362 0, 1, 0,
363 "Whether there is an owner for the given X Selection.\n\
364 The arg should be the name of the selection in question, typically one of\n\
365 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
366 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
367 For convenience, the symbol nil is the same as `PRIMARY',\n\
368 and t is the same as `SECONDARY'.")
369 (selection)
370 Lisp_Object selection;
372 CHECK_SYMBOL (selection, 0);
374 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
375 if the clipboard currently has valid text format contents. */
377 if (EQ (selection, QCLIPBOARD))
379 Lisp_Object val = Qnil;
381 if (OpenClipboard (NULL))
383 int format = 0;
384 while (format = EnumClipboardFormats (format))
385 if (format == CF_TEXT)
387 val = Qt;
388 break;
390 CloseClipboard ();
392 return val;
394 return Qnil;
397 void
398 syms_of_w32select ()
400 #if 0
401 defsubr (&Sw32_open_clipboard);
402 defsubr (&Sw32_empty_clipboard);
403 defsubr (&Sw32_close_clipboard);
404 #endif
405 defsubr (&Sw32_set_clipboard_data);
406 defsubr (&Sw32_get_clipboard_data);
407 defsubr (&Sx_selection_exists_p);
409 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
410 "Coding system for communicating with other X clients.\n\
411 When sending or receiving text via cut_buffer, selection, and clipboard,\n\
412 the text is encoded or decoded by this coding system.\n\
413 A default value is `compound-text'");
414 Vselection_coding_system=intern ("iso-latin-1-dos");
416 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
417 "Coding system for the next communication with other X clients.\n\
418 Usually, `selection-coding-system' is used for communicating with\n\
419 other X clients. But, if this variable is set, it is used for the\n\
420 next communication only. After the communication, this variable is\n\
421 set to nil.");
422 Vnext_selection_coding_system = Qnil;
424 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);