(special-display-p, same-window-p): Add missing
[bpt/emacs.git] / src / w32select.c
CommitLineData
ee78dc32
GV
1/* Win32 Selection processing for emacs
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"
25#include "w32term.h" /* for all of the win32 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
9aa94bd5
KH
30Lisp_Object QCLIPBOARD;
31
ee78dc32
GV
32#if 0
33DEFUN ("win32-open-clipboard", Fwin32_open_clipboard, Swin32_open_clipboard, 0, 1, 0,
34 "This opens the clipboard with the given frame pointer.")
35 (frame)
36 Lisp_Object frame;
37{
38 BOOL ok = FALSE;
39
40 if (!NILP (frame))
41 CHECK_LIVE_FRAME (frame, 0);
42
43 BLOCK_INPUT;
44
45 ok = OpenClipboard ((!NILP (frame) && FRAME_WIN32_P (XFRAME (frame))) ? FRAME_WIN32_WINDOW (XFRAME (frame)) : NULL);
46
47 UNBLOCK_INPUT;
48
49 return (ok ? frame : Qnil);
50}
51
52DEFUN ("win32-empty-clipboard", Fwin32_empty_clipboard, Swin32_empty_clipboard, 0, 0, 0,
53 "This empties the clipboard and assigns ownership to the window which opened the clipboard.")
54 ()
55{
56 BOOL ok = FALSE;
57
58 BLOCK_INPUT;
59
60 ok = EmptyClipboard ();
61
62 UNBLOCK_INPUT;
63
64 return (ok ? Qt : Qnil);
65}
66
67DEFUN ("win32-close-clipboard", Fwin32_close_clipboard, Swin32_close_clipboard, 0, 0, 0,
68 "This closes the clipboard.")
69 ()
70{
71 BOOL ok = FALSE;
72
73 BLOCK_INPUT;
74
75 ok = CloseClipboard ();
76
77 UNBLOCK_INPUT;
78
79 return (ok ? Qt : Qnil);
80}
81
82#endif
83
84DEFUN ("win32-set-clipboard-data", Fwin32_set_clipboard_data, Swin32_set_clipboard_data, 1, 2, 0,
85 "This sets the clipboard data to the given text.")
86 (string, frame)
87 Lisp_Object string, frame;
88{
89 BOOL ok = TRUE;
90 HANDLE htext;
69cddef0
GV
91 int nbytes;
92 int truelen;
93 unsigned char *src;
94 unsigned char *dst;
ee78dc32
GV
95
96 CHECK_STRING (string, 0);
97
98 if (!NILP (frame))
99 CHECK_LIVE_FRAME (frame, 0);
100
101 BLOCK_INPUT;
69cddef0
GV
102
103 nbytes = XSTRING (string)->size + 1;
104 src = XSTRING (string)->data;
105
106 /* need to know final size after '\r' chars are inserted (the
107 standard CF_TEXT clipboard format uses CRLF line endings,
108 while Emacs uses just LF internally) */
109
110 truelen = nbytes;
111 dst = src;
112 /* avoid using strchr because it recomputes the length everytime */
113 while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
114 {
115 truelen++;
116 dst++;
117 }
118
119 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
120 goto error;
121
122 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
ee78dc32 123 goto error;
ee78dc32 124
69cddef0
GV
125 /* convert to CRLF line endings expected by clipboard */
126 while (1)
ee78dc32 127 {
69cddef0
GV
128 unsigned char *next;
129 /* copy next line or remaining bytes including '\0' */
130 next = _memccpy (dst, src, '\n', nbytes);
131 if (next)
ee78dc32 132 {
69cddef0
GV
133 /* copied one line ending with '\n' */
134 int copied = next - dst;
135 nbytes -= copied;
136 src += copied;
137 /* insert '\r' before '\n' */
138 next[-1] = '\r';
139 next[0] = '\n';
140 dst = next + 1;
141 }
142 else
143 /* copied remaining partial line -> now finished */
144 break;
ee78dc32
GV
145 }
146
69cddef0 147 GlobalUnlock (htext);
ee78dc32
GV
148
149 if (!OpenClipboard ((!NILP (frame) && FRAME_WIN32_P (XFRAME (frame))) ? FRAME_WIN32_WINDOW (XFRAME (frame)) : NULL))
150 goto error;
151
152 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
153
154 CloseClipboard ();
155
156 if (ok) goto done;
157
158 error:
159
160 ok = FALSE;
161 if (htext) GlobalFree (htext);
162
163 done:
164 UNBLOCK_INPUT;
165
166 return (ok ? string : Qnil);
167}
168
169DEFUN ("win32-get-clipboard-data", Fwin32_get_clipboard_data, Swin32_get_clipboard_data, 0, 1, 0,
170 "This gets the clipboard data in text format.")
171 (frame)
172 Lisp_Object frame;
173{
174 HANDLE htext;
175 Lisp_Object ret = Qnil;
176
177 if (!NILP (frame))
178 CHECK_LIVE_FRAME (frame, 0);
179
180 BLOCK_INPUT;
181
182 if (!OpenClipboard ((!NILP (frame) && FRAME_WIN32_P (XFRAME (frame))) ? FRAME_WIN32_WINDOW (XFRAME (frame)) : NULL))
183 goto done;
184
185 if ((htext = GetClipboardData (CF_TEXT)) == NULL)
186 goto closeclip;
187
ee78dc32 188 {
69cddef0
GV
189 unsigned char *src;
190 unsigned char *dst;
ee78dc32 191 int nbytes;
69cddef0 192 int truelen;
ee78dc32 193
69cddef0 194 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
ee78dc32
GV
195 goto closeclip;
196
69cddef0
GV
197 nbytes = strlen (src);
198
199 /* need to know final size after '\r' chars are removed because
200 we can't change the string size manually, and doing an extra
201 copy is silly */
202
203 truelen = nbytes;
204 dst = src;
205 /* avoid using strchr because it recomputes the length everytime */
206 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
207 {
208 truelen--;
209 dst++;
210 }
211
212 ret = make_uninit_string (truelen);
213
214 /* convert CRLF line endings (the standard CF_TEXT clipboard
215 format) to LF endings as used internally by Emacs */
216
217 dst = XSTRING (ret)->data;
218 while (1)
219 {
220 unsigned char *next;
221 /* copy next line or remaining bytes excluding '\0' */
222 next = _memccpy (dst, src, '\r', nbytes);
223 if (next)
224 {
225 /* copied one line ending with '\r' */
226 int copied = next - dst;
227 nbytes -= copied;
228 dst += copied - 1; /* overwrite '\r' */
229 src += copied;
230 }
231 else
232 /* copied remaining partial line -> now finished */
233 break;
234 }
235
ee78dc32
GV
236 GlobalUnlock (htext);
237 }
238
239 closeclip:
240 CloseClipboard ();
241
242 done:
243 UNBLOCK_INPUT;
244
245 return (ret);
246}
247
9aa94bd5
KH
248/* Support checking for a clipboard selection. */
249
250DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
251 0, 1, 0,
252 "Whether there is an owner for the given X Selection.\n\
253The arg should be the name of the selection in question, typically one of\n\
254the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
255\(Those are literal upper-case symbol names, since that's what X expects.)\n\
256For convenience, the symbol nil is the same as `PRIMARY',\n\
257and t is the same as `SECONDARY'.")
258 (selection)
259 Lisp_Object selection;
260{
261 CHECK_SYMBOL (selection, 0);
262
263 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
264 if the clipboard currently has valid text format contents. */
265
266 if (EQ (selection, QCLIPBOARD))
267 {
268 Lisp_Object val = Qnil;
269
270 if (OpenClipboard (NULL))
271 {
272 int format = 0;
273 while (format = EnumClipboardFormats (format))
274 if (format == CF_TEXT)
275 {
276 val = Qt;
277 break;
278 }
279 CloseClipboard ();
280 }
281 return val;
282 }
283 return Qnil;
284}
285
ee78dc32
GV
286void
287syms_of_win32select ()
288{
289#if 0
290 defsubr (&Swin32_open_clipboard);
291 defsubr (&Swin32_empty_clipboard);
292 defsubr (&Swin32_close_clipboard);
293#endif
294 defsubr (&Swin32_set_clipboard_data);
295 defsubr (&Swin32_get_clipboard_data);
9aa94bd5
KH
296 defsubr (&Sx_selection_exists_p);
297
298 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
ee78dc32 299}