647
|
1 /* Selection processing for XEmacs -- common btwn select-x.c and select-gtk.c
|
|
2 Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
|
3
|
|
4 This file is part of XEmacs.
|
|
5
|
|
6 XEmacs is free software; you can redistribute it and/or modify it
|
|
7 under the terms of the GNU General Public License as published by the
|
|
8 Free Software Foundation; either version 2, or (at your option) any
|
|
9 later version.
|
|
10
|
|
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with XEmacs; see the file COPYING. If not, write to
|
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
19 Boston, MA 02111-1307, USA. */
|
|
20
|
|
21 /* Synched up with: Not synched with FSF. */
|
|
22
|
|
23 #ifdef PROCESSING_X_CODE
|
|
24 #define XE_ATOM_TYPE Atom
|
|
25 #define XE_ATOM_TO_SYMBOL x_atom_to_symbol
|
|
26 #define XE_SYMBOL_TO_ATOM symbol_to_x_atom
|
|
27 #else
|
|
28 #define XE_ATOM_TYPE GdkAtom
|
|
29 #define XE_ATOM_TO_SYMBOL atom_to_symbol
|
|
30 #define XE_SYMBOL_TO_ATOM symbol_to_gtk_atom
|
|
31 #endif /* PROCESSING_X_CODE */
|
|
32
|
|
33 /* #### These are going to move into Lisp code(!) with the aid of
|
|
34 some new functions I'm working on - ajh */
|
|
35
|
|
36 /* These functions convert from the selection data read from the server into
|
|
37 something that we can use from elisp, and vice versa.
|
|
38
|
|
39 Type: Format: Size: Elisp Type:
|
|
40 ----- ------- ----- -----------
|
|
41 * 8 * String
|
|
42 ATOM 32 1 Symbol
|
|
43 ATOM 32 > 1 Vector of Symbols
|
|
44 * 16 1 Integer
|
|
45 * 16 > 1 Vector of Integers
|
|
46 * 32 1 if <=16 bits: Integer
|
|
47 if > 16 bits: Cons of top16, bot16
|
|
48 * 32 > 1 Vector of the above
|
|
49
|
3833
|
50 NOTE NOTE NOTE:
|
|
51 Format == 32 means that the buffer will be C longs, which need not be
|
|
52 32-bit quantities. See the note in select-x.c (x_get_window_property).
|
|
53
|
647
|
54 When converting a Lisp number to C, it is assumed to be of format 16 if
|
|
55 it is an integer, and of format 32 if it is a cons of two integers.
|
|
56
|
|
57 When converting a vector of numbers from Elisp to C, it is assumed to be
|
|
58 of format 16 if every element in the vector is an integer, and is assumed
|
|
59 to be of format 32 if any element is a cons of two integers.
|
|
60
|
|
61 When converting an object to C, it may be of the form (SYMBOL . <data>)
|
|
62 where SYMBOL is what we should claim that the type is. Format and
|
|
63 representation are as above.
|
|
64
|
|
65 NOTE: Under Mule, when someone shoves us a string without a type, we
|
3025
|
66 set the type to `COMPOUND_TEXT' and automatically convert to Compound
|
647
|
67 Text. If the string has a type, we assume that the user wants the
|
|
68 data sent as-is so we just do "binary" conversion.
|
|
69 */
|
|
70
|
|
71
|
|
72 static Lisp_Object
|
|
73 selection_data_to_lisp_data (struct device *d,
|
2367
|
74 Rawbyte *data,
|
665
|
75 Bytecount size,
|
647
|
76 XE_ATOM_TYPE type,
|
|
77 int format)
|
|
78 {
|
|
79 #ifdef PROCESSING_X_CODE
|
|
80 if (type == DEVICE_XATOM_NULL (d))
|
|
81 return QNULL;
|
|
82
|
|
83 /* Convert any 8-bit data to a string, for compactness. */
|
|
84 else if (format == 8)
|
|
85 return make_ext_string ((Extbyte *) data, size,
|
|
86 type == DEVICE_XATOM_TEXT (d) ||
|
|
87 type == DEVICE_XATOM_COMPOUND_TEXT (d)
|
|
88 ? Qctext : Qbinary);
|
|
89
|
|
90 /* Convert a single atom to a Lisp Symbol.
|
|
91 Convert a set of atoms to a vector of symbols. */
|
|
92 else if (type == XA_ATOM)
|
|
93 #else
|
|
94 if (type == gdk_atom_intern ("NULL", 0))
|
|
95 return QNULL;
|
|
96
|
|
97 /* Convert any 8-bit data to a string, for compactness. */
|
|
98 else if (format == 8)
|
|
99 return make_ext_string ((Extbyte *) data, size,
|
|
100 ((type == gdk_atom_intern ("TEXT", FALSE)) ||
|
|
101 (type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)))
|
|
102 ? Qctext : Qbinary);
|
|
103
|
|
104 /* Convert a single atom to a Lisp Symbol.
|
|
105 Convert a set of atoms to a vector of symbols. */
|
|
106 else if (type == gdk_atom_intern ("ATOM", FALSE))
|
|
107 #endif /* PROCESSING_X_CODE */
|
|
108 {
|
|
109 if (size == sizeof (XE_ATOM_TYPE))
|
|
110 return XE_ATOM_TO_SYMBOL (d, *((XE_ATOM_TYPE *) data));
|
|
111 else
|
|
112 {
|
665
|
113 Elemcount i;
|
|
114 Elemcount len = size / sizeof (XE_ATOM_TYPE);
|
647
|
115 Lisp_Object v = Fmake_vector (make_int (len), Qzero);
|
|
116 for (i = 0; i < len; i++)
|
|
117 Faset (v, make_int (i), XE_ATOM_TO_SYMBOL (d, ((XE_ATOM_TYPE *) data) [i]));
|
|
118 return v;
|
|
119 }
|
|
120 }
|
|
121
|
|
122 /* Convert a single 16 or small 32 bit number to a Lisp Int.
|
|
123 If the number is > 16 bits, convert it to a cons of integers,
|
|
124 16 bits in each half.
|
|
125 */
|
|
126 else if (format == 32 && size == sizeof (long))
|
|
127 return word_to_lisp (((unsigned long *) data) [0]);
|
|
128 else if (format == 16 && size == sizeof (short))
|
|
129 return make_int ((int) (((unsigned short *) data) [0]));
|
|
130
|
|
131 /* Convert any other kind of data to a vector of numbers, represented
|
|
132 as above (as an integer, or a cons of two 16 bit integers).
|
|
133
|
|
134 #### Perhaps we should return the actual type to lisp as well.
|
|
135
|
|
136 (x-get-selection-internal 'PRIMARY 'LINE_NUMBER)
|
|
137 ==> [4 4]
|
|
138
|
|
139 and perhaps it should be
|
|
140
|
|
141 (x-get-selection-internal 'PRIMARY 'LINE_NUMBER)
|
|
142 ==> (SPAN . [4 4])
|
|
143
|
|
144 Right now the fact that the return type was SPAN is discarded before
|
|
145 lisp code gets to see it.
|
|
146 */
|
|
147 else if (format == 16)
|
|
148 {
|
665
|
149 Elemcount i;
|
647
|
150 Lisp_Object v = make_vector (size / 4, Qzero);
|
|
151 for (i = 0; i < size / 4; i++)
|
|
152 {
|
|
153 int j = (int) ((unsigned short *) data) [i];
|
|
154 Faset (v, make_int (i), make_int (j));
|
|
155 }
|
|
156 return v;
|
|
157 }
|
|
158 else
|
|
159 {
|
665
|
160 Elemcount i;
|
647
|
161 Lisp_Object v = make_vector (size / 4, Qzero);
|
|
162 for (i = 0; i < size / 4; i++)
|
|
163 {
|
|
164 unsigned long j = ((unsigned long *) data) [i];
|
|
165 Faset (v, make_int (i), word_to_lisp (j));
|
|
166 }
|
|
167 return v;
|
|
168 }
|
|
169 }
|
|
170
|
|
171
|
|
172 static void
|
|
173 lisp_data_to_selection_data (struct device *d,
|
|
174 Lisp_Object obj,
|
2367
|
175 Rawbyte **data_ret,
|
647
|
176 XE_ATOM_TYPE *type_ret,
|
665
|
177 Bytecount *size_ret,
|
647
|
178 int *format_ret)
|
|
179 {
|
|
180 Lisp_Object type = Qnil;
|
|
181
|
|
182 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
|
|
183 {
|
|
184 type = XCAR (obj);
|
|
185 obj = XCDR (obj);
|
|
186 if (CONSP (obj) && NILP (XCDR (obj)))
|
|
187 obj = XCAR (obj);
|
|
188 }
|
|
189
|
|
190 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
|
|
191 { /* This is not the same as declining */
|
|
192 *format_ret = 32;
|
|
193 *size_ret = 0;
|
|
194 *data_ret = 0;
|
|
195 type = QNULL;
|
|
196 }
|
|
197 else if (STRINGP (obj))
|
|
198 {
|
|
199 const Extbyte *extval;
|
665
|
200 Bytecount extvallen;
|
647
|
201
|
|
202 TO_EXTERNAL_FORMAT (LISP_STRING, obj,
|
|
203 ALLOCA, (extval, extvallen),
|
|
204 (NILP (type) ? Qctext : Qbinary));
|
|
205 *format_ret = 8;
|
|
206 *size_ret = extvallen;
|
2367
|
207 *data_ret = xnew_rawbytes (*size_ret);
|
647
|
208 memcpy (*data_ret, extval, *size_ret);
|
|
209 #ifdef MULE
|
|
210 if (NILP (type)) type = QCOMPOUND_TEXT;
|
|
211 #else
|
|
212 if (NILP (type)) type = QSTRING;
|
|
213 #endif
|
|
214 }
|
|
215 else if (CHARP (obj))
|
|
216 {
|
867
|
217 Ibyte buf[MAX_ICHAR_LEN];
|
647
|
218 Bytecount len;
|
|
219 const Extbyte *extval;
|
665
|
220 Bytecount extvallen;
|
647
|
221
|
|
222 *format_ret = 8;
|
867
|
223 len = set_itext_ichar (buf, XCHAR (obj));
|
647
|
224 TO_EXTERNAL_FORMAT (DATA, (buf, len),
|
|
225 ALLOCA, (extval, extvallen),
|
|
226 Qctext);
|
|
227 *size_ret = extvallen;
|
2367
|
228 *data_ret = xnew_rawbytes (*size_ret);
|
647
|
229 memcpy (*data_ret, extval, *size_ret);
|
|
230 #ifdef MULE
|
|
231 if (NILP (type)) type = QCOMPOUND_TEXT;
|
|
232 #else
|
|
233 if (NILP (type)) type = QSTRING;
|
|
234 #endif
|
|
235 }
|
|
236 else if (SYMBOLP (obj))
|
|
237 {
|
|
238 *format_ret = 32;
|
|
239 *size_ret = 1;
|
2367
|
240 *data_ret = xnew_rawbytes (sizeof (XE_ATOM_TYPE) + 1);
|
647
|
241 (*data_ret) [sizeof (XE_ATOM_TYPE)] = 0;
|
|
242 (*(XE_ATOM_TYPE **) data_ret) [0] = XE_SYMBOL_TO_ATOM (d, obj, 0);
|
|
243 if (NILP (type)) type = QATOM;
|
|
244 }
|
|
245 else if (INTP (obj) &&
|
|
246 XINT (obj) <= 0x7FFF &&
|
|
247 XINT (obj) >= -0x8000)
|
|
248 {
|
|
249 *format_ret = 16;
|
|
250 *size_ret = 1;
|
2367
|
251 *data_ret = xnew_rawbytes (sizeof (short) + 1);
|
647
|
252 (*data_ret) [sizeof (short)] = 0;
|
|
253 (*(short **) data_ret) [0] = (short) XINT (obj);
|
|
254 if (NILP (type)) type = QINTEGER;
|
|
255 }
|
|
256 else if (INTP (obj) || CONSP (obj))
|
|
257 {
|
|
258 *format_ret = 32;
|
|
259 *size_ret = 1;
|
2367
|
260 *data_ret = xnew_rawbytes (sizeof (long) + 1);
|
647
|
261 (*data_ret) [sizeof (long)] = 0;
|
|
262 (*(unsigned long **) data_ret) [0] = lisp_to_word (obj);
|
|
263 if (NILP (type)) type = QINTEGER;
|
|
264 }
|
|
265 else if (VECTORP (obj))
|
|
266 {
|
|
267 /* Lisp Vectors may represent a set of ATOMs;
|
|
268 a set of 16 or 32 bit INTEGERs;
|
|
269 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
|
|
270 */
|
665
|
271 Elemcount i;
|
647
|
272
|
|
273 if (SYMBOLP (XVECTOR_DATA (obj) [0]))
|
|
274 /* This vector is an ATOM set */
|
|
275 {
|
|
276 if (NILP (type)) type = QATOM;
|
|
277 *size_ret = XVECTOR_LENGTH (obj);
|
|
278 *format_ret = 32;
|
2367
|
279 *data_ret = xnew_rawbytes ((*size_ret) * sizeof (XE_ATOM_TYPE));
|
647
|
280 for (i = 0; i < *size_ret; i++)
|
|
281 if (SYMBOLP (XVECTOR_DATA (obj) [i]))
|
|
282 (*(XE_ATOM_TYPE **) data_ret) [i] =
|
|
283 XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (obj) [i], 0);
|
|
284 else
|
|
285 syntax_error
|
|
286 ("all elements of the vector must be of the same type", obj);
|
|
287 }
|
|
288 #if 0 /* #### MULTIPLE doesn't work yet */
|
|
289 else if (VECTORP (XVECTOR_DATA (obj) [0]))
|
|
290 /* This vector is an ATOM_PAIR set */
|
|
291 {
|
|
292 if (NILP (type)) type = QATOM_PAIR;
|
|
293 *size_ret = XVECTOR_LENGTH (obj);
|
|
294 *format_ret = 32;
|
2367
|
295 *data_ret =
|
|
296 xnew_rawbytes ((*size_ret) * sizeof (XE_ATOM_TYPE) * 2);
|
647
|
297 for (i = 0; i < *size_ret; i++)
|
|
298 if (VECTORP (XVECTOR_DATA (obj) [i]))
|
|
299 {
|
|
300 Lisp_Object pair = XVECTOR_DATA (obj) [i];
|
|
301 if (XVECTOR_LENGTH (pair) != 2)
|
|
302 syntax_error
|
|
303 ("elements of the vector must be vectors of exactly two elements", pair);
|
|
304
|
|
305 (*(XE_ATOM_TYPE **) data_ret) [i * 2] =
|
|
306 XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (pair) [0], 0);
|
|
307 (*(XE_ATOM_TYPE **) data_ret) [(i * 2) + 1] =
|
|
308 XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (pair) [1], 0);
|
|
309 }
|
|
310 else
|
|
311 syntax_error
|
|
312 ("all elements of the vector must be of the same type", obj);
|
|
313 }
|
|
314 #endif
|
|
315 else
|
|
316 /* This vector is an INTEGER set, or something like it */
|
|
317 {
|
|
318 *size_ret = XVECTOR_LENGTH (obj);
|
|
319 if (NILP (type)) type = QINTEGER;
|
|
320 *format_ret = 16;
|
|
321 for (i = 0; i < *size_ret; i++)
|
|
322 if (CONSP (XVECTOR_DATA (obj) [i]))
|
|
323 *format_ret = 32;
|
|
324 else if (!INTP (XVECTOR_DATA (obj) [i]))
|
|
325 syntax_error
|
|
326 ("all elements of the vector must be integers or conses of integers", obj);
|
|
327
|
2367
|
328 *data_ret = xnew_rawbytes (*size_ret * (*format_ret/8));
|
647
|
329 for (i = 0; i < *size_ret; i++)
|
|
330 if (*format_ret == 32)
|
|
331 (*((unsigned long **) data_ret)) [i] =
|
|
332 lisp_to_word (XVECTOR_DATA (obj) [i]);
|
|
333 else
|
|
334 (*((unsigned short **) data_ret)) [i] =
|
|
335 (unsigned short) lisp_to_word (XVECTOR_DATA (obj) [i]);
|
|
336 }
|
|
337 }
|
|
338 else
|
|
339 invalid_argument ("unrecognized selection data", obj);
|
|
340
|
|
341 *type_ret = XE_SYMBOL_TO_ATOM (d, type, 0);
|
|
342 }
|
|
343
|