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
|
|
50 When converting a Lisp number to C, it is assumed to be of format 16 if
|
|
51 it is an integer, and of format 32 if it is a cons of two integers.
|
|
52
|
|
53 When converting a vector of numbers from Elisp to C, it is assumed to be
|
|
54 of format 16 if every element in the vector is an integer, and is assumed
|
|
55 to be of format 32 if any element is a cons of two integers.
|
|
56
|
|
57 When converting an object to C, it may be of the form (SYMBOL . <data>)
|
|
58 where SYMBOL is what we should claim that the type is. Format and
|
|
59 representation are as above.
|
|
60
|
|
61 NOTE: Under Mule, when someone shoves us a string without a type, we
|
|
62 set the type to 'COMPOUND_TEXT and automatically convert to Compound
|
|
63 Text. If the string has a type, we assume that the user wants the
|
|
64 data sent as-is so we just do "binary" conversion.
|
|
65 */
|
|
66
|
|
67
|
|
68 static Lisp_Object
|
|
69 selection_data_to_lisp_data (struct device *d,
|
2367
|
70 Rawbyte *data,
|
665
|
71 Bytecount size,
|
647
|
72 XE_ATOM_TYPE type,
|
|
73 int format)
|
|
74 {
|
|
75 #ifdef PROCESSING_X_CODE
|
|
76 if (type == DEVICE_XATOM_NULL (d))
|
|
77 return QNULL;
|
|
78
|
|
79 /* Convert any 8-bit data to a string, for compactness. */
|
|
80 else if (format == 8)
|
|
81 return make_ext_string ((Extbyte *) data, size,
|
|
82 type == DEVICE_XATOM_TEXT (d) ||
|
|
83 type == DEVICE_XATOM_COMPOUND_TEXT (d)
|
|
84 ? Qctext : Qbinary);
|
|
85
|
|
86 /* Convert a single atom to a Lisp Symbol.
|
|
87 Convert a set of atoms to a vector of symbols. */
|
|
88 else if (type == XA_ATOM)
|
|
89 #else
|
|
90 if (type == gdk_atom_intern ("NULL", 0))
|
|
91 return QNULL;
|
|
92
|
|
93 /* Convert any 8-bit data to a string, for compactness. */
|
|
94 else if (format == 8)
|
|
95 return make_ext_string ((Extbyte *) data, size,
|
|
96 ((type == gdk_atom_intern ("TEXT", FALSE)) ||
|
|
97 (type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)))
|
|
98 ? Qctext : Qbinary);
|
|
99
|
|
100 /* Convert a single atom to a Lisp Symbol.
|
|
101 Convert a set of atoms to a vector of symbols. */
|
|
102 else if (type == gdk_atom_intern ("ATOM", FALSE))
|
|
103 #endif /* PROCESSING_X_CODE */
|
|
104 {
|
|
105 if (size == sizeof (XE_ATOM_TYPE))
|
|
106 return XE_ATOM_TO_SYMBOL (d, *((XE_ATOM_TYPE *) data));
|
|
107 else
|
|
108 {
|
665
|
109 Elemcount i;
|
|
110 Elemcount len = size / sizeof (XE_ATOM_TYPE);
|
647
|
111 Lisp_Object v = Fmake_vector (make_int (len), Qzero);
|
|
112 for (i = 0; i < len; i++)
|
|
113 Faset (v, make_int (i), XE_ATOM_TO_SYMBOL (d, ((XE_ATOM_TYPE *) data) [i]));
|
|
114 return v;
|
|
115 }
|
|
116 }
|
|
117
|
|
118 /* Convert a single 16 or small 32 bit number to a Lisp Int.
|
|
119 If the number is > 16 bits, convert it to a cons of integers,
|
|
120 16 bits in each half.
|
|
121 */
|
|
122 else if (format == 32 && size == sizeof (long))
|
|
123 return word_to_lisp (((unsigned long *) data) [0]);
|
|
124 else if (format == 16 && size == sizeof (short))
|
|
125 return make_int ((int) (((unsigned short *) data) [0]));
|
|
126
|
|
127 /* Convert any other kind of data to a vector of numbers, represented
|
|
128 as above (as an integer, or a cons of two 16 bit integers).
|
|
129
|
|
130 #### Perhaps we should return the actual type to lisp as well.
|
|
131
|
|
132 (x-get-selection-internal 'PRIMARY 'LINE_NUMBER)
|
|
133 ==> [4 4]
|
|
134
|
|
135 and perhaps it should be
|
|
136
|
|
137 (x-get-selection-internal 'PRIMARY 'LINE_NUMBER)
|
|
138 ==> (SPAN . [4 4])
|
|
139
|
|
140 Right now the fact that the return type was SPAN is discarded before
|
|
141 lisp code gets to see it.
|
|
142 */
|
|
143 else if (format == 16)
|
|
144 {
|
665
|
145 Elemcount i;
|
647
|
146 Lisp_Object v = make_vector (size / 4, Qzero);
|
|
147 for (i = 0; i < size / 4; i++)
|
|
148 {
|
|
149 int j = (int) ((unsigned short *) data) [i];
|
|
150 Faset (v, make_int (i), make_int (j));
|
|
151 }
|
|
152 return v;
|
|
153 }
|
|
154 else
|
|
155 {
|
665
|
156 Elemcount i;
|
647
|
157 Lisp_Object v = make_vector (size / 4, Qzero);
|
|
158 for (i = 0; i < size / 4; i++)
|
|
159 {
|
|
160 unsigned long j = ((unsigned long *) data) [i];
|
|
161 Faset (v, make_int (i), word_to_lisp (j));
|
|
162 }
|
|
163 return v;
|
|
164 }
|
|
165 }
|
|
166
|
|
167
|
|
168 static void
|
|
169 lisp_data_to_selection_data (struct device *d,
|
|
170 Lisp_Object obj,
|
2367
|
171 Rawbyte **data_ret,
|
647
|
172 XE_ATOM_TYPE *type_ret,
|
665
|
173 Bytecount *size_ret,
|
647
|
174 int *format_ret)
|
|
175 {
|
|
176 Lisp_Object type = Qnil;
|
|
177
|
|
178 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
|
|
179 {
|
|
180 type = XCAR (obj);
|
|
181 obj = XCDR (obj);
|
|
182 if (CONSP (obj) && NILP (XCDR (obj)))
|
|
183 obj = XCAR (obj);
|
|
184 }
|
|
185
|
|
186 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
|
|
187 { /* This is not the same as declining */
|
|
188 *format_ret = 32;
|
|
189 *size_ret = 0;
|
|
190 *data_ret = 0;
|
|
191 type = QNULL;
|
|
192 }
|
|
193 else if (STRINGP (obj))
|
|
194 {
|
|
195 const Extbyte *extval;
|
665
|
196 Bytecount extvallen;
|
647
|
197
|
|
198 TO_EXTERNAL_FORMAT (LISP_STRING, obj,
|
|
199 ALLOCA, (extval, extvallen),
|
|
200 (NILP (type) ? Qctext : Qbinary));
|
|
201 *format_ret = 8;
|
|
202 *size_ret = extvallen;
|
2367
|
203 *data_ret = xnew_rawbytes (*size_ret);
|
647
|
204 memcpy (*data_ret, extval, *size_ret);
|
|
205 #ifdef MULE
|
|
206 if (NILP (type)) type = QCOMPOUND_TEXT;
|
|
207 #else
|
|
208 if (NILP (type)) type = QSTRING;
|
|
209 #endif
|
|
210 }
|
|
211 else if (CHARP (obj))
|
|
212 {
|
867
|
213 Ibyte buf[MAX_ICHAR_LEN];
|
647
|
214 Bytecount len;
|
|
215 const Extbyte *extval;
|
665
|
216 Bytecount extvallen;
|
647
|
217
|
|
218 *format_ret = 8;
|
867
|
219 len = set_itext_ichar (buf, XCHAR (obj));
|
647
|
220 TO_EXTERNAL_FORMAT (DATA, (buf, len),
|
|
221 ALLOCA, (extval, extvallen),
|
|
222 Qctext);
|
|
223 *size_ret = extvallen;
|
2367
|
224 *data_ret = xnew_rawbytes (*size_ret);
|
647
|
225 memcpy (*data_ret, extval, *size_ret);
|
|
226 #ifdef MULE
|
|
227 if (NILP (type)) type = QCOMPOUND_TEXT;
|
|
228 #else
|
|
229 if (NILP (type)) type = QSTRING;
|
|
230 #endif
|
|
231 }
|
|
232 else if (SYMBOLP (obj))
|
|
233 {
|
|
234 *format_ret = 32;
|
|
235 *size_ret = 1;
|
2367
|
236 *data_ret = xnew_rawbytes (sizeof (XE_ATOM_TYPE) + 1);
|
647
|
237 (*data_ret) [sizeof (XE_ATOM_TYPE)] = 0;
|
|
238 (*(XE_ATOM_TYPE **) data_ret) [0] = XE_SYMBOL_TO_ATOM (d, obj, 0);
|
|
239 if (NILP (type)) type = QATOM;
|
|
240 }
|
|
241 else if (INTP (obj) &&
|
|
242 XINT (obj) <= 0x7FFF &&
|
|
243 XINT (obj) >= -0x8000)
|
|
244 {
|
|
245 *format_ret = 16;
|
|
246 *size_ret = 1;
|
2367
|
247 *data_ret = xnew_rawbytes (sizeof (short) + 1);
|
647
|
248 (*data_ret) [sizeof (short)] = 0;
|
|
249 (*(short **) data_ret) [0] = (short) XINT (obj);
|
|
250 if (NILP (type)) type = QINTEGER;
|
|
251 }
|
|
252 else if (INTP (obj) || CONSP (obj))
|
|
253 {
|
|
254 *format_ret = 32;
|
|
255 *size_ret = 1;
|
2367
|
256 *data_ret = xnew_rawbytes (sizeof (long) + 1);
|
647
|
257 (*data_ret) [sizeof (long)] = 0;
|
|
258 (*(unsigned long **) data_ret) [0] = lisp_to_word (obj);
|
|
259 if (NILP (type)) type = QINTEGER;
|
|
260 }
|
|
261 else if (VECTORP (obj))
|
|
262 {
|
|
263 /* Lisp Vectors may represent a set of ATOMs;
|
|
264 a set of 16 or 32 bit INTEGERs;
|
|
265 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
|
|
266 */
|
665
|
267 Elemcount i;
|
647
|
268
|
|
269 if (SYMBOLP (XVECTOR_DATA (obj) [0]))
|
|
270 /* This vector is an ATOM set */
|
|
271 {
|
|
272 if (NILP (type)) type = QATOM;
|
|
273 *size_ret = XVECTOR_LENGTH (obj);
|
|
274 *format_ret = 32;
|
2367
|
275 *data_ret = xnew_rawbytes ((*size_ret) * sizeof (XE_ATOM_TYPE));
|
647
|
276 for (i = 0; i < *size_ret; i++)
|
|
277 if (SYMBOLP (XVECTOR_DATA (obj) [i]))
|
|
278 (*(XE_ATOM_TYPE **) data_ret) [i] =
|
|
279 XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (obj) [i], 0);
|
|
280 else
|
|
281 syntax_error
|
|
282 ("all elements of the vector must be of the same type", obj);
|
|
283 }
|
|
284 #if 0 /* #### MULTIPLE doesn't work yet */
|
|
285 else if (VECTORP (XVECTOR_DATA (obj) [0]))
|
|
286 /* This vector is an ATOM_PAIR set */
|
|
287 {
|
|
288 if (NILP (type)) type = QATOM_PAIR;
|
|
289 *size_ret = XVECTOR_LENGTH (obj);
|
|
290 *format_ret = 32;
|
2367
|
291 *data_ret =
|
|
292 xnew_rawbytes ((*size_ret) * sizeof (XE_ATOM_TYPE) * 2);
|
647
|
293 for (i = 0; i < *size_ret; i++)
|
|
294 if (VECTORP (XVECTOR_DATA (obj) [i]))
|
|
295 {
|
|
296 Lisp_Object pair = XVECTOR_DATA (obj) [i];
|
|
297 if (XVECTOR_LENGTH (pair) != 2)
|
|
298 syntax_error
|
|
299 ("elements of the vector must be vectors of exactly two elements", pair);
|
|
300
|
|
301 (*(XE_ATOM_TYPE **) data_ret) [i * 2] =
|
|
302 XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (pair) [0], 0);
|
|
303 (*(XE_ATOM_TYPE **) data_ret) [(i * 2) + 1] =
|
|
304 XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (pair) [1], 0);
|
|
305 }
|
|
306 else
|
|
307 syntax_error
|
|
308 ("all elements of the vector must be of the same type", obj);
|
|
309 }
|
|
310 #endif
|
|
311 else
|
|
312 /* This vector is an INTEGER set, or something like it */
|
|
313 {
|
|
314 *size_ret = XVECTOR_LENGTH (obj);
|
|
315 if (NILP (type)) type = QINTEGER;
|
|
316 *format_ret = 16;
|
|
317 for (i = 0; i < *size_ret; i++)
|
|
318 if (CONSP (XVECTOR_DATA (obj) [i]))
|
|
319 *format_ret = 32;
|
|
320 else if (!INTP (XVECTOR_DATA (obj) [i]))
|
|
321 syntax_error
|
|
322 ("all elements of the vector must be integers or conses of integers", obj);
|
|
323
|
2367
|
324 *data_ret = xnew_rawbytes (*size_ret * (*format_ret/8));
|
647
|
325 for (i = 0; i < *size_ret; i++)
|
|
326 if (*format_ret == 32)
|
|
327 (*((unsigned long **) data_ret)) [i] =
|
|
328 lisp_to_word (XVECTOR_DATA (obj) [i]);
|
|
329 else
|
|
330 (*((unsigned short **) data_ret)) [i] =
|
|
331 (unsigned short) lisp_to_word (XVECTOR_DATA (obj) [i]);
|
|
332 }
|
|
333 }
|
|
334 else
|
|
335 invalid_argument ("unrecognized selection data", obj);
|
|
336
|
|
337 *type_ret = XE_SYMBOL_TO_ATOM (d, type, 0);
|
|
338 }
|
|
339
|