Mercurial > hg > xemacs-beta
comparison src/select.c @ 410:de805c49cfc1 r21-2-35
Import from CVS: tag r21-2-35
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:19:21 +0200 |
parents | 74fd4e045ea6 |
children |
comparison
equal
deleted
inserted
replaced
409:301b9ebbdf3b | 410:de805c49cfc1 |
---|---|
24 #include <config.h> | 24 #include <config.h> |
25 #include "lisp.h" | 25 #include "lisp.h" |
26 | 26 |
27 #include "buffer.h" | 27 #include "buffer.h" |
28 #include "device.h" | 28 #include "device.h" |
29 #include "extents.h" | |
29 #include "console.h" | 30 #include "console.h" |
30 #include "objects.h" | 31 #include "objects.h" |
31 | 32 |
32 #include "frame.h" | 33 #include "frame.h" |
33 #include "opaque.h" | 34 #include "opaque.h" |
34 #include "select.h" | 35 #include "select.h" |
35 | 36 |
37 /* X Atoms */ | |
36 Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, | 38 Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, |
37 QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL, | 39 QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL, |
38 QATOM_PAIR, QCOMPOUND_TEXT; | 40 QATOM_PAIR, QCOMPOUND_TEXT; |
39 | 41 |
42 /* Windows clipboard formats */ | |
43 Lisp_Object QCF_TEXT, QCF_BITMAP, QCF_METAFILEPICT, QCF_SYLK, QCF_DIF, | |
44 QCF_TIFF, QCF_OEMTEXT, QCF_DIB, QCF_PALETTE, QCF_PENDATA, QCF_RIFF, | |
45 QCF_WAVE, QCF_UNICODETEXT, QCF_ENHMETAFILE, QCF_HDROP, QCF_LOCALE, | |
46 QCF_OWNERDISPLAY, QCF_DSPTEXT, QCF_DSPBITMAP, QCF_DSPMETAFILEPICT, | |
47 QCF_DSPENHMETAFILE; | |
48 | |
49 /* Selection strategy symbols */ | |
50 Lisp_Object Qreplace_all, Qreplace_existing; | |
51 | |
40 /* "Selection owner couldn't convert selection" */ | 52 /* "Selection owner couldn't convert selection" */ |
41 Lisp_Object Qselection_conversion_error; | 53 Lisp_Object Qselection_conversion_error; |
42 | 54 |
43 /* This is an alist whose CARs are selection-types (whose names are the same | 55 /* A couple of Lisp functions */ |
44 as the names of X Atoms) and whose CDRs are the names of Lisp functions to | 56 Lisp_Object Qselect_convert_in, Qselect_convert_out; |
45 call to convert the given Emacs selection value to a string representing | 57 |
46 the given selection type. This is for elisp-level extension of the emacs | 58 /* These are alists whose CARs are selection-types (whose names are the same |
47 selection handling. | 59 as the names of X Atoms or Windows clipboard formats) and whose CDRs are |
60 the names of Lisp functions to call to convert the given Emacs selection | |
61 value to a string representing the given selection type. This is for | |
62 elisp-level extension of the emacs selection handling. | |
48 */ | 63 */ |
49 Lisp_Object Vselection_converter_alist; | 64 Lisp_Object Vselection_converter_out_alist; |
65 Lisp_Object Vselection_converter_in_alist; | |
66 Lisp_Object Vselection_appender_alist; | |
67 Lisp_Object Vselection_buffer_killed_alist; | |
68 Lisp_Object Vselection_coercible_types; | |
50 | 69 |
51 Lisp_Object Vlost_selection_hooks; | 70 Lisp_Object Vlost_selection_hooks; |
52 | 71 |
53 /* This is an association list whose elements are of the form | 72 /* This is an association list whose elements are of the form |
54 ( selection-name selection-value selection-timestamp ) | 73 ( selection-name selection-value selection-timestamp ) |
55 selection-name is a lisp symbol, whose name is the name of an X Atom. | 74 selection-name is a lisp symbol, whose name is the name of an X Atom. |
56 selection-value is the value that emacs owns for that selection. | 75 selection-value is a list of cons pairs that emacs owns for that selection. |
57 It may be any kind of Lisp object. | 76 Each pair consists of (type . value), where type is nil or a |
77 selection data type, and value is any type of Lisp object. | |
58 selection-timestamp is the time at which emacs began owning this selection, | 78 selection-timestamp is the time at which emacs began owning this selection, |
59 as a cons of two 16-bit numbers (making a 32 bit time). | 79 as a cons of two 16-bit numbers (making a 32 bit time). |
60 If there is an entry in this alist, then it can be assumed that emacs owns | 80 If there is an entry in this alist, then it can be assumed that emacs owns |
61 that selection. | 81 that selection. |
62 The only (eq) parts of this list that are visible from elisp are the | 82 The only (eq) parts of this list that are visible from elisp are the |
63 selection-values. | 83 selection-values. |
64 */ | 84 */ |
65 Lisp_Object Vselection_alist; | 85 Lisp_Object Vselection_alist; |
66 | 86 |
87 /* Given a selection-name and desired type, this looks up our local copy of | |
88 the selection value and converts it to the type. */ | |
67 static Lisp_Object | 89 static Lisp_Object |
68 clean_local_selection_data (Lisp_Object obj) | |
69 { | |
70 if (CONSP (obj) && | |
71 INTP (XCAR (obj)) && | |
72 CONSP (XCDR (obj)) && | |
73 INTP (XCAR (XCDR (obj))) && | |
74 NILP (XCDR (XCDR (obj)))) | |
75 obj = Fcons (XCAR (obj), XCDR (obj)); | |
76 | |
77 if (CONSP (obj) && | |
78 INTP (XCAR (obj)) && | |
79 INTP (XCDR (obj))) | |
80 { | |
81 if (XINT (XCAR (obj)) == 0) | |
82 return XCDR (obj); | |
83 if (XINT (XCAR (obj)) == -1) | |
84 return make_int (- XINT (XCDR (obj))); | |
85 } | |
86 if (VECTORP (obj)) | |
87 { | |
88 int i; | |
89 int len = XVECTOR_LENGTH (obj); | |
90 Lisp_Object copy; | |
91 if (len == 1) | |
92 return clean_local_selection_data (XVECTOR_DATA (obj) [0]); | |
93 copy = make_vector (len, Qnil); | |
94 for (i = 0; i < len; i++) | |
95 XVECTOR_DATA (copy) [i] = | |
96 clean_local_selection_data (XVECTOR_DATA (obj) [i]); | |
97 return copy; | |
98 } | |
99 return obj; | |
100 } | |
101 | |
102 /* Given a selection-name and desired type, this looks up our local copy of | |
103 the selection value and converts it to the type. It returns nil or a | |
104 string. This calls random elisp code, and may signal or gc. | |
105 */ | |
106 Lisp_Object | |
107 get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type) | 90 get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type) |
108 { | 91 { |
109 /* This function can GC */ | |
110 Lisp_Object handler_fn, value, check; | |
111 Lisp_Object local_value = assq_no_quit (selection_symbol, Vselection_alist); | 92 Lisp_Object local_value = assq_no_quit (selection_symbol, Vselection_alist); |
112 | 93 |
113 if (NILP (local_value)) return Qnil; | 94 if (!NILP (local_value)) |
114 | 95 { |
115 /* TIMESTAMP and MULTIPLE are special cases 'cause that's easiest. */ | 96 Lisp_Object value_list = XCAR (XCDR (local_value)); |
116 if (EQ (target_type, QTIMESTAMP)) | 97 Lisp_Object value; |
117 { | 98 |
118 handler_fn = Qnil; | 99 /* First try to find an entry of the appropriate type */ |
119 value = XCAR (XCDR (XCDR (local_value))); | 100 value = assq_no_quit (target_type, value_list); |
120 } | 101 |
121 | 102 if (!NILP (value)) |
122 #if 0 /* #### MULTIPLE doesn't work yet and probably never will */ | 103 return XCDR (value); |
123 else if (CONSP (target_type) && | 104 } |
124 XCAR (target_type) == QMULTIPLE) | 105 |
125 { | 106 return Qnil; |
126 Lisp_Object pairs = XCDR (target_type); | 107 } |
127 int len = XVECTOR_LENGTH (pairs); | 108 |
128 int i; | 109 /* #### Should perhaps handle 'MULTIPLE. The code below is now completely |
129 /* If the target is MULTIPLE, then target_type looks like | 110 broken due to a re-organization of get_local_selection, but I've left |
130 (MULTIPLE . [[SELECTION1 TARGET1] [SELECTION2 TARGET2] ... ]) | 111 it here should anyone show an interest - ajh */ |
131 We modify the second element of each pair in the vector and | 112 #if 0 |
132 return it as [[SELECTION1 <value1>] [SELECTION2 <value2>] ... ] | 113 else if (CONSP (target_type) && |
133 */ | 114 XCAR (target_type) == QMULTIPLE) |
134 for (i = 0; i < len; i++) | |
135 { | 115 { |
136 Lisp_Object pair = XVECTOR_DATA (pairs) [i]; | 116 Lisp_Object pairs = XCDR (target_type); |
137 XVECTOR_DATA (pair) [1] = | 117 int len = XVECTOR_LENGTH (pairs); |
138 x_get_local_selection (XVECTOR_DATA (pair) [0], | 118 int i; |
139 XVECTOR_DATA (pair) [1]); | 119 /* If the target is MULTIPLE, then target_type looks like |
120 (MULTIPLE . [[SELECTION1 TARGET1] [SELECTION2 TARGET2] ... ]) | |
121 We modify the second element of each pair in the vector and | |
122 return it as [[SELECTION1 <value1>] [SELECTION2 <value2>] ... ] | |
123 */ | |
124 for (i = 0; i < len; i++) | |
125 { | |
126 Lisp_Object pair = XVECTOR_DATA (pairs) [i]; | |
127 XVECTOR_DATA (pair) [1] = | |
128 x_get_local_selection (XVECTOR_DATA (pair) [0], | |
129 XVECTOR_DATA (pair) [1]); | |
130 } | |
131 return pairs; | |
140 } | 132 } |
141 return pairs; | |
142 } | |
143 #endif | 133 #endif |
144 else | 134 |
145 { | 135 DEFUN ("own-selection-internal", Fown_selection_internal, 2, 5, 0, /* |
146 CHECK_SYMBOL (target_type); | 136 Assert a selection of the given NAME with the given VALUE, and |
147 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist)); | 137 optional window-system DATA-TYPE. HOW-TO-ADD specifies how the |
148 if (NILP (handler_fn)) return Qnil; | 138 selection will be combined with any existing selection(s) - see |
149 value = call3 (handler_fn, | 139 `own-selection' for more information. |
150 selection_symbol, target_type, | 140 NAME is a symbol, typically PRIMARY, SECONDARY, or CLIPBOARD. |
151 XCAR (XCDR (local_value))); | |
152 } | |
153 | |
154 /* This lets the selection function to return (TYPE . VALUE). For example, | |
155 when the selected type is LINE_NUMBER, the returned type is SPAN, not | |
156 INTEGER. | |
157 */ | |
158 check = value; | |
159 if (CONSP (value) && SYMBOLP (XCAR (value))) | |
160 check = XCDR (value); | |
161 | |
162 /* Strings, vectors, and symbols are converted to selection data format in | |
163 the obvious way. Integers are converted to 16 bit quantities if they're | |
164 small enough, otherwise 32 bits are used. | |
165 */ | |
166 if (STRINGP (check) || | |
167 VECTORP (check) || | |
168 SYMBOLP (check) || | |
169 INTP (check) || | |
170 CHARP (check) || | |
171 NILP (value)) | |
172 return value; | |
173 | |
174 /* (N . M) or (N M) get turned into a 32 bit quantity. So if you want to | |
175 always return a small quantity as 32 bits, your converter routine needs | |
176 to return a cons. | |
177 */ | |
178 else if (CONSP (check) && | |
179 INTP (XCAR (check)) && | |
180 (INTP (XCDR (check)) || | |
181 (CONSP (XCDR (check)) && | |
182 INTP (XCAR (XCDR (check))) && | |
183 NILP (XCDR (XCDR (check)))))) | |
184 return value; | |
185 /* Otherwise the lisp converter function returned something unrecognized. | |
186 */ | |
187 else | |
188 signal_error (Qerror, | |
189 list3 (build_string | |
190 ("unrecognized selection-conversion type"), | |
191 handler_fn, | |
192 value)); | |
193 | |
194 return Qnil; /* suppress compiler warning */ | |
195 } | |
196 | |
197 DEFUN ("own-selection-internal", Fown_selection_internal, 2, 3, 0, /* | |
198 Assert a selection of the given TYPE with the given VALUE. | |
199 TYPE is a symbol, typically PRIMARY, SECONDARY, or CLIPBOARD. | |
200 VALUE is typically a string, or a cons of two markers, but may be | 141 VALUE is typically a string, or a cons of two markers, but may be |
201 anything that the functions on selection-converter-alist know about. | 142 anything that the functions on selection-converter-out-alist know about. |
202 */ | 143 */ |
203 (selection_name, selection_value, device)) | 144 (selection_name, selection_value, how_to_add, data_type, device)) |
204 { | 145 { |
205 Lisp_Object selection_time, selection_data, prev_value; | 146 Lisp_Object selection_time, selection_data, prev_value = Qnil, |
147 value_list = Qnil; | |
148 Lisp_Object prev_real_value = Qnil; | |
206 struct gcpro gcpro1; | 149 struct gcpro gcpro1; |
207 | 150 |
208 CHECK_SYMBOL (selection_name); | 151 CHECK_SYMBOL (selection_name); |
209 if (NILP (selection_value)) error ("selection-value may not be nil."); | 152 if (NILP (selection_value)) error ("selection-value may not be nil."); |
210 | 153 |
211 if (NILP (device)) | 154 if (NILP (device)) |
212 device = Fselected_device (Qnil); | 155 device = Fselected_device (Qnil); |
213 | 156 |
214 /* Now update the local cache */ | 157 if (!EQ (how_to_add, Qappend) && !EQ (how_to_add, Qt) |
215 selection_data = list3 (selection_name, | 158 && !EQ (how_to_add, Qreplace_existing) |
216 selection_value, | 159 && !EQ (how_to_add, Qreplace_all) && !NILP (how_to_add)) |
217 Qnil); | 160 error ("how-to-add must be nil, append, replace_all, " |
218 GCPRO1 (selection_data); | 161 "replace_existing or t."); |
219 | 162 |
220 prev_value = assq_no_quit (selection_name, Vselection_alist); | 163 #ifdef MULE |
221 Vselection_alist = Fcons (selection_data, Vselection_alist); | 164 if (NILP (data_type)) |
165 data_type = QCOMPOUND_TEXT; | |
166 #else | |
167 if (NILP (data_type)) | |
168 data_type = QSTRING; | |
169 #endif | |
170 | |
171 /* Examine the how-to-add argument */ | |
172 if (EQ (how_to_add, Qreplace_all) || NILP (how_to_add)) | |
173 { | |
174 Lisp_Object local_selection_data = assq_no_quit (selection_name, | |
175 Vselection_alist); | |
176 | |
177 if (!NILP (local_selection_data)) | |
178 { | |
179 /* Don't use Fdelq() as that may QUIT;. */ | |
180 if (EQ (local_selection_data, Fcar (Vselection_alist))) | |
181 Vselection_alist = Fcdr (Vselection_alist); | |
182 else | |
183 { | |
184 Lisp_Object rest; | |
185 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest)) | |
186 if (EQ (local_selection_data, Fcar (XCDR (rest)))) | |
187 { | |
188 XCDR (rest) = Fcdr (XCDR (rest)); | |
189 break; | |
190 } | |
191 } | |
192 } | |
193 } | |
194 else | |
195 { | |
196 /* Look for a previous value */ | |
197 prev_value = assq_no_quit (selection_name, Vselection_alist); | |
198 | |
199 if (!NILP (prev_value)) | |
200 value_list = XCAR (XCDR (prev_value)); | |
201 | |
202 if (!NILP (value_list)) | |
203 prev_real_value = assq_no_quit (data_type, value_list); | |
204 } | |
205 | |
206 /* Append values if necessary */ | |
207 if (!NILP (value_list) && (EQ (how_to_add, Qappend) || EQ (how_to_add, Qt))) | |
208 { | |
209 /* Did we have anything of this type previously? */ | |
210 if (!NILP (prev_real_value)) | |
211 { | |
212 if ((NILP (data_type) && STRINGP (selection_value) | |
213 && STRINGP (XCDR (prev_real_value))) | |
214 || !NILP (data_type)) | |
215 { | |
216 Lisp_Object function = assq_no_quit (data_type, | |
217 Vselection_appender_alist); | |
218 | |
219 if (NILP (function)) | |
220 error ("cannot append selections of supplied types."); | |
221 | |
222 function = XCDR (function); | |
223 | |
224 selection_value = call4 (function, | |
225 selection_name, | |
226 data_type, | |
227 XCDR (prev_real_value), | |
228 selection_value); | |
229 | |
230 if (NILP (selection_value)) | |
231 error ("cannot append selections of supplied types."); | |
232 } | |
233 else | |
234 error ("cannot append selections of supplied types."); | |
235 } | |
236 | |
237 selection_data = Fcons (data_type, selection_value); | |
238 value_list = Fcons (selection_data, value_list); | |
239 } | |
222 | 240 |
223 /* If we already owned the selection, remove the old selection data. | 241 if (!NILP (prev_real_value)) |
224 Perhaps we should destructively modify it instead. | 242 { |
225 Don't use Fdelq() as that may QUIT;. | 243 Lisp_Object rest; /* We know it isn't the CAR, so it's easy. */ |
226 */ | 244 |
227 if (!NILP (prev_value)) | 245 /* Delete the old type entry from the list */ |
228 { | 246 for (rest = value_list; !NILP (rest); rest = Fcdr (rest)) |
229 Lisp_Object rest; /* we know it's not the CAR, so it's easy. */ | 247 if (EQ (prev_real_value, Fcar (XCDR (rest)))) |
230 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest)) | |
231 if (EQ (prev_value, Fcar (XCDR (rest)))) | |
232 { | 248 { |
233 XCDR (rest) = Fcdr (XCDR (rest)); | 249 XCDR (rest) = Fcdr (XCDR (rest)); |
234 break; | 250 break; |
235 } | 251 } |
236 } | 252 } |
253 else | |
254 { | |
255 value_list = Fcons (Fcons (data_type, selection_value), | |
256 value_list); | |
257 } | |
258 | |
259 /* Complete the local cache update; note that we destructively | |
260 modify the current list entry if there is one */ | |
261 if (NILP (prev_value)) | |
262 { | |
263 selection_data = list3 (selection_name, value_list, Qnil); | |
264 Vselection_alist = Fcons (selection_data, Vselection_alist); | |
265 } | |
266 else | |
267 { | |
268 selection_data = prev_value; | |
269 Fsetcar (XCDR (selection_data), value_list); | |
270 } | |
271 | |
272 GCPRO1 (selection_data); | |
237 | 273 |
238 /* have to do device specific stuff last so that methods can access the | 274 /* have to do device specific stuff last so that methods can access the |
239 selection_alist */ | 275 selection_alist */ |
240 if (HAS_DEVMETH_P (XDEVICE (device), own_selection)) | 276 if (HAS_DEVMETH_P (XDEVICE (device), own_selection)) |
241 selection_time = DEVMETH (XDEVICE (device), own_selection, | 277 selection_time = DEVMETH (XDEVICE (device), own_selection, |
242 (selection_name, selection_value)); | 278 (selection_name, selection_value, |
279 how_to_add, data_type)); | |
243 else | 280 else |
244 selection_time = Qnil; | 281 selection_time = Qnil; |
245 | 282 |
246 Fsetcar (XCDR (XCDR (selection_data)), selection_time); | 283 Fsetcar (XCDR (XCDR (selection_data)), selection_time); |
247 | 284 |
248 UNGCPRO; | 285 UNGCPRO; |
249 | 286 |
250 return selection_value; | 287 return selection_value; |
251 } | 288 } |
252 | 289 |
290 DEFUN ("register-selection-data-type", Fregister_selection_data_type, 1,2,0, /* | |
291 Register a new selection data type DATA-TYPE, optionally on the specified | |
292 DEVICE. Returns the device-specific data type identifier, or nil if the | |
293 device does not support this feature or the registration fails. */ | |
294 (data_type, device)) | |
295 { | |
296 /* Check arguments */ | |
297 CHECK_STRING (data_type); | |
298 | |
299 if (NILP (device)) | |
300 device = Fselected_device (Qnil); | |
301 | |
302 if (HAS_DEVMETH_P (XDEVICE (device), register_selection_data_type)) | |
303 return DEVMETH (XDEVICE (device), register_selection_data_type, | |
304 (data_type)); | |
305 else | |
306 return Qnil; | |
307 } | |
308 | |
309 DEFUN ("selection-data-type-name", Fselection_data_type_name, 1, 2, 0, /* | |
310 Retrieve the name of the specified selection data type DATA-TYPE, optionally | |
311 on the specified DEVICE. Returns either a string or a symbol on success, and | |
312 nil if the device does not support this feature or the type is not known. */ | |
313 (data_type, device)) | |
314 { | |
315 if (NILP (device)) | |
316 device = Fselected_device (Qnil); | |
317 | |
318 if (HAS_DEVMETH_P (XDEVICE (device), selection_data_type_name)) | |
319 return DEVMETH (XDEVICE (device), selection_data_type_name, (data_type)); | |
320 else | |
321 return Qnil; | |
322 } | |
323 | |
324 DEFUN ("available-selection-types", Favailable_selection_types, 1, 2, 0, /* | |
325 Retrieve a list of currently available types of selection associated with | |
326 the given SELECTION-NAME, optionally on the specified DEVICE. This list | |
327 does not take into account any possible conversions that might take place, | |
328 so it should be taken as a minimal estimate of what is available. | |
329 */ | |
330 (selection_name, device)) | |
331 { | |
332 Lisp_Object types = Qnil, rest; | |
333 struct gcpro gcpro1; | |
334 | |
335 CHECK_SYMBOL (selection_name); | |
336 | |
337 if (NILP (device)) | |
338 device = Fselected_device (Qnil); | |
339 | |
340 GCPRO1 (types); | |
341 | |
342 /* First check the device */ | |
343 if (HAS_DEVMETH_P (XDEVICE (device), available_selection_types)) | |
344 types = DEVMETH (XDEVICE (device), available_selection_types, | |
345 (selection_name)); | |
346 | |
347 /* Now look in the list */ | |
348 rest = assq_no_quit (selection_name, Vselection_alist); | |
349 | |
350 if (NILP (rest)) | |
351 { | |
352 UNGCPRO; | |
353 | |
354 return types; | |
355 } | |
356 | |
357 /* Examine the types and cons them onto the front of the list */ | |
358 for (rest = XCAR (XCDR (rest)); !NILP (rest); rest = XCDR (rest)) | |
359 { | |
360 Lisp_Object value = XCDR (XCAR (rest)); | |
361 Lisp_Object type = XCAR (XCAR (rest)); | |
362 | |
363 types = Fcons (type, types); | |
364 | |
365 if ((STRINGP (value) || EXTENTP (value)) | |
366 && (NILP (type) || EQ (type, QSTRING) | |
367 || EQ (type, QTEXT) || EQ (type, QCOMPOUND_TEXT))) | |
368 types = Fcons (QTEXT, Fcons (QCOMPOUND_TEXT, Fcons (QSTRING, types))); | |
369 else if (INTP (value) && NILP (type)) | |
370 types = Fcons (QINTEGER, types); | |
371 else if (SYMBOLP (value) && NILP (type)) | |
372 types = Fcons (QATOM, types); | |
373 } | |
374 | |
375 UNGCPRO; | |
376 | |
377 return types; | |
378 } | |
379 | |
253 /* remove a selection from our local copy | 380 /* remove a selection from our local copy |
254 */ | 381 */ |
255 void | 382 void |
256 handle_selection_clear (Lisp_Object selection_symbol) | 383 handle_selection_clear (Lisp_Object selection_symbol) |
257 { | 384 { |
258 Lisp_Object local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); | 385 Lisp_Object local_selection_data = assq_no_quit (selection_symbol, |
386 Vselection_alist); | |
259 | 387 |
260 /* Well, we already believe that we don't own it, so that's just fine. */ | 388 /* Well, we already believe that we don't own it, so that's just fine. */ |
261 if (NILP (local_selection_data)) return; | 389 if (NILP (local_selection_data)) return; |
262 | 390 |
263 /* Otherwise, we're really honest and truly being told to drop it. | 391 /* Otherwise, we're really honest and truly being told to drop it. |
324 else if (EQ (selection, Qt)) selection = QSECONDARY; | 452 else if (EQ (selection, Qt)) selection = QSECONDARY; |
325 | 453 |
326 return NILP (Fassq (selection, Vselection_alist)) ? Qnil : Qt; | 454 return NILP (Fassq (selection, Vselection_alist)) ? Qnil : Qt; |
327 } | 455 } |
328 | 456 |
329 DEFUN ("selection-exists-p", Fselection_exists_p, 0, 2, 0, /* | 457 DEFUN ("selection-exists-p", Fselection_exists_p, 0, 3, 0, /* |
330 Whether there is an owner for the given Selection. | 458 Whether there is an owner for the given Selection. |
331 The arg should be the name of the selection in question, typically one of | 459 The arg should be the name of the selection in question, typically one of |
332 the symbols PRIMARY, SECONDARY, or CLIPBOARD. (For convenience, the symbol | 460 the symbols PRIMARY, SECONDARY, or CLIPBOARD. (For convenience, the symbol |
333 nil is the same as PRIMARY, and t is the same as SECONDARY.) | 461 nil is the same as PRIMARY, and t is the same as SECONDARY.) |
462 Optionally the DEVICE and the window-system DATA-TYPE may be specified. | |
334 */ | 463 */ |
335 (selection, device)) | 464 (selection, data_type, device)) |
336 { | 465 { |
337 CHECK_SYMBOL (selection); | 466 CHECK_SYMBOL (selection); |
338 if (!NILP (Fselection_owner_p (selection))) | 467 if (NILP (data_type) |
468 && !NILP (Fselection_owner_p (selection))) | |
339 return Qt; | 469 return Qt; |
340 | 470 |
341 if (NILP (device)) | 471 if (NILP (device)) |
342 device = Fselected_device (Qnil); | 472 device = Fselected_device (Qnil); |
343 | 473 |
344 return HAS_DEVMETH_P (XDEVICE (device), selection_exists_p) ? | 474 return HAS_DEVMETH_P (XDEVICE (device), selection_exists_p) ? |
345 DEVMETH (XDEVICE (device), selection_exists_p, (selection)) | 475 DEVMETH (XDEVICE (device), selection_exists_p, (selection, data_type)) |
346 : Qnil; | 476 : Qnil; |
477 } | |
478 | |
479 /* Get the timestamp of the given selection */ | |
480 DEFUN ("get-selection-timestamp", Fget_selection_timestamp, 1, 1, 0, /* | |
481 Return the timestamp associated with the specified SELECTION, if it exists. | |
482 Note that the timestamp is a device-specific object, and may not actually be | |
483 visible from Lisp. | |
484 */ | |
485 (selection)) | |
486 { | |
487 Lisp_Object local_value = assq_no_quit (selection, Vselection_alist); | |
488 | |
489 if (!NILP (local_value)) | |
490 return XCAR (XCDR (XCDR (local_value))); | |
491 | |
492 return Qnil; | |
347 } | 493 } |
348 | 494 |
349 /* Request the selection value from the owner. If we are the owner, | 495 /* Request the selection value from the owner. If we are the owner, |
350 simply return our selection value. If we are not the owner, this | 496 simply return our selection value. If we are not the owner, this |
351 will block until all of the data has arrived. | 497 will block until all of the data has arrived. |
358 TEXT or COMPOUND_TEXT, it will be decoded as Compound Text. | 504 TEXT or COMPOUND_TEXT, it will be decoded as Compound Text. |
359 */ | 505 */ |
360 (selection_symbol, target_type, device)) | 506 (selection_symbol, target_type, device)) |
361 { | 507 { |
362 /* This function can GC */ | 508 /* This function can GC */ |
363 Lisp_Object val = Qnil; | 509 Lisp_Object val = Qnil, element = Qnil; |
364 struct gcpro gcpro1, gcpro2; | 510 struct gcpro gcpro1, gcpro2, gcpro3; |
365 GCPRO2 (target_type, val); /* we store newly consed data into these */ | 511 GCPRO3 (target_type, val, element); |
366 CHECK_SYMBOL (selection_symbol); | 512 CHECK_SYMBOL (selection_symbol); |
367 | 513 |
368 if (NILP (device)) | 514 if (NILP (device)) |
369 device = Fselected_device (Qnil); | 515 device = Fselected_device (Qnil); |
370 | 516 |
517 #ifdef MULE | |
518 if (NILP (target_type)) | |
519 target_type = QCOMPOUND_TEXT; | |
520 #else | |
521 if (NILP (target_type)) | |
522 target_type = QSTRING; | |
523 #endif | |
524 | |
371 #if 0 /* #### MULTIPLE doesn't work yet and probably never will */ | 525 #if 0 /* #### MULTIPLE doesn't work yet and probably never will */ |
372 if (CONSP (target_type) && | 526 if (CONSP (target_type) && |
373 XCAR (target_type) == QMULTIPLE) | 527 XCAR (target_type) == QMULTIPLE) |
374 { | 528 { |
375 CHECK_VECTOR (XCDR (target_type)); | 529 CHECK_VECTOR (XCDR (target_type)); |
376 /* So we don't destructively modify this... */ | 530 /* So we don't destructively modify this... */ |
377 target_type = copy_multiple_data (target_type); | 531 target_type = copy_multiple_data (target_type); |
378 } | 532 } |
379 else | |
380 #endif | 533 #endif |
381 CHECK_SYMBOL (target_type); | 534 |
535 /* Used to check that target_type was a symbol. This is no longer | |
536 necessarily the case, because the type might be registered with | |
537 the device (in which case target_type would be a device-specific | |
538 identifier - probably an integer) - ajh */ | |
382 | 539 |
383 val = get_local_selection (selection_symbol, target_type); | 540 val = get_local_selection (selection_symbol, target_type); |
384 | 541 |
385 if (NILP (val) && (HAS_DEVMETH_P (XDEVICE (device), get_foreign_selection))) | 542 if (NILP (val) && (HAS_DEVMETH_P (XDEVICE (device), get_foreign_selection))) |
386 { | 543 { |
387 val = DEVMETH (XDEVICE (device), get_foreign_selection, | 544 val = DEVMETH (XDEVICE (device), get_foreign_selection, |
388 (selection_symbol, target_type)); | 545 (selection_symbol, target_type)); |
389 } | 546 } |
390 else | 547 |
391 { | 548 if (NILP (val)) |
392 if (CONSP (val) && SYMBOLP (XCAR (val))) | 549 { |
550 /* Still nothing. Try coercion. */ | |
551 | |
552 /* Try looking in selection-coercible-types to see if any of | |
553 them are present for this selection. We try them *in order*; | |
554 the first for which a conversion succeeds gets returned. */ | |
555 EXTERNAL_LIST_LOOP_2 (element, Vselection_coercible_types) | |
393 { | 556 { |
394 val = XCDR (val); | 557 val = get_local_selection (selection_symbol, element); |
395 if (CONSP (val) && NILP (XCDR (val))) | 558 |
396 val = XCAR (val); | 559 if (NILP (val)) |
560 continue; | |
561 | |
562 /* #### Probably should have a Qselection_coercion_alist and a | |
563 select-coerce function. */ | |
564 val = call3 (Qselect_convert_out, | |
565 selection_symbol, target_type, val); | |
566 | |
567 if (!NILP (val)) | |
568 break; | |
397 } | 569 } |
398 val = clean_local_selection_data (val); | 570 } |
399 } | 571 |
572 if (NILP (val)) | |
573 { | |
574 UNGCPRO; | |
575 | |
576 return Qnil; | |
577 } | |
578 | |
579 /* Used to call clean_local_selection here... but that really belonged | |
580 in Lisp (so the equivalent is now built-in to the INTEGER conversion | |
581 function select-convert-from-integer) - ajh */ | |
582 | |
400 UNGCPRO; | 583 UNGCPRO; |
401 return val; | 584 return val; |
402 } | 585 } |
403 | 586 |
587 /* These two are convenient interfaces to the lisp code in select.el; | |
588 this way we can rename them easily rather than having to hunt everywhere. | |
589 Also, this gives us access to get_local_selection so that convert_out | |
590 can retrieve the internal selection value automatically if passed a | |
591 value of Qnil. */ | |
592 Lisp_Object | |
593 select_convert_in (Lisp_Object selection, | |
594 Lisp_Object type, | |
595 Lisp_Object value) | |
596 { | |
597 return call3 (Qselect_convert_in, selection, type, value); | |
598 } | |
599 | |
600 Lisp_Object | |
601 select_convert_out (Lisp_Object selection, | |
602 Lisp_Object type, | |
603 Lisp_Object value) | |
604 { | |
605 if (NILP (value)) | |
606 value = get_local_selection (selection, type); | |
607 | |
608 if (NILP (value)) | |
609 { | |
610 Lisp_Object element = Qnil, ret; | |
611 struct gcpro gcpro1; | |
612 GCPRO1 (element); | |
613 | |
614 { | |
615 /* Try looking in selection-coercible-types to see if any of | |
616 them are present for this selection. We try them *in order*; | |
617 the first for which a conversion succeeds gets returned. */ | |
618 EXTERNAL_LIST_LOOP_2 (element, Vselection_coercible_types) | |
619 { | |
620 value = get_local_selection (selection, element); | |
621 | |
622 if (NILP (value)) | |
623 continue; | |
624 | |
625 ret = call3 (Qselect_convert_out, selection, type, value); | |
626 | |
627 if (!NILP (ret)) | |
628 { | |
629 UNGCPRO; | |
630 | |
631 return ret; | |
632 } | |
633 } | |
634 } | |
635 | |
636 UNGCPRO; | |
637 | |
638 return Qnil; | |
639 } | |
640 | |
641 return call3 (Qselect_convert_out, selection, type, value); | |
642 } | |
643 | |
644 | |
645 /* Gets called from kill-buffer; this lets us dispose of buffer-dependent | |
646 selections (or alternatively make them independent of the buffer) when | |
647 it gets vaped. */ | |
648 void | |
649 select_notify_buffer_kill (Lisp_Object buffer) | |
650 { | |
651 Lisp_Object rest; | |
652 struct gcpro gcpro1, gcpro2, gcpro3; | |
653 | |
654 /* For each element of Vselection_alist */ | |
655 for (rest = Vselection_alist; | |
656 !NILP (rest);) | |
657 { | |
658 Lisp_Object selection, values, prev = Qnil; | |
659 | |
660 selection = XCAR (rest); | |
661 | |
662 for (values = XCAR (XCDR (selection)); | |
663 !NILP (values); | |
664 values = XCDR (values)) | |
665 { | |
666 Lisp_Object value, handler_fn; | |
667 | |
668 /* Extract the (type . value) pair. */ | |
669 value = XCAR (values); | |
670 | |
671 /* Find the handler function (if any). */ | |
672 handler_fn = Fcdr (Fassq (XCAR (value), | |
673 Vselection_buffer_killed_alist)); | |
674 | |
675 if (!NILP (handler_fn)) | |
676 { | |
677 Lisp_Object newval; | |
678 | |
679 /* Protect ourselves, just in case some tomfool calls | |
680 own-selection from with the buffer-killed handler, then | |
681 causes a GC. Just as a note, *don't do this*. */ | |
682 GCPRO3 (rest, values, value); | |
683 | |
684 newval = call4 (handler_fn, XCAR (selection), XCAR (value), | |
685 XCDR (value), buffer); | |
686 | |
687 UNGCPRO; | |
688 | |
689 /* Set or delete the value (by destructively modifying | |
690 the list). */ | |
691 if (!NILP (newval)) | |
692 { | |
693 Fsetcdr (value, newval); | |
694 | |
695 prev = values; | |
696 } | |
697 else | |
698 { | |
699 if (NILP (prev)) | |
700 Fsetcar (XCDR (selection), XCDR (values)); | |
701 else | |
702 Fsetcdr (prev, XCDR (values)); | |
703 } | |
704 } | |
705 else | |
706 prev = values; | |
707 } | |
708 | |
709 /* If we have no values for this selection */ | |
710 if (NILP (XCAR (XCDR (selection)))) | |
711 { | |
712 /* Move on to the next element *first* */ | |
713 rest = XCDR (rest); | |
714 | |
715 /* Protect it and disown this selection */ | |
716 GCPRO1 (rest); | |
717 | |
718 Fdisown_selection_internal (XCAR (selection), Qnil, Qnil); | |
719 | |
720 UNGCPRO; | |
721 } | |
722 else | |
723 rest = XCDR (rest); | |
724 } | |
725 } | |
726 | |
727 | |
404 void | 728 void |
405 syms_of_select (void) | 729 syms_of_select (void) |
406 { | 730 { |
407 DEFSUBR (Fown_selection_internal); | 731 DEFSUBR (Fown_selection_internal); |
408 DEFSUBR (Fget_selection_internal); | 732 DEFSUBR (Fget_selection_internal); |
409 DEFSUBR (Fselection_exists_p); | 733 DEFSUBR (Fselection_exists_p); |
734 DEFSUBR (Fget_selection_timestamp); | |
410 DEFSUBR (Fdisown_selection_internal); | 735 DEFSUBR (Fdisown_selection_internal); |
411 DEFSUBR (Fselection_owner_p); | 736 DEFSUBR (Fselection_owner_p); |
412 | 737 DEFSUBR (Favailable_selection_types); |
738 DEFSUBR (Fregister_selection_data_type); | |
739 DEFSUBR (Fselection_data_type_name); | |
740 | |
741 /* Lisp Functions */ | |
742 defsymbol (&Qselect_convert_in, "select-convert-in"); | |
743 defsymbol (&Qselect_convert_out, "select-convert-out"); | |
744 | |
745 /* X Atoms */ | |
413 defsymbol (&QPRIMARY, "PRIMARY"); | 746 defsymbol (&QPRIMARY, "PRIMARY"); |
414 defsymbol (&QSECONDARY, "SECONDARY"); | 747 defsymbol (&QSECONDARY, "SECONDARY"); |
415 defsymbol (&QSTRING, "STRING"); | 748 defsymbol (&QSTRING, "STRING"); |
416 defsymbol (&QINTEGER, "INTEGER"); | 749 defsymbol (&QINTEGER, "INTEGER"); |
417 defsymbol (&QCLIPBOARD, "CLIPBOARD"); | 750 defsymbol (&QCLIPBOARD, "CLIPBOARD"); |
425 defsymbol (&QATOM, "ATOM"); | 758 defsymbol (&QATOM, "ATOM"); |
426 defsymbol (&QATOM_PAIR, "ATOM_PAIR"); | 759 defsymbol (&QATOM_PAIR, "ATOM_PAIR"); |
427 defsymbol (&QCOMPOUND_TEXT, "COMPOUND_TEXT"); | 760 defsymbol (&QCOMPOUND_TEXT, "COMPOUND_TEXT"); |
428 defsymbol (&QNULL, "NULL"); | 761 defsymbol (&QNULL, "NULL"); |
429 | 762 |
763 /* Windows formats - these all start with CF_ */ | |
764 defsymbol (&QCF_TEXT, "CF_TEXT"); | |
765 defsymbol (&QCF_BITMAP, "CF_BITMAP"); | |
766 defsymbol (&QCF_METAFILEPICT, "CF_METAFILEPICT"); | |
767 defsymbol (&QCF_SYLK, "CF_SYLK"); | |
768 defsymbol (&QCF_DIF, "CF_DIF"); | |
769 defsymbol (&QCF_TIFF, "CF_TIFF"); | |
770 defsymbol (&QCF_OEMTEXT, "CF_OEMTEXT"); | |
771 defsymbol (&QCF_DIB, "CF_DIB"); | |
772 defsymbol (&QCF_PALETTE, "CF_PALETTE"); | |
773 defsymbol (&QCF_PENDATA, "CF_PENDATA"); | |
774 defsymbol (&QCF_RIFF, "CF_RIFF"); | |
775 defsymbol (&QCF_WAVE, "CF_WAVE"); | |
776 defsymbol (&QCF_UNICODETEXT, "CF_UNICODETEXT"); | |
777 defsymbol (&QCF_ENHMETAFILE, "CF_ENHMETAFILE"); | |
778 defsymbol (&QCF_HDROP, "CF_HDROP"); | |
779 defsymbol (&QCF_LOCALE, "CF_LOCALE"); | |
780 defsymbol (&QCF_OWNERDISPLAY, "CF_OWNERDISPLAY"); | |
781 defsymbol (&QCF_DSPTEXT, "CF_DSPTEXT"); | |
782 defsymbol (&QCF_DSPBITMAP, "CF_DSPBITMAP"); | |
783 defsymbol (&QCF_DSPMETAFILEPICT, "CF_DSPMETAFILEPICT"); | |
784 defsymbol (&QCF_DSPENHMETAFILE, "CF_DSPENHMETAFILE"); | |
785 | |
786 /* Selection strategies */ | |
787 defsymbol (&Qreplace_all, "replace-all"); | |
788 defsymbol (&Qreplace_existing, "replace-existing"); | |
789 | |
430 deferror (&Qselection_conversion_error, | 790 deferror (&Qselection_conversion_error, |
431 "selection-conversion-error", | 791 "selection-conversion-error", |
432 "selection-conversion error", Qio_error); | 792 "selection-conversion error", Qio_error); |
433 } | 793 } |
434 | 794 |
436 vars_of_select (void) | 796 vars_of_select (void) |
437 { | 797 { |
438 Vselection_alist = Qnil; | 798 Vselection_alist = Qnil; |
439 staticpro (&Vselection_alist); | 799 staticpro (&Vselection_alist); |
440 | 800 |
441 DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist /* | 801 DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_out_alist /* |
802 An alist associating selection-types (such as STRING and TIMESTAMP) with | |
803 functions. This is an alias for `selection-converter-out-alist', and should | |
804 be considered obsolete. Use the new name instead. */ ); | |
805 | |
806 DEFVAR_LISP ("selection-converter-out-alist", | |
807 &Vselection_converter_out_alist /* | |
442 An alist associating selection-types (such as STRING and TIMESTAMP) with | 808 An alist associating selection-types (such as STRING and TIMESTAMP) with |
443 functions. These functions will be called with three args: the name | 809 functions. These functions will be called with three args: the name |
444 of the selection (typically PRIMARY, SECONDARY, or CLIPBOARD); a | 810 of the selection (typically PRIMARY, SECONDARY, or CLIPBOARD); a |
445 desired type to which the selection should be converted; and the local | 811 desired type to which the selection should be converted; and the local |
446 selection value (whatever had been passed to `own-selection'). For | 812 selection value (whatever had been passed to `own-selection'). |
447 historical reasons these functions should return the value to send to | 813 |
448 an X server, which should be one of: | 814 The return type of these functions depends upon the device in question; |
815 for mswindows, a string should be returned containing data in the requested | |
816 format, or nil to indicate that the conversion could not be done. Additionally, | |
817 it is permissible to return a cons of the form (DATA-TYPE . STRING) suggesting | |
818 a new data type to use instead. | |
819 | |
820 For X, the return value should be one of: | |
449 | 821 |
450 -- nil (the conversion could not be done) | 822 -- nil (the conversion could not be done) |
451 -- a cons of a symbol and any of the following values; the symbol | 823 -- a cons of a symbol and any of the following values; the symbol |
452 explicitly specifies the type that will be sent. | 824 explicitly specifies the type that will be sent. |
453 -- a string (If the type is not specified, then if Mule support exists, | 825 -- a string (If the type is not specified, then if Mule support exists, |
477 If the type is not specified, a type of 'INTEGER | 849 If the type is not specified, a type of 'INTEGER |
478 will be sent.) | 850 will be sent.) |
479 -- a vector of integers and/or conses (HIGH . LOW) of integers | 851 -- a vector of integers and/or conses (HIGH . LOW) of integers |
480 (Will be converted into a list of 16-bit integers. | 852 (Will be converted into a list of 16-bit integers. |
481 If the type is not specified, a type of 'INTEGER | 853 If the type is not specified, a type of 'INTEGER |
482 will be sent.) */ ); | 854 will be sent.) |
483 Vselection_converter_alist = Qnil; | 855 */ ); |
484 | 856 Vselection_converter_out_alist = Qnil; |
857 | |
858 DEFVAR_LISP ("selection-converter-in-alist", | |
859 &Vselection_converter_in_alist /* | |
860 An alist associating selection-types (such as STRING and TIMESTAMP) with | |
861 functions. These functions will be called with three args: the name | |
862 of the selection (typically PRIMARY, SECONDARY or CLIPBOARD); the | |
863 type from which the selection should be converted; and the selection | |
864 value. These functions should return a suitable representation of the | |
865 value, or nil to indicate that the conversion was not possible. | |
866 | |
867 See also `selection-converter-out-alist'. */ ); | |
868 Vselection_converter_in_alist = Qnil; | |
869 | |
870 DEFVAR_LISP ("selection-appender-alist", | |
871 &Vselection_appender_alist /* | |
872 An alist associating selection-types (such as STRING and TIMESTAMP) with | |
873 functions. These functions will be called with four args; the name | |
874 of the selection (typically PRIMARY, SECONDARY or CLIPBOARD); the type | |
875 of the selection; and two selection values. The functions are expected to | |
876 return a value representing the catenation of the two values, or nil to | |
877 indicate that this was not possible. */ ); | |
878 Vselection_appender_alist = Qnil; | |
879 | |
880 DEFVAR_LISP ("selection-buffer-killed-alist", | |
881 &Vselection_buffer_killed_alist /* | |
882 An alist associating selection-types (such as STRING and TIMESTAMP) with | |
883 functions. These functions will be called whenever a buffer is killed, | |
884 with four args: the name of the selection (typically PRIMARY, SECONDARY | |
885 or CLIPBOARD); the type of the selection; the value of the selection; and | |
886 the buffer that has just been killed. These functions should return a new | |
887 selection value, or nil to indicate that the selection value should be | |
888 deleted. */ ); | |
889 Vselection_buffer_killed_alist = Qnil; | |
890 | |
891 DEFVAR_LISP ("selection-coercible-types", | |
892 &Vselection_coercible_types /* | |
893 A list of selection types that are coercible---that is, types that may be | |
894 automatically converted to another type. Selection values with types in this | |
895 list may be subject to conversion attempts to other types. */ ); | |
896 Vselection_coercible_types = Qnil; | |
897 | |
485 DEFVAR_LISP ("lost-selection-hooks", &Vlost_selection_hooks /* | 898 DEFVAR_LISP ("lost-selection-hooks", &Vlost_selection_hooks /* |
486 A function or functions to be called after we have been notified | 899 A function or functions to be called after we have been notified |
487 that we have lost the selection. The function(s) will be called with one | 900 that we have lost the selection. The function(s) will be called with one |
488 argument, a symbol naming the selection (typically PRIMARY, SECONDARY, or | 901 argument, a symbol naming the selection (typically PRIMARY, SECONDARY, or |
489 CLIPBOARD). | 902 CLIPBOARD). |
490 */ ); | 903 */ ); |
491 Vlost_selection_hooks = Qunbound; | 904 Vlost_selection_hooks = Qunbound; |
492 } | 905 } |
493 |