(w32_get_string_resource): Check for name in current
[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. */
129 int charsets[MAX_CHARSET + 1];
130 int num;
131
132 bzero (charsets, (MAX_CHARSET + 1) * sizeof (int));
93cbf229
GV
133 num = ((nbytes <= 1 /* Check the possibility of short cut. */
134 || !STRING_MULTIBYTE (string)
135 || nbytes == XSTRING (string)->size)
bbb059f3 136 ? 0
2798f181 137 : find_charset_in_str (src, nbytes, charsets, Qnil, 0, 1));
bbb059f3
AI
138
139 if (!num || (num == 1 && charsets[CHARSET_ASCII]))
140 {
141 /* No multibyte character in OBJ. We need not encode it. */
69cddef0 142
c0ca703b 143 /* Need to know final size after CR chars are inserted (the
bbb059f3 144 standard CF_TEXT clipboard format uses CRLF line endings,
c0ca703b 145 while Emacs uses just LF internally). */
69cddef0 146
0ece9ef6 147 truelen = nbytes + nlines;
69cddef0 148
bbb059f3
AI
149 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
150 goto error;
151
152 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
153 goto error;
ee78dc32 154
bbb059f3
AI
155 /* convert to CRLF line endings expected by clipboard */
156 while (1)
157 {
158 unsigned char *next;
159 /* copy next line or remaining bytes including '\0' */
160 next = _memccpy (dst, src, '\n', nbytes);
161 if (next)
162 {
163 /* copied one line ending with '\n' */
164 int copied = next - dst;
165 nbytes -= copied;
166 src += copied;
167 /* insert '\r' before '\n' */
168 next[-1] = '\r';
169 next[0] = '\n';
170 dst = next + 1;
171 }
172 else
173 /* copied remaining partial line -> now finished */
174 break;
175 }
ee78dc32 176
bbb059f3 177 GlobalUnlock (htext);
0108f679
AI
178
179 Vlast_coding_system_used = Qraw_text;
bbb059f3
AI
180 }
181 else
182 {
183 /* We must encode contents of OBJ to compound text format.
184 The format is compatible with what the target `STRING'
185 expects if OBJ contains only ASCII and Latin-1
186 characters. */
187 int bufsize;
188 struct coding_system coding;
189 HANDLE htext2;
190
93cbf229
GV
191 if (NILP (Vnext_selection_coding_system))
192 Vnext_selection_coding_system = Vselection_coding_system;
bbb059f3 193 setup_coding_system
93cbf229
GV
194 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
195 Vnext_selection_coding_system = Qnil;
bbb059f3 196 coding.mode |= CODING_MODE_LAST_BLOCK;
0ece9ef6 197 bufsize = encoding_buffer_size (&coding, nbytes) + nlines;
bbb059f3
AI
198 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL)
199 goto error;
200 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
201 goto error;
202 encode_coding (&coding, src, dst, nbytes, bufsize);
0108f679 203 Vlast_coding_system_used = coding.symbol;
bbb059f3
AI
204 GlobalUnlock (htext);
205 /* Shrink data block to actual size. */
206 htext2 = GlobalReAlloc (htext, coding.produced, GMEM_MOVEABLE | GMEM_DDESHARE);
207 if (htext2 != NULL) htext = htext2;
208 }
209 }
ee78dc32 210
fbd6baed 211 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
ee78dc32
GV
212 goto error;
213
214 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
215
216 CloseClipboard ();
217
218 if (ok) goto done;
219
220 error:
221
222 ok = FALSE;
223 if (htext) GlobalFree (htext);
224
225 done:
226 UNBLOCK_INPUT;
227
228 return (ok ? string : Qnil);
229}
230
fbd6baed 231DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, Sw32_get_clipboard_data, 0, 1, 0,
ee78dc32
GV
232 "This gets the clipboard data in text format.")
233 (frame)
234 Lisp_Object frame;
235{
236 HANDLE htext;
237 Lisp_Object ret = Qnil;
238
239 if (!NILP (frame))
240 CHECK_LIVE_FRAME (frame, 0);
241
242 BLOCK_INPUT;
243
fbd6baed 244 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
ee78dc32
GV
245 goto done;
246
247 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
248 goto closeclip;
249
ee78dc32 250 {
69cddef0
GV
251 unsigned char *src;
252 unsigned char *dst;
ee78dc32 253 int nbytes;
69cddef0 254 int truelen;
c0ca703b 255 int require_decoding = 0;
ee78dc32 256
69cddef0 257 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
ee78dc32
GV
258 goto closeclip;
259
69cddef0
GV
260 nbytes = strlen (src);
261
93cbf229
GV
262 if (
263#if 1
264 1
265#else
266 ! NILP (buffer_defaults.enable_multibyte_characters)
267#endif
268 )
269 {
c0ca703b 270 /* If the clipboard data contains any non-ascii code, we
93cbf229
GV
271 need to decode it. */
272 int i;
273
274 for (i = 0; i < nbytes; i++)
275 {
276 if (src[i] >= 0x80)
277 {
c0ca703b 278 require_decoding = 1;
93cbf229
GV
279 break;
280 }
281 }
282 }
283
c0ca703b 284 if (require_decoding)
69cddef0 285 {
bbb059f3
AI
286 int bufsize;
287 unsigned char *buf;
288 struct coding_system coding;
289
93cbf229
GV
290 if (NILP (Vnext_selection_coding_system))
291 Vnext_selection_coding_system = Vselection_coding_system;
bbb059f3 292 setup_coding_system
93cbf229
GV
293 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
294 Vnext_selection_coding_system = Qnil;
bbb059f3
AI
295 coding.mode |= CODING_MODE_LAST_BLOCK;
296 bufsize = decoding_buffer_size (&coding, nbytes);
297 buf = (unsigned char *) xmalloc (bufsize);
298 decode_coding (&coding, src, buf, nbytes, bufsize);
0108f679 299 Vlast_coding_system_used = coding.symbol;
bbb059f3
AI
300 truelen = (coding.fake_multibyte
301 ? multibyte_chars_in_text (buf, coding.produced)
302 : coding.produced_char);
303 ret = make_string_from_bytes ((char *) buf, truelen, coding.produced);
304 xfree (buf);
69cddef0 305 }
bbb059f3
AI
306 else
307 {
c0ca703b
GV
308 /* Need to know final size after CR chars are removed because we
309 can't change the string size manually, and doing an extra
310 copy is silly. Note that we only remove CR when it appears
311 as part of CRLF. */
bbb059f3
AI
312
313 truelen = nbytes;
314 dst = src;
315 /* avoid using strchr because it recomputes the length everytime */
316 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
317 {
c0ca703b
GV
318 if (dst[1] == '\n') /* safe because of trailing '\0' */
319 truelen--;
bbb059f3
AI
320 dst++;
321 }
69cddef0 322
bbb059f3 323 ret = make_uninit_string (truelen);
69cddef0 324
c0ca703b
GV
325 /* Convert CRLF line endings (the standard CF_TEXT clipboard
326 format) to LF endings as used internally by Emacs. */
69cddef0 327
bbb059f3
AI
328 dst = XSTRING (ret)->data;
329 while (1)
69cddef0 330 {
bbb059f3
AI
331 unsigned char *next;
332 /* copy next line or remaining bytes excluding '\0' */
333 next = _memccpy (dst, src, '\r', nbytes);
334 if (next)
335 {
336 /* copied one line ending with '\r' */
337 int copied = next - dst;
338 nbytes -= copied;
c0ca703b 339 dst += copied;
bbb059f3 340 src += copied;
c0ca703b
GV
341 if (*src == '\n')
342 dst--; /* overwrite '\r' with '\n' */
343 }
bbb059f3
AI
344 else
345 /* copied remaining partial line -> now finished */
346 break;
347 }
0108f679
AI
348
349 Vlast_coding_system_used = Qraw_text;
69cddef0
GV
350 }
351
ee78dc32
GV
352 GlobalUnlock (htext);
353 }
354
355 closeclip:
356 CloseClipboard ();
357
358 done:
359 UNBLOCK_INPUT;
360
361 return (ret);
362}
363
9aa94bd5
KH
364/* Support checking for a clipboard selection. */
365
366DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
367 0, 1, 0,
368 "Whether there is an owner for the given X Selection.\n\
369The arg should be the name of the selection in question, typically one of\n\
370the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
371\(Those are literal upper-case symbol names, since that's what X expects.)\n\
372For convenience, the symbol nil is the same as `PRIMARY',\n\
373and t is the same as `SECONDARY'.")
374 (selection)
375 Lisp_Object selection;
376{
377 CHECK_SYMBOL (selection, 0);
378
379 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
380 if the clipboard currently has valid text format contents. */
381
382 if (EQ (selection, QCLIPBOARD))
383 {
384 Lisp_Object val = Qnil;
385
386 if (OpenClipboard (NULL))
387 {
388 int format = 0;
389 while (format = EnumClipboardFormats (format))
390 if (format == CF_TEXT)
391 {
392 val = Qt;
393 break;
394 }
395 CloseClipboard ();
396 }
397 return val;
398 }
399 return Qnil;
400}
401
ee78dc32 402void
fbd6baed 403syms_of_w32select ()
ee78dc32
GV
404{
405#if 0
fbd6baed
GV
406 defsubr (&Sw32_open_clipboard);
407 defsubr (&Sw32_empty_clipboard);
408 defsubr (&Sw32_close_clipboard);
ee78dc32 409#endif
fbd6baed
GV
410 defsubr (&Sw32_set_clipboard_data);
411 defsubr (&Sw32_get_clipboard_data);
9aa94bd5
KH
412 defsubr (&Sx_selection_exists_p);
413
72aca5fa 414 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
bbb059f3
AI
415 "Coding system for communicating with other X clients.\n\
416When sending or receiving text via cut_buffer, selection, and clipboard,\n\
417the text is encoded or decoded by this coding system.\n\
418A default value is `compound-text'");
72aca5fa 419 Vselection_coding_system=intern ("iso-latin-1-dos");
bbb059f3 420
93cbf229
GV
421 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
422 "Coding system for the next communication with other X clients.\n\
423Usually, `selection-coding-system' is used for communicating with\n\
424other X clients. But, if this variable is set, it is used for the\n\
425next communication only. After the communication, this variable is\n\
426set to nil.");
427 Vnext_selection_coding_system = Qnil;
428
9aa94bd5 429 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
ee78dc32 430}