*** empty log message ***
[bpt/emacs.git] / src / w32select.c
CommitLineData
e9e23e23 1/* Selection processing for Emacs on the Microsoft W32 API.
ee78dc32
GV
2 Copyright (C) 1993, 1994 Free Software Foundation.
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
GV
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"
bbb059f3
AI
29#include "buffer.h"
30#include "charset.h"
31#include "coding.h"
ee78dc32 32
9aa94bd5
KH
33Lisp_Object QCLIPBOARD;
34
bbb059f3
AI
35/* Coding system for communicating with other Windows programs via the
36 clipboard. */
72aca5fa 37static Lisp_Object Vselection_coding_system;
bbb059f3 38
93cbf229
GV
39/* Coding system for the next communicating with other X clients. */
40static Lisp_Object Vnext_selection_coding_system;
41
ee78dc32 42#if 0
fbd6baed 43DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0,
ee78dc32
GV
44 "This opens the clipboard with the given frame pointer.")
45 (frame)
46 Lisp_Object frame;
47{
48 BOOL ok = FALSE;
49
50 if (!NILP (frame))
51 CHECK_LIVE_FRAME (frame, 0);
52
53 BLOCK_INPUT;
54
fbd6baed 55 ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL);
ee78dc32
GV
56
57 UNBLOCK_INPUT;
58
59 return (ok ? frame : Qnil);
60}
61
fbd6baed 62DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard, Sw32_empty_clipboard, 0, 0, 0,
ee78dc32
GV
63 "This empties the clipboard and assigns ownership to the window which opened the clipboard.")
64 ()
65{
66 BOOL ok = FALSE;
67
68 BLOCK_INPUT;
69
70 ok = EmptyClipboard ();
71
72 UNBLOCK_INPUT;
73
74 return (ok ? Qt : Qnil);
75}
76
fbd6baed 77DEFUN ("w32-close-clipboard", Fw32_close_clipboard, Sw32_close_clipboard, 0, 0, 0,
ee78dc32
GV
78 "This closes the clipboard.")
79 ()
80{
81 BOOL ok = FALSE;
82
83 BLOCK_INPUT;
84
85 ok = CloseClipboard ();
86
87 UNBLOCK_INPUT;
88
89 return (ok ? Qt : Qnil);
90}
91
92#endif
93
fbd6baed 94DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, Sw32_set_clipboard_data, 1, 2, 0,
ee78dc32
GV
95 "This sets the clipboard data to the given text.")
96 (string, frame)
97 Lisp_Object string, frame;
98{
99 BOOL ok = TRUE;
100 HANDLE htext;
69cddef0 101 int nbytes;
0ece9ef6 102 int truelen, nlines = 0;
69cddef0
GV
103 unsigned char *src;
104 unsigned char *dst;
0ece9ef6 105
ee78dc32
GV
106 CHECK_STRING (string, 0);
107
108 if (!NILP (frame))
109 CHECK_LIVE_FRAME (frame, 0);
110
111 BLOCK_INPUT;
69cddef0 112
bbb059f3 113 nbytes = STRING_BYTES (XSTRING (string)) + 1;
69cddef0 114 src = XSTRING (string)->data;
0ece9ef6
AI
115 dst = src;
116
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)
121 {
122 nlines++;
123 dst++;
124 }
69cddef0 125
bbb059f3
AI
126 {
127 /* Since we are now handling multilingual text, we must consider
128 encoding text for the clipboard. */
69ebbf81
KH
129 int charset_info = find_charset_in_text (src, XSTRING (string)->size,
130 nbytes, NULL, QNil);
bbb059f3 131
69ebbf81 132 if (charset_info == 0)
bbb059f3
AI
133 {
134 /* No multibyte character in OBJ. We need not encode it. */
69cddef0 135
c0ca703b 136 /* Need to know final size after CR chars are inserted (the
bbb059f3 137 standard CF_TEXT clipboard format uses CRLF line endings,
c0ca703b 138 while Emacs uses just LF internally). */
69cddef0 139
0ece9ef6 140 truelen = nbytes + nlines;
69cddef0 141
bbb059f3
AI
142 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
143 goto error;
144
145 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
146 goto error;
ee78dc32 147
bbb059f3
AI
148 /* convert to CRLF line endings expected by clipboard */
149 while (1)
150 {
151 unsigned char *next;
152 /* copy next line or remaining bytes including '\0' */
153 next = _memccpy (dst, src, '\n', nbytes);
154 if (next)
155 {
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;
164 }
165 else
166 /* copied remaining partial line -> now finished */
167 break;
168 }
ee78dc32 169
bbb059f3 170 GlobalUnlock (htext);
0108f679
AI
171
172 Vlast_coding_system_used = Qraw_text;
bbb059f3
AI
173 }
174 else
175 {
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;
183
93cbf229
GV
184 if (NILP (Vnext_selection_coding_system))
185 Vnext_selection_coding_system = Vselection_coding_system;
bbb059f3 186 setup_coding_system
93cbf229 187 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
69ebbf81
KH
188 coding.src_multibyte = 1;
189 coding.dst_multibyte = 0;
93cbf229 190 Vnext_selection_coding_system = Qnil;
bbb059f3 191 coding.mode |= CODING_MODE_LAST_BLOCK;
43df7d0b 192 bufsize = encoding_buffer_size (&coding, nbytes);
bbb059f3
AI
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);
0108f679 198 Vlast_coding_system_used = coding.symbol;
bbb059f3
AI
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;
203 }
204 }
ee78dc32 205
fbd6baed 206 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
ee78dc32
GV
207 goto error;
208
209 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
210
211 CloseClipboard ();
212
213 if (ok) goto done;
214
215 error:
216
217 ok = FALSE;
218 if (htext) GlobalFree (htext);
219
220 done:
221 UNBLOCK_INPUT;
222
223 return (ok ? string : Qnil);
224}
225
fbd6baed 226DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, Sw32_get_clipboard_data, 0, 1, 0,
ee78dc32
GV
227 "This gets the clipboard data in text format.")
228 (frame)
229 Lisp_Object frame;
230{
231 HANDLE htext;
232 Lisp_Object ret = Qnil;
233
234 if (!NILP (frame))
235 CHECK_LIVE_FRAME (frame, 0);
236
237 BLOCK_INPUT;
238
fbd6baed 239 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
ee78dc32
GV
240 goto done;
241
242 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
243 goto closeclip;
244
ee78dc32 245 {
69cddef0
GV
246 unsigned char *src;
247 unsigned char *dst;
ee78dc32 248 int nbytes;
69cddef0 249 int truelen;
c0ca703b 250 int require_decoding = 0;
ee78dc32 251
69cddef0 252 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
ee78dc32
GV
253 goto closeclip;
254
69cddef0
GV
255 nbytes = strlen (src);
256
93cbf229
GV
257 if (
258#if 1
259 1
260#else
261 ! NILP (buffer_defaults.enable_multibyte_characters)
262#endif
263 )
264 {
c0ca703b 265 /* If the clipboard data contains any non-ascii code, we
93cbf229
GV
266 need to decode it. */
267 int i;
268
269 for (i = 0; i < nbytes; i++)
270 {
271 if (src[i] >= 0x80)
272 {
c0ca703b 273 require_decoding = 1;
93cbf229
GV
274 break;
275 }
276 }
277 }
278
c0ca703b 279 if (require_decoding)
69cddef0 280 {
bbb059f3
AI
281 int bufsize;
282 unsigned char *buf;
283 struct coding_system coding;
284
93cbf229
GV
285 if (NILP (Vnext_selection_coding_system))
286 Vnext_selection_coding_system = Vselection_coding_system;
bbb059f3 287 setup_coding_system
93cbf229 288 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
69ebbf81
KH
289 coding.src_multibyte = 0;
290 coding.dst_multibyte = 1;
93cbf229 291 Vnext_selection_coding_system = Qnil;
bbb059f3
AI
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);
0108f679 296 Vlast_coding_system_used = coding.symbol;
69ebbf81
KH
297 ret = make_string_from_bytes ((char *) buf,
298 coding.produced_char, coding.produced);
bbb059f3 299 xfree (buf);
69cddef0 300 }
bbb059f3
AI
301 else
302 {
c0ca703b
GV
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. */
bbb059f3
AI
307
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)
312 {
c0ca703b
GV
313 if (dst[1] == '\n') /* safe because of trailing '\0' */
314 truelen--;
bbb059f3
AI
315 dst++;
316 }
69cddef0 317
bbb059f3 318 ret = make_uninit_string (truelen);
69cddef0 319
c0ca703b
GV
320 /* Convert CRLF line endings (the standard CF_TEXT clipboard
321 format) to LF endings as used internally by Emacs. */
69cddef0 322
bbb059f3
AI
323 dst = XSTRING (ret)->data;
324 while (1)
69cddef0 325 {
bbb059f3
AI
326 unsigned char *next;
327 /* copy next line or remaining bytes excluding '\0' */
328 next = _memccpy (dst, src, '\r', nbytes);
329 if (next)
330 {
331 /* copied one line ending with '\r' */
332 int copied = next - dst;
333 nbytes -= copied;
c0ca703b 334 dst += copied;
bbb059f3 335 src += copied;
c0ca703b
GV
336 if (*src == '\n')
337 dst--; /* overwrite '\r' with '\n' */
338 }
bbb059f3
AI
339 else
340 /* copied remaining partial line -> now finished */
341 break;
342 }
0108f679
AI
343
344 Vlast_coding_system_used = Qraw_text;
69cddef0
GV
345 }
346
ee78dc32
GV
347 GlobalUnlock (htext);
348 }
349
350 closeclip:
351 CloseClipboard ();
352
353 done:
354 UNBLOCK_INPUT;
355
356 return (ret);
357}
358
9aa94bd5
KH
359/* Support checking for a clipboard selection. */
360
361DEFUN ("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\
364The arg should be the name of the selection in question, typically one of\n\
365the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
366\(Those are literal upper-case symbol names, since that's what X expects.)\n\
367For convenience, the symbol nil is the same as `PRIMARY',\n\
368and t is the same as `SECONDARY'.")
369 (selection)
370 Lisp_Object selection;
371{
372 CHECK_SYMBOL (selection, 0);
373
374 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
375 if the clipboard currently has valid text format contents. */
376
377 if (EQ (selection, QCLIPBOARD))
378 {
379 Lisp_Object val = Qnil;
380
381 if (OpenClipboard (NULL))
382 {
383 int format = 0;
384 while (format = EnumClipboardFormats (format))
385 if (format == CF_TEXT)
386 {
387 val = Qt;
388 break;
389 }
390 CloseClipboard ();
391 }
392 return val;
393 }
394 return Qnil;
395}
396
ee78dc32 397void
fbd6baed 398syms_of_w32select ()
ee78dc32
GV
399{
400#if 0
fbd6baed
GV
401 defsubr (&Sw32_open_clipboard);
402 defsubr (&Sw32_empty_clipboard);
403 defsubr (&Sw32_close_clipboard);
ee78dc32 404#endif
fbd6baed
GV
405 defsubr (&Sw32_set_clipboard_data);
406 defsubr (&Sw32_get_clipboard_data);
9aa94bd5
KH
407 defsubr (&Sx_selection_exists_p);
408
72aca5fa 409 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
bbb059f3
AI
410 "Coding system for communicating with other X clients.\n\
411When sending or receiving text via cut_buffer, selection, and clipboard,\n\
412the text is encoded or decoded by this coding system.\n\
413A default value is `compound-text'");
72aca5fa 414 Vselection_coding_system=intern ("iso-latin-1-dos");
bbb059f3 415
93cbf229
GV
416 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
417 "Coding system for the next communication with other X clients.\n\
418Usually, `selection-coding-system' is used for communicating with\n\
419other X clients. But, if this variable is set, it is used for the\n\
420next communication only. After the communication, this variable is\n\
421set to nil.");
422 Vnext_selection_coding_system = Qnil;
423
9aa94bd5 424 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
ee78dc32 425}