Mercurial > hg > xemacs-beta
comparison src/select-msw.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | a5df635868b2 |
children | e7ef97881643 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
22 | 22 |
23 /* Authorship: | 23 /* Authorship: |
24 | 24 |
25 Written by Kevin Gallo for FSF Emacs. | 25 Written by Kevin Gallo for FSF Emacs. |
26 Rewritten for mswindows by Jonathan Harris, December 1997 for 21.0. | 26 Rewritten for mswindows by Jonathan Harris, December 1997 for 21.0. |
27 */ | 27 Hacked by Alastair Houghton, July 2000 for enhanced clipboard support. |
28 | 28 */ |
29 | 29 |
30 #include <config.h> | 30 #include <config.h> |
31 #include "lisp.h" | 31 #include "lisp.h" |
32 #include "frame.h" | 32 #include "frame.h" |
33 #include "select.h" | 33 #include "select.h" |
34 #include "opaque.h" | |
35 #include "file-coding.h" | |
36 #include "buffer.h" | |
34 | 37 |
35 #include "console-msw.h" | 38 #include "console-msw.h" |
36 | 39 |
37 DEFUN ("mswindows-set-clipboard", Fmswindows_set_clipboard, 1, 1, 0, /* | 40 /* A list of handles that we must release. Not accessible from Lisp. */ |
38 Copy STRING to the mswindows clipboard. | 41 static Lisp_Object Vhandle_alist; |
42 | |
43 /* Test if this is an X symbol that we understand */ | |
44 static int | |
45 x_sym_p (Lisp_Object value) | |
46 { | |
47 if (NILP (value) || INTP (value)) | |
48 return 0; | |
49 | |
50 /* Check for some of the X symbols */ | |
51 if (EQ (value, QSTRING)) return 1; | |
52 if (EQ (value, QTEXT)) return 1; | |
53 if (EQ (value, QCOMPOUND_TEXT)) return 1; | |
54 | |
55 return 0; | |
56 } | |
57 | |
58 /* This converts a Lisp symbol to an MS-Windows clipboard format. | |
59 We have symbols for all predefined clipboard formats, but that | |
60 doesn't mean we support them all ;-) | |
61 The name of this function is actually a lie - it also knows about | |
62 integers and strings... */ | |
63 static UINT | |
64 symbol_to_ms_cf (Lisp_Object value) | |
65 { | |
66 /* If it's NIL, we're in trouble. */ | |
67 if (NILP (value)) return 0; | |
68 | |
69 /* If it's an integer, assume it's a format ID */ | |
70 if (INTP (value)) return (UINT) (XINT (value)); | |
71 | |
72 /* If it's a string, register the format(!) */ | |
73 if (STRINGP (value)) | |
74 return RegisterClipboardFormat (XSTRING_DATA (value)); | |
75 | |
76 /* Check for Windows clipboard format symbols */ | |
77 if (EQ (value, QCF_TEXT)) return CF_TEXT; | |
78 if (EQ (value, QCF_BITMAP)) return CF_BITMAP; | |
79 if (EQ (value, QCF_METAFILEPICT)) return CF_METAFILEPICT; | |
80 if (EQ (value, QCF_SYLK)) return CF_SYLK; | |
81 if (EQ (value, QCF_DIF)) return CF_DIF; | |
82 if (EQ (value, QCF_TIFF)) return CF_TIFF; | |
83 if (EQ (value, QCF_OEMTEXT)) return CF_OEMTEXT; | |
84 if (EQ (value, QCF_DIB)) return CF_DIB; | |
85 #ifdef CF_DIBV5 | |
86 if (EQ (value, QCF_DIBV5)) return CF_DIBV5; | |
87 #endif | |
88 if (EQ (value, QCF_PALETTE)) return CF_PALETTE; | |
89 if (EQ (value, QCF_PENDATA)) return CF_PENDATA; | |
90 if (EQ (value, QCF_RIFF)) return CF_RIFF; | |
91 if (EQ (value, QCF_WAVE)) return CF_WAVE; | |
92 if (EQ (value, QCF_UNICODETEXT)) return CF_UNICODETEXT; | |
93 if (EQ (value, QCF_ENHMETAFILE)) return CF_ENHMETAFILE; | |
94 if (EQ (value, QCF_HDROP)) return CF_HDROP; | |
95 if (EQ (value, QCF_LOCALE)) return CF_LOCALE; | |
96 if (EQ (value, QCF_OWNERDISPLAY)) return CF_OWNERDISPLAY; | |
97 if (EQ (value, QCF_DSPTEXT)) return CF_DSPTEXT; | |
98 if (EQ (value, QCF_DSPBITMAP)) return CF_DSPBITMAP; | |
99 if (EQ (value, QCF_DSPMETAFILEPICT)) return CF_DSPMETAFILEPICT; | |
100 if (EQ (value, QCF_DSPENHMETAFILE)) return CF_DSPENHMETAFILE; | |
101 | |
102 return 0; | |
103 } | |
104 | |
105 /* This converts an MS-Windows clipboard format to its corresponding | |
106 Lisp symbol, or a Lisp integer otherwise. */ | |
107 static Lisp_Object | |
108 ms_cf_to_symbol (UINT format) | |
109 { | |
110 switch (format) | |
111 { | |
112 case CF_TEXT: return QCF_TEXT; | |
113 case CF_BITMAP: return QCF_BITMAP; | |
114 case CF_METAFILEPICT: return QCF_METAFILEPICT; | |
115 case CF_SYLK: return QCF_SYLK; | |
116 case CF_DIF: return QCF_DIF; | |
117 case CF_TIFF: return QCF_TIFF; | |
118 case CF_OEMTEXT: return QCF_OEMTEXT; | |
119 case CF_DIB: return QCF_DIB; | |
120 #ifdef CF_DIBV5 | |
121 case CF_DIBV5: return QCF_DIBV5; | |
122 #endif | |
123 case CF_PALETTE: return QCF_PALETTE; | |
124 case CF_PENDATA: return QCF_PENDATA; | |
125 case CF_RIFF: return QCF_RIFF; | |
126 case CF_WAVE: return QCF_WAVE; | |
127 case CF_UNICODETEXT: return QCF_UNICODETEXT; | |
128 case CF_ENHMETAFILE: return QCF_ENHMETAFILE; | |
129 case CF_HDROP: return QCF_HDROP; | |
130 case CF_LOCALE: return QCF_LOCALE; | |
131 case CF_OWNERDISPLAY: return QCF_OWNERDISPLAY; | |
132 case CF_DSPTEXT: return QCF_DSPTEXT; | |
133 case CF_DSPBITMAP: return QCF_DSPBITMAP; | |
134 case CF_DSPMETAFILEPICT: return QCF_DSPMETAFILEPICT; | |
135 case CF_DSPENHMETAFILE: return QCF_DSPENHMETAFILE; | |
136 default: return make_int ((int) format); | |
137 } | |
138 } | |
139 | |
140 /* Test if the specified clipboard format is auto-released by the OS. If | |
141 not, we must remember the handle on Vhandle_alist, and free it if | |
142 the clipboard is emptied or if we set data with the same format. */ | |
143 static int | |
144 cf_is_autofreed (UINT format) | |
145 { | |
146 switch (format) | |
147 { | |
148 /* This list comes from the SDK documentation */ | |
149 case CF_DSPENHMETAFILE: | |
150 case CF_DSPMETAFILEPICT: | |
151 case CF_ENHMETAFILE: | |
152 case CF_METAFILEPICT: | |
153 case CF_BITMAP: | |
154 case CF_DSPBITMAP: | |
155 case CF_PALETTE: | |
156 case CF_DIB: | |
157 #ifdef CF_DIBV5 | |
158 case CF_DIBV5: | |
159 #endif | |
160 case CF_DSPTEXT: | |
161 case CF_OEMTEXT: | |
162 case CF_TEXT: | |
163 case CF_UNICODETEXT: | |
164 return TRUE; | |
165 | |
166 default: | |
167 return FALSE; | |
168 } | |
169 } | |
170 | |
171 /* Do protocol to assert ourself as a selection owner. | |
172 | |
173 Under mswindows, we: | |
174 | |
175 * Only set the clipboard if (eq selection-name 'CLIPBOARD) | |
176 | |
177 * Check if an X atom name has been passed. If so, convert to CF_TEXT | |
178 (or CF_UNICODETEXT) remembering to perform LF -> CR-LF conversion. | |
179 | |
180 * Otherwise assume the data is formatted appropriately for the data type | |
181 that was passed. | |
182 | |
183 Then set the clipboard as necessary. | |
39 */ | 184 */ |
40 (string)) | 185 static Lisp_Object |
41 { | 186 mswindows_own_selection (Lisp_Object selection_name, |
42 int rawsize, size, i; | 187 Lisp_Object selection_value, |
43 unsigned char *src, *dst, *next; | 188 Lisp_Object how_to_add, |
44 HGLOBAL h = NULL; | 189 Lisp_Object selection_type) |
45 struct frame *f = NULL; | 190 { |
46 | 191 HGLOBAL hValue = NULL; |
47 CHECK_STRING (string); | 192 UINT cfType; |
48 | 193 int is_X_type = FALSE; |
49 /* Calculate size with LFs converted to CRLFs because | 194 Lisp_Object cfObject; |
50 * CF_TEXT format uses CRLF delimited ASCIIZ */ | 195 Lisp_Object data = Qnil; |
51 src = XSTRING_DATA (string); | 196 int size; |
52 size = rawsize = XSTRING_LENGTH (string) + 1; | 197 void *src, *dst; |
53 for (i=0; i<rawsize; i++) | 198 struct frame *f = NULL; |
54 if (src[i] == '\n') | 199 |
55 size++; | 200 /* Only continue if we're trying to set the clipboard - mswindows doesn't |
56 | 201 use the same selection model as X */ |
202 if (!EQ (selection_name, QCLIPBOARD)) | |
203 return Qnil; | |
204 | |
205 /* If this is one of the X-style atom name symbols, or NIL, convert it | |
206 as appropriate */ | |
207 if (NILP (selection_type) || x_sym_p (selection_type)) | |
208 { | |
209 /* Should COMPOUND_TEXT map to CF_UNICODETEXT? */ | |
210 cfType = CF_TEXT; | |
211 cfObject = QCF_TEXT; | |
212 is_X_type = TRUE; | |
213 } | |
214 else | |
215 { | |
216 cfType = symbol_to_ms_cf (selection_type); | |
217 | |
218 /* Only continue if we can figure out a clipboard type */ | |
219 if (!cfType) | |
220 return Qnil; | |
221 | |
222 cfObject = selection_type; | |
223 } | |
224 | |
225 /* Convert things appropriately */ | |
226 data = select_convert_out (selection_name, | |
227 cfObject, | |
228 selection_value); | |
229 | |
230 if (NILP (data)) | |
231 return Qnil; | |
232 | |
233 if (CONSP (data)) | |
234 { | |
235 if (!EQ (XCAR (data), cfObject)) | |
236 cfType = symbol_to_ms_cf (XCAR (data)); | |
237 | |
238 if (!cfType) | |
239 return Qnil; | |
240 | |
241 data = XCDR (data); | |
242 } | |
243 | |
244 /* We support opaque or string values, but we only mention string | |
245 values for now... */ | |
246 if (!OPAQUEP (data) | |
247 && !STRINGP (data)) | |
248 return Qnil; | |
249 | |
250 /* Compute the data length */ | |
251 if (OPAQUEP (data)) | |
252 size = XOPAQUE_SIZE (data); | |
253 else | |
254 size = XSTRING_LENGTH (data) + 1; | |
255 | |
256 /* Find the frame */ | |
57 f = selected_frame (); | 257 f = selected_frame (); |
258 | |
259 /* Open the clipboard */ | |
58 if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f))) | 260 if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f))) |
59 return Qnil; | 261 return Qnil; |
60 | 262 |
61 if (!EmptyClipboard () || | 263 /* Allocate memory */ |
62 (h = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, size)) == NULL || | 264 hValue = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, size); |
63 (dst = (unsigned char *) GlobalLock (h)) == NULL) | 265 |
64 { | 266 if (!hValue) |
65 if (h != NULL) GlobalFree (h); | 267 { |
66 CloseClipboard (); | 268 CloseClipboard (); |
269 | |
67 return Qnil; | 270 return Qnil; |
68 } | 271 } |
69 | 272 |
70 /* Convert LFs to CRLFs */ | 273 /* Copy the data */ |
71 do | 274 if (OPAQUEP (data)) |
72 { | 275 src = XOPAQUE_DATA (data); |
73 /* copy next line or remaining bytes including '\0' */ | 276 else |
74 next = memccpy (dst, src, '\n', rawsize); | 277 src = XSTRING_DATA (data); |
75 if (next) | 278 |
279 dst = GlobalLock (hValue); | |
280 | |
281 if (!dst) | |
282 { | |
283 GlobalFree (hValue); | |
284 CloseClipboard (); | |
285 | |
286 return Qnil; | |
287 } | |
288 | |
289 memcpy (dst, src, size); | |
290 | |
291 GlobalUnlock (hValue); | |
292 | |
293 /* Empty the clipboard if we're replacing everything */ | |
294 if (NILP (how_to_add) || EQ (how_to_add, Qreplace_all)) | |
295 { | |
296 if (!EmptyClipboard ()) | |
76 { | 297 { |
77 /* copied one line ending with '\n' */ | 298 CloseClipboard (); |
78 int copied = next - dst; | 299 GlobalFree (hValue); |
79 rawsize -= copied; | 300 |
80 src += copied; | 301 return Qnil; |
81 /* insert '\r' before '\n' */ | 302 } |
82 next[-1] = '\r'; | 303 } |
83 next[0] = '\n'; | 304 |
84 dst = next+1; | 305 /* Append is currently handled in select.el; perhaps this should change, |
85 } | 306 but it only really makes sense for ordinary text in any case... */ |
86 } | 307 |
87 while (next); | 308 SetClipboardData (cfType, hValue); |
88 | 309 |
89 GlobalUnlock (h); | 310 if (!cf_is_autofreed (cfType)) |
90 | 311 { |
91 i = (SetClipboardData (CF_TEXT, h) != NULL); | 312 Lisp_Object alist_elt = Qnil, rest; |
92 | 313 Lisp_Object cfType_int = make_int (cfType); |
314 | |
315 /* First check if there's an element in the alist for this type | |
316 already. */ | |
317 alist_elt = assq_no_quit (cfType_int, Vhandle_alist); | |
318 | |
319 /* Add an element to the alist */ | |
320 Vhandle_alist = Fcons (Fcons (cfType_int, make_opaque_ptr (hValue)), | |
321 Vhandle_alist); | |
322 | |
323 if (!NILP (alist_elt)) | |
324 { | |
325 /* Free the original handle */ | |
326 GlobalFree ((HGLOBAL) get_opaque_ptr (XCDR (alist_elt))); | |
327 | |
328 /* Remove the original one (adding first makes life easier, because | |
329 we don't have to special case this being the first element) */ | |
330 for (rest = Vhandle_alist; !NILP (rest); rest = Fcdr (rest)) | |
331 if (EQ (cfType_int, Fcar (XCDR (rest)))) | |
332 { | |
333 XCDR (rest) = Fcdr (XCDR (rest)); | |
334 break; | |
335 } | |
336 } | |
337 } | |
338 | |
93 CloseClipboard (); | 339 CloseClipboard (); |
94 | 340 |
95 return i ? Qt : Qnil; | 341 /* #### Should really return a time, though this is because of the |
96 } | 342 X model (by the looks of things) */ |
97 | 343 return Qnil; |
98 /* Do protocol to assert ourself as a selection owner. Under mswindows | 344 } |
99 this is easy, we just set the clipboard. */ | 345 |
100 static Lisp_Object | 346 static Lisp_Object |
101 mswindows_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) | 347 mswindows_available_selection_types (Lisp_Object selection_name) |
102 { | 348 { |
103 Lisp_Object converted_value = get_local_selection (selection_name, QSTRING); | 349 Lisp_Object types = Qnil; |
104 if (!NILP (converted_value) && | 350 UINT format = 0; |
105 CONSP (converted_value) && | 351 struct frame *f = NULL; |
106 EQ (XCAR (converted_value), QSTRING) && | 352 |
107 /* pure mswindows behaviour only says we can own the selection | 353 if (!EQ (selection_name, QCLIPBOARD)) |
108 if it is the clipboard */ | 354 return Qnil; |
109 EQ (selection_name, QCLIPBOARD)) | 355 |
110 Fmswindows_set_clipboard (XCDR (converted_value)); | 356 /* Find the frame */ |
357 f = selected_frame (); | |
358 | |
359 /* Open the clipboard */ | |
360 if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f))) | |
361 return Qnil; | |
362 | |
363 /* #### ajh - Should there be an unwind-protect handler around this? | |
364 It could (well it probably won't, but it's always better to | |
365 be safe) run out of memory and leave the clipboard open... */ | |
366 | |
367 while ((format = EnumClipboardFormats (format))) | |
368 types = Fcons (ms_cf_to_symbol (format), types); | |
369 | |
370 /* Close it */ | |
371 CloseClipboard (); | |
372 | |
373 return types; | |
374 } | |
375 | |
376 static Lisp_Object | |
377 mswindows_register_selection_data_type (Lisp_Object type_name) | |
378 { | |
379 /* Type already checked in select.c */ | |
380 const char *name = XSTRING_DATA (type_name); | |
381 UINT format; | |
382 | |
383 format = RegisterClipboardFormat (name); | |
384 | |
385 if (format) | |
386 return make_int ((int) format); | |
387 else | |
388 return Qnil; | |
389 } | |
390 | |
391 static Lisp_Object | |
392 mswindows_selection_data_type_name (Lisp_Object type_id) | |
393 { | |
394 UINT format; | |
395 int numchars; | |
396 char name_buf[128]; | |
397 | |
398 /* If it's an integer, convert to a symbol if appropriate */ | |
399 if (INTP (type_id)) | |
400 type_id = ms_cf_to_symbol (XINT (type_id)); | |
401 | |
402 /* If this is a symbol, return it */ | |
403 if (SYMBOLP (type_id)) | |
404 return type_id; | |
405 | |
406 /* Find the format code */ | |
407 format = symbol_to_ms_cf (type_id); | |
408 | |
409 if (!format) | |
410 return Qnil; | |
411 | |
412 /* Microsoft, stupid Microsoft */ | |
413 numchars = GetClipboardFormatName (format, name_buf, 128); | |
414 | |
415 if (numchars) | |
416 { | |
417 Lisp_Object name; | |
418 | |
419 /* Do this properly - though we could support UNICODE (UCS-2) if | |
420 MULE could hack it. */ | |
421 name = make_ext_string (name_buf, numchars, | |
422 Fget_coding_system (Qraw_text)); | |
423 | |
424 return name; | |
425 } | |
111 | 426 |
112 return Qnil; | 427 return Qnil; |
113 } | 428 } |
114 | 429 |
115 DEFUN ("mswindows-get-clipboard", Fmswindows_get_clipboard, 0, 0, 0, /* | 430 static Lisp_Object |
116 Return the contents of the mswindows clipboard. | 431 mswindows_get_foreign_selection (Lisp_Object selection_symbol, |
117 */ | 432 Lisp_Object target_type) |
118 ()) | 433 { |
119 { | 434 HGLOBAL hValue = NULL; |
120 HANDLE h; | 435 UINT cfType; |
121 unsigned char *src, *dst, *next; | 436 Lisp_Object cfObject = Qnil, ret = Qnil, value = Qnil; |
122 Lisp_Object ret = Qnil; | 437 int is_X_type = FALSE; |
123 | 438 int size; |
124 if (!OpenClipboard (NULL)) | 439 void *data; |
125 return Qnil; | 440 struct frame *f = NULL; |
126 | 441 struct gcpro gcpro1; |
127 if ((h = GetClipboardData (CF_TEXT)) != NULL && | 442 |
128 (src = (unsigned char *) GlobalLock (h)) != NULL) | 443 /* Only continue if we're trying to read the clipboard - mswindows doesn't |
129 { | 444 use the same selection model as X */ |
130 int i; | 445 if (!EQ (selection_symbol, QCLIPBOARD)) |
131 int size, rawsize; | 446 return Qnil; |
132 size = rawsize = strlen (src); | 447 |
133 | 448 /* If this is one of the X-style atom name symbols, or NIL, convert it |
134 for (i=0; i<rawsize; i++) | 449 as appropriate */ |
135 if (src[i] == '\r' && src[i+1] == '\n') | 450 if (NILP (target_type) || x_sym_p (target_type)) |
136 size--; | 451 { |
137 | 452 /* Should COMPOUND_TEXT map to CF_UNICODETEXT? */ |
138 /* Convert CRLFs to LFs */ | 453 cfType = CF_TEXT; |
139 ret = make_uninit_string (size); | 454 cfObject = QCF_TEXT; |
140 dst = XSTRING_DATA (ret); | 455 is_X_type = TRUE; |
141 do | 456 } |
142 { | 457 else |
143 /* copy next line or remaining bytes excluding '\0' */ | 458 { |
144 next = memccpy (dst, src, '\r', rawsize); | 459 cfType = symbol_to_ms_cf (target_type); |
145 if (next) | 460 |
146 { | 461 /* Only continue if we can figure out a clipboard type */ |
147 /* copied one line ending with '\r' */ | 462 if (!cfType) |
148 int copied = next - dst; | 463 return Qnil; |
149 rawsize -= copied; | 464 |
150 src += copied; | 465 cfObject = ms_cf_to_symbol (cfType); |
151 if (*src == '\n') | 466 } |
152 dst += copied - 1; /* overwrite '\r' */ | 467 |
153 else | 468 /* Find the frame */ |
154 dst += copied; | 469 f = selected_frame (); |
155 } | 470 |
156 } | 471 /* Open the clipboard */ |
157 while (next); | 472 if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f))) |
158 | 473 return Qnil; |
159 GlobalUnlock (h); | 474 |
160 } | 475 /* Read the clipboard */ |
161 | 476 hValue = GetClipboardData (cfType); |
477 | |
478 if (!hValue) | |
479 { | |
480 CloseClipboard (); | |
481 | |
482 return Qnil; | |
483 } | |
484 | |
485 /* Find the data */ | |
486 size = GlobalSize (hValue); | |
487 data = GlobalLock (hValue); | |
488 | |
489 if (!data) | |
490 { | |
491 CloseClipboard (); | |
492 | |
493 return Qnil; | |
494 } | |
495 | |
496 /* Place it in a Lisp string */ | |
497 TO_INTERNAL_FORMAT (DATA, (data, size), | |
498 LISP_STRING, ret, | |
499 Qbinary); | |
500 | |
501 GlobalUnlock (data); | |
162 CloseClipboard (); | 502 CloseClipboard (); |
163 | 503 |
164 return ret; | 504 GCPRO1 (ret); |
165 } | 505 |
166 | 506 /* Convert this to the appropriate type. If we can't find anything, |
167 static Lisp_Object | 507 then we return a cons of the form (DATA-TYPE . STRING), where the |
168 mswindows_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type) | 508 string contains the raw binary data. */ |
169 { | 509 value = select_convert_in (selection_symbol, |
170 if (EQ (selection_symbol, QCLIPBOARD)) | 510 cfObject, |
171 return Fmswindows_get_clipboard (); | 511 ret); |
512 | |
513 UNGCPRO; | |
514 | |
515 if (NILP (value)) | |
516 return Fcons (cfObject, ret); | |
172 else | 517 else |
173 return Qnil; | 518 return value; |
174 } | |
175 | |
176 DEFUN ("mswindows-selection-exists-p", Fmswindows_selection_exists_p, 0, 0, 0, /* | |
177 Whether there is an MS-Windows selection. | |
178 */ | |
179 ()) | |
180 { | |
181 return IsClipboardFormatAvailable (CF_TEXT) ? Qt : Qnil; | |
182 } | |
183 | |
184 DEFUN ("mswindows-delete-selection", Fmswindows_delete_selection, 0, 0, 0, /* | |
185 Remove the current MS-Windows selection from the clipboard. | |
186 */ | |
187 ()) | |
188 { | |
189 BOOL success = OpenClipboard (NULL); | |
190 if (success) | |
191 { | |
192 success = EmptyClipboard (); | |
193 /* Close it regardless of whether empty worked. */ | |
194 if (!CloseClipboard ()) | |
195 success = FALSE; | |
196 } | |
197 | |
198 return success ? Qt : Qnil; | |
199 } | 519 } |
200 | 520 |
201 static void | 521 static void |
202 mswindows_disown_selection (Lisp_Object selection, Lisp_Object timeval) | 522 mswindows_disown_selection (Lisp_Object selection, Lisp_Object timeval) |
203 { | 523 { |
204 if (EQ (selection, QCLIPBOARD)) | 524 if (EQ (selection, QCLIPBOARD)) |
205 Fmswindows_delete_selection (); | 525 { |
526 BOOL success = OpenClipboard (NULL); | |
527 if (success) | |
528 { | |
529 success = EmptyClipboard (); | |
530 /* Close it regardless of whether empty worked. */ | |
531 if (!CloseClipboard ()) | |
532 success = FALSE; | |
533 } | |
534 | |
535 /* #### return success ? Qt : Qnil; */ | |
536 } | |
537 } | |
538 | |
539 void | |
540 mswindows_destroy_selection (Lisp_Object selection) | |
541 { | |
542 /* Do nothing if this isn't for the clipboard. */ | |
543 if (!EQ (selection, QCLIPBOARD)) | |
544 return; | |
545 | |
546 /* Right. We need to delete everything in Vhandle_alist. */ | |
547 { | |
548 LIST_LOOP_2 (elt, Vhandle_alist) | |
549 GlobalFree ((HGLOBAL) get_opaque_ptr (XCDR (elt))); | |
550 } | |
551 | |
552 Vhandle_alist = Qnil; | |
553 } | |
554 | |
555 static Lisp_Object | |
556 mswindows_selection_exists_p (Lisp_Object selection, | |
557 Lisp_Object selection_type) | |
558 { | |
559 /* We used to be picky about the format, but now we support anything. */ | |
560 if (EQ (selection, QCLIPBOARD)) | |
561 { | |
562 if (NILP (selection_type)) | |
563 return CountClipboardFormats () ? Qt : Qnil; | |
564 else | |
565 return IsClipboardFormatAvailable (symbol_to_ms_cf (selection_type)) | |
566 ? Qt : Qnil; | |
567 } | |
568 else | |
569 return Qnil; | |
206 } | 570 } |
207 | 571 |
208 | 572 |
209 /************************************************************************/ | 573 /************************************************************************/ |
210 /* initialization */ | 574 /* initialization */ |
213 void | 577 void |
214 console_type_create_select_mswindows (void) | 578 console_type_create_select_mswindows (void) |
215 { | 579 { |
216 CONSOLE_HAS_METHOD (mswindows, own_selection); | 580 CONSOLE_HAS_METHOD (mswindows, own_selection); |
217 CONSOLE_HAS_METHOD (mswindows, disown_selection); | 581 CONSOLE_HAS_METHOD (mswindows, disown_selection); |
582 CONSOLE_HAS_METHOD (mswindows, selection_exists_p); | |
218 CONSOLE_HAS_METHOD (mswindows, get_foreign_selection); | 583 CONSOLE_HAS_METHOD (mswindows, get_foreign_selection); |
584 CONSOLE_HAS_METHOD (mswindows, available_selection_types); | |
585 CONSOLE_HAS_METHOD (mswindows, register_selection_data_type); | |
586 CONSOLE_HAS_METHOD (mswindows, selection_data_type_name); | |
219 } | 587 } |
220 | 588 |
221 void | 589 void |
222 syms_of_select_mswindows (void) | 590 syms_of_select_mswindows (void) |
223 { | 591 { |
224 DEFSUBR (Fmswindows_set_clipboard); | |
225 DEFSUBR (Fmswindows_get_clipboard); | |
226 DEFSUBR (Fmswindows_selection_exists_p); | |
227 DEFSUBR (Fmswindows_delete_selection); | |
228 } | 592 } |
229 | 593 |
230 void | 594 void |
231 vars_of_select_mswindows (void) | 595 vars_of_select_mswindows (void) |
232 { | 596 { |
233 } | 597 /* Initialise Vhandle_alist */ |
598 Vhandle_alist = Qnil; | |
599 staticpro (&Vhandle_alist); | |
600 } |