Mercurial > hg > xemacs-beta
comparison src/xselect.c @ 173:8eaf7971accc r20-3b13
Import from CVS: tag r20-3b13
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:49:09 +0200 |
parents | 15872534500d |
children | 2d532a89d707 |
comparison
equal
deleted
inserted
replaced
172:a38aed19690b | 173:8eaf7971accc |
---|---|
66 Lisp_Object Vx_sent_selection_hooks; | 66 Lisp_Object Vx_sent_selection_hooks; |
67 | 67 |
68 /* If this is a smaller number than the max-request-size of the display, | 68 /* If this is a smaller number than the max-request-size of the display, |
69 emacs will use INCR selection transfer when the selection is larger | 69 emacs will use INCR selection transfer when the selection is larger |
70 than this. The max-request-size is usually around 64k, so if you want | 70 than this. The max-request-size is usually around 64k, so if you want |
71 emacs to use incremental selection transfers when the selection is | 71 emacs to use incremental selection transfers when the selection is |
72 smaller than that, set this. I added this mostly for debugging the | 72 smaller than that, set this. I added this mostly for debugging the |
73 incremental transfer stuff, but it might improve server performance. | 73 incremental transfer stuff, but it might improve server performance. |
74 */ | 74 */ |
75 #define MAX_SELECTION_QUANTUM 0xFFFFFF | 75 #define MAX_SELECTION_QUANTUM 0xFFFFFF |
76 | 76 |
90 */ | 90 */ |
91 Lisp_Object Vselection_alist; | 91 Lisp_Object Vselection_alist; |
92 | 92 |
93 /* This is an alist whose CARs are selection-types (whose names are the same | 93 /* This is an alist whose CARs are selection-types (whose names are the same |
94 as the names of X Atoms) and whose CDRs are the names of Lisp functions to | 94 as the names of X Atoms) and whose CDRs are the names of Lisp functions to |
95 call to convert the given Emacs selection value to a string representing | 95 call to convert the given Emacs selection value to a string representing |
96 the given selection type. This is for elisp-level extension of the emacs | 96 the given selection type. This is for elisp-level extension of the emacs |
97 selection handling. | 97 selection handling. |
98 */ | 98 */ |
99 Lisp_Object Vselection_converter_alist; | 99 Lisp_Object Vselection_converter_alist; |
100 | |
101 /* "Selection owner couldn't convert selection" */ | |
102 Lisp_Object Qselection_conversion_error; | |
100 | 103 |
101 /* If the selection owner takes too long to reply to a selection request, | 104 /* If the selection owner takes too long to reply to a selection request, |
102 we give up on it. This is in seconds (0 = no timeout). | 105 we give up on it. This is in seconds (0 = no timeout). |
103 */ | 106 */ |
104 int x_selection_timeout; | 107 int x_selection_timeout; |
126 static int expect_property_change (Display *, Window, Atom prop, int state); | 129 static int expect_property_change (Display *, Window, Atom prop, int state); |
127 static void wait_for_property_change (long); | 130 static void wait_for_property_change (long); |
128 static void unexpect_property_change (int); | 131 static void unexpect_property_change (int); |
129 static int waiting_for_other_props_on_window (Display *, Window); | 132 static int waiting_for_other_props_on_window (Display *, Window); |
130 | 133 |
131 /* This converts a Lisp symbol to a server Atom, avoiding a server | 134 /* This converts a Lisp symbol to a server Atom, avoiding a server |
132 roundtrip whenever possible. | 135 roundtrip whenever possible. |
133 */ | 136 */ |
134 Atom | 137 Atom |
135 symbol_to_x_atom (struct device *d, Lisp_Object sym, int only_if_exists) | 138 symbol_to_x_atom (struct device *d, Lisp_Object sym, int only_if_exists) |
136 { | 139 { |
137 Display *display = DEVICE_X_DISPLAY (d); | 140 Display *display = DEVICE_X_DISPLAY (d); |
138 Atom val; | 141 |
139 if (NILP (sym)) return XA_PRIMARY; | 142 if (NILP (sym)) return XA_PRIMARY; |
140 if (EQ (sym, Qt)) return XA_SECONDARY; | 143 if (EQ (sym, Qt)) return XA_SECONDARY; |
141 if (EQ (sym, QPRIMARY)) return XA_PRIMARY; | 144 if (EQ (sym, QPRIMARY)) return XA_PRIMARY; |
142 if (EQ (sym, QSECONDARY)) return XA_SECONDARY; | 145 if (EQ (sym, QSECONDARY)) return XA_SECONDARY; |
143 if (EQ (sym, QSTRING)) return XA_STRING; | 146 if (EQ (sym, QSTRING)) return XA_STRING; |
144 if (EQ (sym, QINTEGER)) return XA_INTEGER; | 147 if (EQ (sym, QINTEGER)) return XA_INTEGER; |
145 if (EQ (sym, QATOM)) return XA_ATOM; | 148 if (EQ (sym, QATOM)) return XA_ATOM; |
146 if (EQ (sym, QCLIPBOARD)) return DEVICE_XATOM_CLIPBOARD (d); | 149 if (EQ (sym, QCLIPBOARD)) return DEVICE_XATOM_CLIPBOARD (d); |
147 if (EQ (sym, QTIMESTAMP)) return DEVICE_XATOM_TIMESTAMP (d); | 150 if (EQ (sym, QTIMESTAMP)) return DEVICE_XATOM_TIMESTAMP (d); |
148 if (EQ (sym, QTEXT)) return DEVICE_XATOM_TEXT (d); | 151 if (EQ (sym, QTEXT)) return DEVICE_XATOM_TEXT (d); |
149 if (EQ (sym, QDELETE)) return DEVICE_XATOM_DELETE (d); | 152 if (EQ (sym, QDELETE)) return DEVICE_XATOM_DELETE (d); |
150 if (EQ (sym, QMULTIPLE)) return DEVICE_XATOM_MULTIPLE (d); | 153 if (EQ (sym, QMULTIPLE)) return DEVICE_XATOM_MULTIPLE (d); |
151 if (EQ (sym, QINCR)) return DEVICE_XATOM_INCR (d); | 154 if (EQ (sym, QINCR)) return DEVICE_XATOM_INCR (d); |
152 if (EQ (sym, QEMACS_TMP)) return DEVICE_XATOM_EMACS_TMP (d); | 155 if (EQ (sym, QEMACS_TMP)) return DEVICE_XATOM_EMACS_TMP (d); |
153 if (EQ (sym, QTARGETS)) return DEVICE_XATOM_TARGETS (d); | 156 if (EQ (sym, QTARGETS)) return DEVICE_XATOM_TARGETS (d); |
154 if (EQ (sym, QNULL)) return DEVICE_XATOM_NULL (d); | 157 if (EQ (sym, QNULL)) return DEVICE_XATOM_NULL (d); |
155 if (EQ (sym, QATOM_PAIR)) return DEVICE_XATOM_ATOM_PAIR (d); | 158 if (EQ (sym, QATOM_PAIR)) return DEVICE_XATOM_ATOM_PAIR (d); |
156 if (EQ (sym, QCOMPOUND_TEXT)) return DEVICE_XATOM_COMPOUND_TEXT (d); | 159 if (EQ (sym, QCOMPOUND_TEXT)) return DEVICE_XATOM_COMPOUND_TEXT (d); |
157 #ifdef EPOCH | 160 #ifdef EPOCH |
158 if (EQ (sym, QARC)) return XA_ARC; | 161 if (EQ (sym, QARC)) return XA_ARC; |
159 if (EQ (sym, QBITMAP)) return XA_BITMAP; | 162 if (EQ (sym, QBITMAP)) return XA_BITMAP; |
177 if (EQ (sym, QCUT_BUFFER3)) return XA_CUT_BUFFER3; | 180 if (EQ (sym, QCUT_BUFFER3)) return XA_CUT_BUFFER3; |
178 if (EQ (sym, QCUT_BUFFER4)) return XA_CUT_BUFFER4; | 181 if (EQ (sym, QCUT_BUFFER4)) return XA_CUT_BUFFER4; |
179 if (EQ (sym, QCUT_BUFFER5)) return XA_CUT_BUFFER5; | 182 if (EQ (sym, QCUT_BUFFER5)) return XA_CUT_BUFFER5; |
180 if (EQ (sym, QCUT_BUFFER6)) return XA_CUT_BUFFER6; | 183 if (EQ (sym, QCUT_BUFFER6)) return XA_CUT_BUFFER6; |
181 if (EQ (sym, QCUT_BUFFER7)) return XA_CUT_BUFFER7; | 184 if (EQ (sym, QCUT_BUFFER7)) return XA_CUT_BUFFER7; |
182 #endif | 185 #endif /* CUT_BUFFER_SUPPORT */ |
186 | |
183 { | 187 { |
184 CONST char *nameext; | 188 CONST char *nameext; |
185 Lisp_Object namesym; | 189 Lisp_Object namesym; |
186 XSETSTRING (namesym, XSYMBOL (sym)->name); | 190 XSETSTRING (namesym, XSYMBOL (sym)->name); |
187 GET_C_STRING_CTEXT_DATA_ALLOCA (namesym, nameext); | 191 GET_C_STRING_CTEXT_DATA_ALLOCA (namesym, nameext); |
188 val = XInternAtom (display, nameext, only_if_exists ? True : False); | 192 return XInternAtom (display, nameext, only_if_exists ? True : False); |
189 } | 193 } |
190 return val; | |
191 } | 194 } |
192 | 195 |
193 | 196 |
194 /* This converts a server Atom to a Lisp symbol, avoiding server roundtrips | 197 /* This converts a server Atom to a Lisp symbol, avoiding server roundtrips |
195 and calls to intern whenever possible. | 198 and calls to intern whenever possible. |
196 */ | 199 */ |
197 Lisp_Object | 200 Lisp_Object |
198 x_atom_to_symbol (struct device *d, Atom atom) | 201 x_atom_to_symbol (struct device *d, Atom atom) |
199 { | 202 { |
200 char *str; | |
201 Display *display = DEVICE_X_DISPLAY (d); | 203 Display *display = DEVICE_X_DISPLAY (d); |
202 | 204 |
203 if (! atom) return Qnil; | 205 if (! atom) return Qnil; |
204 if (atom == XA_PRIMARY) return QPRIMARY; | 206 if (atom == XA_PRIMARY) return QPRIMARY; |
205 if (atom == XA_SECONDARY) return QSECONDARY; | 207 if (atom == XA_SECONDARY) return QSECONDARY; |
206 if (atom == XA_STRING) return QSTRING; | 208 if (atom == XA_STRING) return QSTRING; |
207 if (atom == XA_INTEGER) return QINTEGER; | 209 if (atom == XA_INTEGER) return QINTEGER; |
208 if (atom == XA_ATOM) return QATOM; | 210 if (atom == XA_ATOM) return QATOM; |
209 if (atom == DEVICE_XATOM_CLIPBOARD (d)) return QCLIPBOARD; | 211 if (atom == DEVICE_XATOM_CLIPBOARD (d)) return QCLIPBOARD; |
210 if (atom == DEVICE_XATOM_TIMESTAMP (d)) return QTIMESTAMP; | 212 if (atom == DEVICE_XATOM_TIMESTAMP (d)) return QTIMESTAMP; |
211 if (atom == DEVICE_XATOM_TEXT (d)) return QTEXT; | 213 if (atom == DEVICE_XATOM_TEXT (d)) return QTEXT; |
212 if (atom == DEVICE_XATOM_DELETE (d)) return QDELETE; | 214 if (atom == DEVICE_XATOM_DELETE (d)) return QDELETE; |
213 if (atom == DEVICE_XATOM_MULTIPLE (d)) return QMULTIPLE; | 215 if (atom == DEVICE_XATOM_MULTIPLE (d)) return QMULTIPLE; |
214 if (atom == DEVICE_XATOM_INCR (d)) return QINCR; | 216 if (atom == DEVICE_XATOM_INCR (d)) return QINCR; |
215 if (atom == DEVICE_XATOM_EMACS_TMP (d)) return QEMACS_TMP; | 217 if (atom == DEVICE_XATOM_EMACS_TMP (d)) return QEMACS_TMP; |
216 if (atom == DEVICE_XATOM_TARGETS (d)) return QTARGETS; | 218 if (atom == DEVICE_XATOM_TARGETS (d)) return QTARGETS; |
217 if (atom == DEVICE_XATOM_NULL (d)) return QNULL; | 219 if (atom == DEVICE_XATOM_NULL (d)) return QNULL; |
218 if (atom == DEVICE_XATOM_ATOM_PAIR (d)) return QATOM_PAIR; | 220 if (atom == DEVICE_XATOM_ATOM_PAIR (d)) return QATOM_PAIR; |
219 if (atom == DEVICE_XATOM_COMPOUND_TEXT (d)) return QCOMPOUND_TEXT; | 221 if (atom == DEVICE_XATOM_COMPOUND_TEXT (d)) return QCOMPOUND_TEXT; |
220 | 222 |
221 #ifdef EPOCH | 223 #ifdef EPOCH |
222 if (atom == XA_ARC) return QARC; | 224 if (atom == XA_ARC) return QARC; |
242 if (atom == XA_CUT_BUFFER5) return QCUT_BUFFER5; | 244 if (atom == XA_CUT_BUFFER5) return QCUT_BUFFER5; |
243 if (atom == XA_CUT_BUFFER6) return QCUT_BUFFER6; | 245 if (atom == XA_CUT_BUFFER6) return QCUT_BUFFER6; |
244 if (atom == XA_CUT_BUFFER7) return QCUT_BUFFER7; | 246 if (atom == XA_CUT_BUFFER7) return QCUT_BUFFER7; |
245 #endif | 247 #endif |
246 | 248 |
247 str = XGetAtomName (display, atom); | |
248 if (! str) return Qnil; | |
249 { | 249 { |
250 CONST char *intstr; | 250 CONST char *intstr; |
251 Lisp_Object val; | 251 char *str = XGetAtomName (display, atom); |
252 | |
253 if (! str) return Qnil; | |
252 | 254 |
253 GET_C_CHARPTR_INT_CTEXT_DATA_ALLOCA (str, intstr); | 255 GET_C_CHARPTR_INT_CTEXT_DATA_ALLOCA (str, intstr); |
254 val = intern (intstr); | |
255 XFree (str); | 256 XFree (str); |
256 return val; | 257 return intern (intstr); |
257 } | 258 } |
258 } | 259 } |
259 | 260 |
260 | 261 |
261 /* Do protocol to assert ourself as a selection owner. | 262 /* Do protocol to assert ourself as a selection owner. |
262 Update the Vselection_alist so that we can reply to later requests for | 263 Update the Vselection_alist so that we can reply to later requests for |
263 our selection. | 264 our selection. |
264 */ | 265 */ |
265 static void | 266 static void |
266 x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) | 267 x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) |
267 { | 268 { |
268 struct device *d = decode_x_device (Qnil); | 269 struct device *d = decode_x_device (Qnil); |
269 Display *display = DEVICE_X_DISPLAY (d); | 270 Display *display = DEVICE_X_DISPLAY (d); |
270 struct frame *sel_frame = selected_frame (); | 271 struct frame *sel_frame = selected_frame (); |
271 Window selecting_window = XtWindow (FRAME_X_TEXT_WIDGET (sel_frame)); | 272 Window selecting_window = XtWindow (FRAME_X_TEXT_WIDGET (sel_frame)); |
272 /* Use the time of the last-read mouse or keyboard event. | 273 /* Use the time of the last-read mouse or keyboard event. |
273 For selection purposes, we use this as a sleazy way of knowing what the | 274 For selection purposes, we use this as a sleazy way of knowing what the |
274 current time is in server-time. This assumes that the most recently read | 275 current time is in server-time. This assumes that the most recently read |
275 mouse or keyboard event has something to do with the assertion of the | 276 mouse or keyboard event has something to do with the assertion of the |
276 selection, which is probably true. | 277 selection, which is probably true. |
277 */ | 278 */ |
389 { | 390 { |
390 chartypes = LATIN_1; | 391 chartypes = LATIN_1; |
391 ptr += 2; | 392 ptr += 2; |
392 continue; | 393 continue; |
393 } | 394 } |
394 | 395 |
395 chartypes = WORLD; | 396 chartypes = WORLD; |
396 break; | 397 break; |
397 } | 398 } |
398 | 399 |
399 if (chartypes == LATIN_1) | 400 if (chartypes == LATIN_1) |
495 #if 0 /* #### MULTIPLE doesn't work yet */ | 496 #if 0 /* #### MULTIPLE doesn't work yet */ |
496 else if (CONSP (target_type) && | 497 else if (CONSP (target_type) && |
497 XCAR (target_type) == QMULTIPLE) | 498 XCAR (target_type) == QMULTIPLE) |
498 { | 499 { |
499 Lisp_Object pairs = XCDR (target_type); | 500 Lisp_Object pairs = XCDR (target_type); |
500 int size = XVECTOR (pairs)->size; | 501 int len = XVECTOR_LENGTH (pairs); |
501 int i; | 502 int i; |
502 /* If the target is MULTIPLE, then target_type looks like | 503 /* If the target is MULTIPLE, then target_type looks like |
503 (MULTIPLE . [[SELECTION1 TARGET1] [SELECTION2 TARGET2] ... ]) | 504 (MULTIPLE . [[SELECTION1 TARGET1] [SELECTION2 TARGET2] ... ]) |
504 We modify the second element of each pair in the vector and | 505 We modify the second element of each pair in the vector and |
505 return it as [[SELECTION1 <value1>] [SELECTION2 <value2>] ... ] | 506 return it as [[SELECTION1 <value1>] [SELECTION2 <value2>] ... ] |
506 */ | 507 */ |
507 for (i = 0; i < size; i++) | 508 for (i = 0; i < len; i++) |
508 { | 509 { |
509 Lisp_Object pair = vector_data (XVECTOR (pairs)) [i]; | 510 Lisp_Object pair = XVECTOR_DATA (pairs) [i]; |
510 vector_data (XVECTOR (pair)) [1] = | 511 XVECTOR_DATA (pair) [1] = |
511 x_get_local_selection (vector_data (XVECTOR (pair)) [0], | 512 x_get_local_selection (XVECTOR_DATA (pair) [0], |
512 vector_data (XVECTOR (pair)) [1]); | 513 XVECTOR_DATA (pair) [1]); |
513 } | 514 } |
514 return pairs; | 515 return pairs; |
515 } | 516 } |
516 #endif | 517 #endif |
517 else | 518 else |
529 INTEGER. | 530 INTEGER. |
530 */ | 531 */ |
531 check = value; | 532 check = value; |
532 if (CONSP (value) && SYMBOLP (XCAR (value))) | 533 if (CONSP (value) && SYMBOLP (XCAR (value))) |
533 check = XCDR (value); | 534 check = XCDR (value); |
534 | 535 |
535 /* Strings, vectors, and symbols are converted to selection data format in | 536 /* Strings, vectors, and symbols are converted to selection data format in |
536 the obvious way. Integers are converted to 16 bit quantities if they're | 537 the obvious way. Integers are converted to 16 bit quantities if they're |
537 small enough, otherwise 32 bits are used. | 538 small enough, otherwise 32 bits are used. |
538 */ | 539 */ |
539 if (STRINGP (check) || | 540 if (STRINGP (check) || |
553 (INTP (XCDR (check)) || | 554 (INTP (XCDR (check)) || |
554 (CONSP (XCDR (check)) && | 555 (CONSP (XCDR (check)) && |
555 INTP (XCAR (XCDR (check))) && | 556 INTP (XCAR (XCDR (check))) && |
556 NILP (XCDR (XCDR (check)))))) | 557 NILP (XCDR (XCDR (check)))))) |
557 return value; | 558 return value; |
558 /* Otherwise the lisp converter function returned something unrecognized. | 559 /* Otherwise the lisp converter function returned something unrecognized. |
559 */ | 560 */ |
560 else | 561 else |
561 signal_error (Qerror, | 562 signal_error (Qerror, |
562 list3 (build_string | 563 list3 (build_string |
563 ("unrecognized selection-conversion type"), | 564 ("unrecognized selection-conversion type"), |
574 */ | 575 */ |
575 static void | 576 static void |
576 x_decline_selection_request (XSelectionRequestEvent *event) | 577 x_decline_selection_request (XSelectionRequestEvent *event) |
577 { | 578 { |
578 XSelectionEvent reply; | 579 XSelectionEvent reply; |
579 reply.type = SelectionNotify; | 580 reply.type = SelectionNotify; |
580 reply.display = event->display; | 581 reply.display = event->display; |
581 reply.requestor = event->requestor; | 582 reply.requestor = event->requestor; |
582 reply.selection = event->selection; | 583 reply.selection = event->selection; |
583 reply.time = event->time; | 584 reply.time = event->time; |
584 reply.target = event->target; | 585 reply.target = event->target; |
585 reply.property = None; | 586 reply.property = None; |
586 | 587 |
587 (void) XSendEvent (reply.display, reply.requestor, False, 0L, | 588 XSendEvent (reply.display, reply.requestor, False, 0L, (XEvent *) &reply); |
588 (XEvent *) &reply); | |
589 XFlush (reply.display); | 589 XFlush (reply.display); |
590 } | 590 } |
591 | 591 |
592 | 592 |
593 /* Used as an unwind-protect clause so that, if a selection-converter signals | 593 /* Used as an unwind-protect clause so that, if a selection-converter signals |
623 int bytes_remaining; | 623 int bytes_remaining; |
624 int format_bytes = format/8; | 624 int format_bytes = format/8; |
625 int max_bytes = SELECTION_QUANTUM (display); | 625 int max_bytes = SELECTION_QUANTUM (display); |
626 if (max_bytes > MAX_SELECTION_QUANTUM) max_bytes = MAX_SELECTION_QUANTUM; | 626 if (max_bytes > MAX_SELECTION_QUANTUM) max_bytes = MAX_SELECTION_QUANTUM; |
627 | 627 |
628 reply.type = SelectionNotify; | 628 reply.type = SelectionNotify; |
629 reply.display = display; | 629 reply.display = display; |
630 reply.requestor = window; | 630 reply.requestor = window; |
631 reply.selection = event->selection; | 631 reply.selection = event->selection; |
632 reply.time = event->time; | 632 reply.time = event->time; |
633 reply.target = event->target; | 633 reply.target = event->target; |
634 reply.property = (event->property == None ? event->target : event->property); | 634 reply.property = (event->property == None ? event->target : event->property); |
635 | 635 |
636 /* #### XChangeProperty can generate BadAlloc, and we must handle it! */ | 636 /* #### XChangeProperty can generate BadAlloc, and we must handle it! */ |
637 | 637 |
638 /* Store the data on the requested property. | 638 /* Store the data on the requested property. |
639 If the selection is large, only store the first N bytes of it. | 639 If the selection is large, only store the first N bytes of it. |
646 stderr_out ("\nStoring all %d\n", bytes_remaining); | 646 stderr_out ("\nStoring all %d\n", bytes_remaining); |
647 #endif | 647 #endif |
648 XChangeProperty (display, window, reply.property, type, format, | 648 XChangeProperty (display, window, reply.property, type, format, |
649 PropModeReplace, data, size); | 649 PropModeReplace, data, size); |
650 /* At this point, the selection was successfully stored; ack it. */ | 650 /* At this point, the selection was successfully stored; ack it. */ |
651 (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply); | 651 XSendEvent (display, window, False, 0L, (XEvent *) &reply); |
652 XFlush (display); | 652 XFlush (display); |
653 } | 653 } |
654 else | 654 else |
655 { | 655 { |
656 /* Send an INCR selection. */ | 656 /* Send an INCR selection. */ |
667 XChangeProperty (display, window, reply.property, DEVICE_XATOM_INCR (d), | 667 XChangeProperty (display, window, reply.property, DEVICE_XATOM_INCR (d), |
668 32, PropModeReplace, (unsigned char *) | 668 32, PropModeReplace, (unsigned char *) |
669 &bytes_remaining, 1); | 669 &bytes_remaining, 1); |
670 XSelectInput (display, window, PropertyChangeMask); | 670 XSelectInput (display, window, PropertyChangeMask); |
671 /* Tell 'em the INCR data is there... */ | 671 /* Tell 'em the INCR data is there... */ |
672 (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply); | 672 XSendEvent (display, window, False, 0L, (XEvent *) &reply); |
673 XFlush (display); | 673 XFlush (display); |
674 | 674 |
675 /* First, wait for the requestor to ack by deleting the property. | 675 /* First, wait for the requestor to ack by deleting the property. |
676 This can run random lisp code (process handlers) or signal. | 676 This can run random lisp code (process handlers) or signal. |
677 */ | 677 */ |
730 int count; | 730 int count; |
731 struct device *d = get_device_from_display (event->display); | 731 struct device *d = get_device_from_display (event->display); |
732 | 732 |
733 GCPRO3 (local_selection_data, converted_selection, target_symbol); | 733 GCPRO3 (local_selection_data, converted_selection, target_symbol); |
734 | 734 |
735 reply.type = SelectionNotify; /* Construct the reply event */ | 735 reply.type = SelectionNotify; /* Construct the reply event */ |
736 reply.display = event->display; | 736 reply.display = event->display; |
737 reply.requestor = event->requestor; | 737 reply.requestor = event->requestor; |
738 reply.selection = event->selection; | 738 reply.selection = event->selection; |
739 reply.time = event->time; | 739 reply.time = event->time; |
740 reply.target = event->target; | 740 reply.target = event->target; |
741 reply.property = (event->property == None ? event->target : event->property); | 741 reply.property = (event->property == None ? event->target : event->property); |
742 | 742 |
743 selection_symbol = x_atom_to_symbol (d, event->selection); | 743 selection_symbol = x_atom_to_symbol (d, event->selection); |
744 | 744 |
745 local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); | 745 local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); |
746 | 746 |
747 #if 0 | 747 #if 0 |
748 # define CDR(x) (XCDR (x)) | 748 # define CDR(x) (XCDR (x)) |
749 # define CAR(x) (XCAR (x)) | 749 # define CAR(x) (XCAR (x)) |
750 /* This list isn't user-visible, so it can't "go bad." */ | 750 /* This list isn't user-visible, so it can't "go bad." */ |
751 if (!CONSP (local_selection_data)) abort (); | 751 if (!CONSP (local_selection_data)) abort (); |
787 | 787 |
788 #if 0 /* #### MULTIPLE doesn't work yet */ | 788 #if 0 /* #### MULTIPLE doesn't work yet */ |
789 if (EQ (target_symbol, QMULTIPLE)) | 789 if (EQ (target_symbol, QMULTIPLE)) |
790 target_symbol = fetch_multiple_target (event); | 790 target_symbol = fetch_multiple_target (event); |
791 #endif | 791 #endif |
792 | 792 |
793 /* Convert lisp objects back into binary data */ | 793 /* Convert lisp objects back into binary data */ |
794 | 794 |
795 converted_selection = | 795 converted_selection = |
796 x_get_local_selection (selection_symbol, target_symbol); | 796 x_get_local_selection (selection_symbol, target_symbol); |
797 | 797 |
798 if (! NILP (converted_selection)) | 798 if (! NILP (converted_selection)) |
799 { | 799 { |
800 unsigned char *data; | 800 unsigned char *data; |
801 unsigned int size; | 801 unsigned int size; |
802 int format; | 802 int format; |
803 Atom type; | 803 Atom type; |
804 lisp_data_to_selection_data (d, converted_selection, | 804 lisp_data_to_selection_data (d, converted_selection, |
805 &data, &type, &size, &format); | 805 &data, &type, &size, &format); |
806 | 806 |
807 x_reply_selection_request (event, format, data, size, type); | 807 x_reply_selection_request (event, format, data, size, type); |
808 successful_p = Qt; | 808 successful_p = Qt; |
809 /* Tell x_selection_request_lisp_error() it's cool. */ | 809 /* Tell x_selection_request_lisp_error() it's cool. */ |
810 event->type = 0; | 810 event->type = 0; |
811 xfree (data); | 811 xfree (data); |
814 | 814 |
815 DONE_LABEL: | 815 DONE_LABEL: |
816 | 816 |
817 UNGCPRO; | 817 UNGCPRO; |
818 | 818 |
819 /* Let random lisp code notice that the selection has been asked for. | 819 /* Let random lisp code notice that the selection has been asked for. */ |
820 */ | |
821 { | 820 { |
822 Lisp_Object rest; | 821 Lisp_Object rest; |
823 Lisp_Object val = Vx_sent_selection_hooks; | 822 Lisp_Object val = Vx_sent_selection_hooks; |
824 if (!UNBOUNDP (val) && !NILP (val)) | 823 if (!UNBOUNDP (val) && !NILP (val)) |
825 { | 824 { |
842 { | 841 { |
843 Display *display = event->display; | 842 Display *display = event->display; |
844 struct device *d = get_device_from_display (display); | 843 struct device *d = get_device_from_display (display); |
845 Atom selection = event->selection; | 844 Atom selection = event->selection; |
846 Time changed_owner_time = event->time; | 845 Time changed_owner_time = event->time; |
847 | 846 |
848 Lisp_Object selection_symbol, local_selection_data; | 847 Lisp_Object selection_symbol, local_selection_data; |
849 Time local_selection_time; | 848 Time local_selection_time; |
850 | 849 |
851 selection_symbol = x_atom_to_symbol (d, selection); | 850 selection_symbol = x_atom_to_symbol (d, selection); |
852 | 851 |
1044 static Lisp_Object | 1043 static Lisp_Object |
1045 copy_multiple_data (Lisp_Object obj) | 1044 copy_multiple_data (Lisp_Object obj) |
1046 { | 1045 { |
1047 Lisp_Object vec; | 1046 Lisp_Object vec; |
1048 int i; | 1047 int i; |
1049 int size; | 1048 int len; |
1050 if (CONSP (obj)) | 1049 if (CONSP (obj)) |
1051 return Fcons (XCAR (obj), copy_multiple_data (XCDR (obj))); | 1050 return Fcons (XCAR (obj), copy_multiple_data (XCDR (obj))); |
1052 | 1051 |
1053 CHECK_VECTOR (obj); | 1052 CHECK_VECTOR (obj); |
1054 size = XVECTOR (obj)->size; | 1053 len = XVECTOR_LENGTH (obj); |
1055 vec = make_vector (size, Qnil); | 1054 vec = make_vector (len, Qnil); |
1056 for (i = 0; i < size; i++) | 1055 for (i = 0; i < len; i++) |
1057 { | 1056 { |
1058 Lisp_Object vec2 = vector_data (XVECTOR (obj)) [i]; | 1057 Lisp_Object vec2 = XVECTOR_DATA (obj) [i]; |
1059 CHECK_VECTOR (vec2); | 1058 CHECK_VECTOR (vec2); |
1060 if (XVECTOR (vec2)->size != 2) | 1059 if (XVECTOR_LENGTH (vec2) != 2) |
1061 signal_error (Qerror, list2 (build_string | 1060 signal_error (Qerror, list2 (build_string |
1062 ("vectors must be of length 2"), | 1061 ("vectors must be of length 2"), |
1063 vec2)); | 1062 vec2)); |
1064 vector_data (XVECTOR (vec)) [i] = make_vector (2, Qnil); | 1063 XVECTOR_DATA (vec) [i] = make_vector (2, Qnil); |
1065 vector_data (XVECTOR (vector_data (XVECTOR (vec)) [i])) [0] = | 1064 XVECTOR_DATA (XVECTOR_DATA (vec) [i]) [0] = XVECTOR_DATA (vec2) [0]; |
1066 vector_data (XVECTOR (vec2)) [0]; | 1065 XVECTOR_DATA (XVECTOR_DATA (vec) [i]) [1] = XVECTOR_DATA (vec2) [1]; |
1067 vector_data (XVECTOR (vector_data (XVECTOR (vec)) [i])) [1] = | |
1068 vector_data (XVECTOR (vec2)) [1]; | |
1069 } | 1066 } |
1070 return vec; | 1067 return vec; |
1071 } | 1068 } |
1072 | 1069 |
1073 #endif | 1070 #endif |
1109 struct frame *sel_frame = selected_frame (); | 1106 struct frame *sel_frame = selected_frame (); |
1110 Window requestor_window = XtWindow (FRAME_X_TEXT_WIDGET (sel_frame)); | 1107 Window requestor_window = XtWindow (FRAME_X_TEXT_WIDGET (sel_frame)); |
1111 Time requestor_time = DEVICE_X_MOUSE_TIMESTAMP (d); | 1108 Time requestor_time = DEVICE_X_MOUSE_TIMESTAMP (d); |
1112 Atom target_property = DEVICE_XATOM_EMACS_TMP (d); | 1109 Atom target_property = DEVICE_XATOM_EMACS_TMP (d); |
1113 Atom selection_atom = symbol_to_x_atom (d, selection_symbol, 0); | 1110 Atom selection_atom = symbol_to_x_atom (d, selection_symbol, 0); |
1114 Atom type_atom; | |
1115 int speccount; | 1111 int speccount; |
1116 | 1112 Atom type_atom = symbol_to_x_atom (d, (CONSP (target_type) ? |
1117 if (CONSP (target_type)) | 1113 XCAR (target_type) : target_type), 0); |
1118 type_atom = symbol_to_x_atom (d, XCAR (target_type), 0); | |
1119 else | |
1120 type_atom = symbol_to_x_atom (d, target_type, 0); | |
1121 | 1114 |
1122 XConvertSelection (display, selection_atom, type_atom, target_property, | 1115 XConvertSelection (display, selection_atom, type_atom, target_property, |
1123 requestor_window, requestor_time); | 1116 requestor_window, requestor_time); |
1124 | 1117 |
1125 /* Block until the reply has been read. */ | 1118 /* Block until the reply has been read. */ |
1165 int offset = 0; | 1158 int offset = 0; |
1166 unsigned char *tmp_data = 0; | 1159 unsigned char *tmp_data = 0; |
1167 int result; | 1160 int result; |
1168 int buffer_size = SELECTION_QUANTUM (display); | 1161 int buffer_size = SELECTION_QUANTUM (display); |
1169 if (buffer_size > MAX_SELECTION_QUANTUM) buffer_size = MAX_SELECTION_QUANTUM; | 1162 if (buffer_size > MAX_SELECTION_QUANTUM) buffer_size = MAX_SELECTION_QUANTUM; |
1170 | 1163 |
1171 /* First probe the thing to find out how big it is. */ | 1164 /* First probe the thing to find out how big it is. */ |
1172 result = XGetWindowProperty (display, window, property, | 1165 result = XGetWindowProperty (display, window, property, |
1173 0, 0, False, AnyPropertyType, | 1166 0, 0, False, AnyPropertyType, |
1174 actual_type_ret, actual_format_ret, | 1167 actual_type_ret, actual_format_ret, |
1175 actual_size_ret, | 1168 actual_size_ret, |
1179 *data_ret = 0; | 1172 *data_ret = 0; |
1180 *bytes_ret = 0; | 1173 *bytes_ret = 0; |
1181 return; | 1174 return; |
1182 } | 1175 } |
1183 XFree ((char *) tmp_data); | 1176 XFree ((char *) tmp_data); |
1184 | 1177 |
1185 if (*actual_type_ret == None || *actual_format_ret == 0) | 1178 if (*actual_type_ret == None || *actual_format_ret == 0) |
1186 { | 1179 { |
1187 if (delete_p) XDeleteProperty (display, window, property); | 1180 if (delete_p) XDeleteProperty (display, window, property); |
1188 *data_ret = 0; | 1181 *data_ret = 0; |
1189 *bytes_ret = 0; | 1182 *bytes_ret = 0; |
1190 return; | 1183 return; |
1191 } | 1184 } |
1192 | 1185 |
1193 total_size = bytes_remaining + 1; | 1186 total_size = bytes_remaining + 1; |
1194 *data_ret = (unsigned char *) xmalloc (total_size); | 1187 *data_ret = (unsigned char *) xmalloc (total_size); |
1195 | 1188 |
1196 /* Now read, until weve gotten it all. */ | 1189 /* Now read, until weve gotten it all. */ |
1197 while (bytes_remaining) | 1190 while (bytes_remaining) |
1198 { | 1191 { |
1199 #if 0 | 1192 #if 0 |
1200 int last = bytes_remaining; | 1193 int last = bytes_remaining; |
1303 { | 1296 { |
1304 /* This function can GC */ | 1297 /* This function can GC */ |
1305 Atom actual_type; | 1298 Atom actual_type; |
1306 int actual_format; | 1299 int actual_format; |
1307 unsigned long actual_size; | 1300 unsigned long actual_size; |
1308 unsigned char *data = 0; | 1301 unsigned char *data = NULL; |
1309 int bytes = 0; | 1302 int bytes = 0; |
1310 Lisp_Object val; | 1303 Lisp_Object val; |
1311 struct device *d = get_device_from_display (display); | 1304 struct device *d = get_device_from_display (display); |
1312 | 1305 |
1313 x_get_window_property (display, window, property, &data, &bytes, | 1306 x_get_window_property (display, window, property, &data, &bytes, |
1314 &actual_type, &actual_format, &actual_size, 1); | 1307 &actual_type, &actual_format, &actual_size, 1); |
1315 if (! data) | 1308 if (! data) |
1316 { | 1309 { |
1317 int there_is_a_selection_owner; | 1310 if (XGetSelectionOwner (display, selection_atom)) |
1318 there_is_a_selection_owner = | 1311 /* there is a selection owner */ |
1319 XGetSelectionOwner (display, selection_atom); | 1312 signal_error |
1320 signal_error (Qerror, | 1313 (Qselection_conversion_error, |
1321 (there_is_a_selection_owner | 1314 Fcons (build_string ("selection owner couldn't convert"), |
1322 ? Fcons (build_string ("selection owner couldn't convert"), | 1315 Fcons (x_atom_to_symbol (d, selection_atom), |
1323 (actual_type | 1316 actual_type ? |
1324 ? list2 (target_type, | 1317 list2 (target_type, x_atom_to_symbol (d, actual_type)) : |
1325 x_atom_to_symbol (d, actual_type)) | 1318 list1 (target_type)))); |
1326 : list1 (target_type))) | 1319 else |
1327 : list2 (build_string ("no selection"), | 1320 signal_error (Qerror, |
1328 x_atom_to_symbol (d, selection_atom)))); | 1321 list2 (build_string ("no selection"), |
1329 } | 1322 x_atom_to_symbol (d, selection_atom))); |
1330 | 1323 } |
1324 | |
1331 if (actual_type == DEVICE_XATOM_INCR (d)) | 1325 if (actual_type == DEVICE_XATOM_INCR (d)) |
1332 { | 1326 { |
1333 /* Ok, that data wasnt *the* data, it was just the beginning. */ | 1327 /* Ok, that data wasn't *the* data, it was just the beginning. */ |
1334 | 1328 |
1335 unsigned int min_size_bytes = * ((unsigned int *) data); | 1329 unsigned int min_size_bytes = * ((unsigned int *) data); |
1336 XFree ((char *) data); | 1330 xfree (data); |
1337 receive_incremental_selection (display, window, property, target_type, | 1331 receive_incremental_selection (display, window, property, target_type, |
1338 min_size_bytes, &data, &bytes, | 1332 min_size_bytes, &data, &bytes, |
1339 &actual_type, &actual_format, | 1333 &actual_type, &actual_format, |
1340 &actual_size); | 1334 &actual_size); |
1341 } | 1335 } |
1342 | 1336 |
1343 /* It's been read. Now convert it to a lisp object in some semi-rational | 1337 /* It's been read. Now convert it to a lisp object in some semi-rational |
1344 manner. | 1338 manner. */ |
1345 */ | |
1346 val = selection_data_to_lisp_data (d, data, bytes, | 1339 val = selection_data_to_lisp_data (d, data, bytes, |
1347 actual_type, actual_format); | 1340 actual_type, actual_format); |
1348 | 1341 |
1349 xfree (data); | 1342 xfree (data); |
1350 return val; | 1343 return val; |
1351 } | 1344 } |
1352 | 1345 |
1353 /* These functions convert from the selection data read from the server into | 1346 /* These functions convert from the selection data read from the server into |
1393 return QNULL; | 1386 return QNULL; |
1394 | 1387 |
1395 /* Convert any 8-bit data to a string, for compactness. */ | 1388 /* Convert any 8-bit data to a string, for compactness. */ |
1396 else if (format == 8) | 1389 else if (format == 8) |
1397 return make_ext_string (data, size, | 1390 return make_ext_string (data, size, |
1398 type == DEVICE_XATOM_TEXT (d) | 1391 type == DEVICE_XATOM_TEXT (d) || |
1399 || type == DEVICE_XATOM_COMPOUND_TEXT (d) | 1392 type == DEVICE_XATOM_COMPOUND_TEXT (d) |
1400 ? FORMAT_CTEXT : FORMAT_BINARY); | 1393 ? FORMAT_CTEXT : FORMAT_BINARY); |
1401 | 1394 |
1402 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to | 1395 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to |
1403 a vector of symbols. | 1396 a vector of symbols. |
1404 */ | 1397 */ |
1566 a set of 16 or 32 bit INTEGERs; | 1559 a set of 16 or 32 bit INTEGERs; |
1567 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...] | 1560 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...] |
1568 */ | 1561 */ |
1569 int i; | 1562 int i; |
1570 | 1563 |
1571 if (SYMBOLP (vector_data (XVECTOR (obj)) [0])) | 1564 if (SYMBOLP (XVECTOR_DATA (obj) [0])) |
1572 /* This vector is an ATOM set */ | 1565 /* This vector is an ATOM set */ |
1573 { | 1566 { |
1574 if (NILP (type)) type = QATOM; | 1567 if (NILP (type)) type = QATOM; |
1575 *size_ret = XVECTOR (obj)->size; | 1568 *size_ret = XVECTOR_LENGTH (obj); |
1576 *format_ret = 32; | 1569 *format_ret = 32; |
1577 *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom)); | 1570 *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom)); |
1578 for (i = 0; i < *size_ret; i++) | 1571 for (i = 0; i < *size_ret; i++) |
1579 if (SYMBOLP (vector_data (XVECTOR (obj)) [i])) | 1572 if (SYMBOLP (XVECTOR_DATA (obj) [i])) |
1580 (*(Atom **) data_ret) [i] = | 1573 (*(Atom **) data_ret) [i] = |
1581 symbol_to_x_atom (d, vector_data (XVECTOR (obj)) [i], 0); | 1574 symbol_to_x_atom (d, XVECTOR_DATA (obj) [i], 0); |
1582 else | 1575 else |
1583 signal_error (Qerror, /* Qselection_error */ | 1576 signal_error (Qerror, /* Qselection_error */ |
1584 list2 (build_string | 1577 list2 (build_string |
1585 ("all elements of the vector must be of the same type"), | 1578 ("all elements of the vector must be of the same type"), |
1586 obj)); | 1579 obj)); |
1587 } | 1580 } |
1588 #if 0 /* #### MULTIPLE doesn't work yet */ | 1581 #if 0 /* #### MULTIPLE doesn't work yet */ |
1589 else if (VECTORP (vector_data (XVECTOR (obj)) [0])) | 1582 else if (VECTORP (XVECTOR_DATA (obj) [0])) |
1590 /* This vector is an ATOM_PAIR set */ | 1583 /* This vector is an ATOM_PAIR set */ |
1591 { | 1584 { |
1592 if (NILP (type)) type = QATOM_PAIR; | 1585 if (NILP (type)) type = QATOM_PAIR; |
1593 *size_ret = XVECTOR (obj)->size; | 1586 *size_ret = XVECTOR_LENGTH (obj); |
1594 *format_ret = 32; | 1587 *format_ret = 32; |
1595 *data_ret = (unsigned char *) | 1588 *data_ret = (unsigned char *) |
1596 xmalloc ((*size_ret) * sizeof (Atom) * 2); | 1589 xmalloc ((*size_ret) * sizeof (Atom) * 2); |
1597 for (i = 0; i < *size_ret; i++) | 1590 for (i = 0; i < *size_ret; i++) |
1598 if (VECTORP (vector_data (XVECTOR (obj)) [i])) | 1591 if (VECTORP (XVECTOR_DATA (obj) [i])) |
1599 { | 1592 { |
1600 Lisp_Object pair = vector_data (XVECTOR (obj)) [i]; | 1593 Lisp_Object pair = XVECTOR_DATA (obj) [i]; |
1601 if (XVECTOR (pair)->size != 2) | 1594 if (XVECTOR_LENGTH (pair) != 2) |
1602 signal_error (Qerror, | 1595 signal_error (Qerror, |
1603 list2 (build_string | 1596 list2 (build_string |
1604 ("elements of the vector must be vectors of exactly two elements"), | 1597 ("elements of the vector must be vectors of exactly two elements"), |
1605 pair)); | 1598 pair)); |
1606 | 1599 |
1607 (*(Atom **) data_ret) [i * 2] = | 1600 (*(Atom **) data_ret) [i * 2] = |
1608 symbol_to_x_atom (d, vector_data (XVECTOR (pair)) [0], 0); | 1601 symbol_to_x_atom (d, XVECTOR_DATA (pair) [0], 0); |
1609 (*(Atom **) data_ret) [(i * 2) + 1] = | 1602 (*(Atom **) data_ret) [(i * 2) + 1] = |
1610 symbol_to_x_atom (d, vector_data (XVECTOR (pair)) [1], 0); | 1603 symbol_to_x_atom (d, XVECTOR_DATA (pair) [1], 0); |
1611 } | 1604 } |
1612 else | 1605 else |
1613 signal_error (Qerror, | 1606 signal_error (Qerror, |
1614 list2 (build_string | 1607 list2 (build_string |
1615 ("all elements of the vector must be of the same type"), | 1608 ("all elements of the vector must be of the same type"), |
1617 } | 1610 } |
1618 #endif | 1611 #endif |
1619 else | 1612 else |
1620 /* This vector is an INTEGER set, or something like it */ | 1613 /* This vector is an INTEGER set, or something like it */ |
1621 { | 1614 { |
1622 *size_ret = XVECTOR (obj)->size; | 1615 *size_ret = XVECTOR_LENGTH (obj); |
1623 if (NILP (type)) type = QINTEGER; | 1616 if (NILP (type)) type = QINTEGER; |
1624 *format_ret = 16; | 1617 *format_ret = 16; |
1625 for (i = 0; i < *size_ret; i++) | 1618 for (i = 0; i < *size_ret; i++) |
1626 if (CONSP (vector_data (XVECTOR (obj)) [i])) | 1619 if (CONSP (XVECTOR_DATA (obj) [i])) |
1627 *format_ret = 32; | 1620 *format_ret = 32; |
1628 else if (!INTP (vector_data (XVECTOR (obj)) [i])) | 1621 else if (!INTP (XVECTOR_DATA (obj) [i])) |
1629 signal_error (Qerror, /* Qselection_error */ | 1622 signal_error (Qerror, /* Qselection_error */ |
1630 list2 (build_string | 1623 list2 (build_string |
1631 ("all elements of the vector must be integers or conses of integers"), | 1624 ("all elements of the vector must be integers or conses of integers"), |
1632 obj)); | 1625 obj)); |
1633 | 1626 |
1634 *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); | 1627 *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); |
1635 for (i = 0; i < *size_ret; i++) | 1628 for (i = 0; i < *size_ret; i++) |
1636 if (*format_ret == 32) | 1629 if (*format_ret == 32) |
1637 (*((unsigned long **) data_ret)) [i] = | 1630 (*((unsigned long **) data_ret)) [i] = |
1638 lisp_to_word (vector_data (XVECTOR (obj)) [i]); | 1631 lisp_to_word (XVECTOR_DATA (obj) [i]); |
1639 else | 1632 else |
1640 (*((unsigned short **) data_ret)) [i] = | 1633 (*((unsigned short **) data_ret)) [i] = |
1641 (unsigned short) lisp_to_word (vector_data (XVECTOR (obj)) [i]); | 1634 (unsigned short) lisp_to_word (XVECTOR_DATA (obj) [i]); |
1642 } | 1635 } |
1643 } | 1636 } |
1644 else | 1637 else |
1645 signal_error (Qerror, /* Qselection_error */ | 1638 signal_error (Qerror, /* Qselection_error */ |
1646 list2 (build_string ("unrecognized selection data"), | 1639 list2 (build_string ("unrecognized selection data"), |
1669 return make_int (- XINT (XCDR (obj))); | 1662 return make_int (- XINT (XCDR (obj))); |
1670 } | 1663 } |
1671 if (VECTORP (obj)) | 1664 if (VECTORP (obj)) |
1672 { | 1665 { |
1673 int i; | 1666 int i; |
1674 int size = XVECTOR (obj)->size; | 1667 int len = XVECTOR_LENGTH (obj); |
1675 Lisp_Object copy; | 1668 Lisp_Object copy; |
1676 if (size == 1) | 1669 if (len == 1) |
1677 return clean_local_selection_data (vector_data (XVECTOR (obj)) [0]); | 1670 return clean_local_selection_data (XVECTOR_DATA (obj) [0]); |
1678 copy = make_vector (size, Qnil); | 1671 copy = make_vector (len, Qnil); |
1679 for (i = 0; i < size; i++) | 1672 for (i = 0; i < len; i++) |
1680 vector_data (XVECTOR (copy)) [i] = | 1673 XVECTOR_DATA (copy) [i] = |
1681 clean_local_selection_data (vector_data (XVECTOR (obj)) [i]); | 1674 clean_local_selection_data (XVECTOR_DATA (obj) [i]); |
1682 return copy; | 1675 return copy; |
1683 } | 1676 } |
1684 return obj; | 1677 return obj; |
1685 } | 1678 } |
1686 | 1679 |
1690 */ | 1683 */ |
1691 void | 1684 void |
1692 x_handle_selection_notify (XSelectionEvent *event) | 1685 x_handle_selection_notify (XSelectionEvent *event) |
1693 { | 1686 { |
1694 if (! reading_selection_reply) | 1687 if (! reading_selection_reply) |
1695 { | 1688 message ("received an unexpected SelectionNotify event"); |
1696 message ("received an unexpected SelectionNotify event"); | 1689 else if (event->requestor != reading_selection_reply) |
1697 return; | 1690 message ("received a SelectionNotify event for the wrong window"); |
1698 } | 1691 else if (event->selection != reading_which_selection) |
1699 if (event->requestor != reading_selection_reply) | 1692 message ("received the wrong selection type in SelectionNotify!"); |
1700 { | 1693 else |
1701 message ("received a SelectionNotify event for the wrong window"); | 1694 reading_selection_reply = 0; /* we're done now. */ |
1702 return; | |
1703 } | |
1704 if (event->selection != reading_which_selection) | |
1705 { | |
1706 message ("received the wrong selection type in SelectionNotify!"); | |
1707 return; | |
1708 } | |
1709 | |
1710 reading_selection_reply = 0; /* we're done now. */ | |
1711 } | 1695 } |
1712 | 1696 |
1713 | 1697 |
1714 DEFUN ("x-own-selection-internal", Fx_own_selection_internal, 2, 2, 0, /* | 1698 DEFUN ("x-own-selection-internal", Fx_own_selection_internal, 2, 2, 0, /* |
1715 Assert an X selection of the given TYPE with the given VALUE. | 1699 Assert an X selection of the given TYPE with the given VALUE. |
1730 simply return our selection value. If we are not the owner, this | 1714 simply return our selection value. If we are not the owner, this |
1731 will block until all of the data has arrived. | 1715 will block until all of the data has arrived. |
1732 */ | 1716 */ |
1733 DEFUN ("x-get-selection-internal", Fx_get_selection_internal, 2, 2, 0, /* | 1717 DEFUN ("x-get-selection-internal", Fx_get_selection_internal, 2, 2, 0, /* |
1734 Return text selected from some X window. | 1718 Return text selected from some X window. |
1735 SELECTION is a symbol, typically PRIMARY, SECONDARY, or CLIPBOARD. | 1719 SELECTION_SYMBOL is a symbol, typically PRIMARY, SECONDARY, or CLIPBOARD. |
1736 TYPE is the type of data desired, typically STRING or COMPOUND_TEXT. | 1720 TARGET_TYPE is the type of data desired, typically STRING or COMPOUND_TEXT. |
1737 Under Mule, if the resultant data comes back as 8-bit data in type | 1721 Under Mule, if the resultant data comes back as 8-bit data in type |
1738 TEXT or COMPOUND_TEXT, it will be decoded as Compound Text. | 1722 TEXT or COMPOUND_TEXT, it will be decoded as Compound Text. |
1739 */ | 1723 */ |
1740 (selection_symbol, target_type)) | 1724 (selection_symbol, target_type)) |
1741 { | 1725 { |
1759 | 1743 |
1760 val = x_get_local_selection (selection_symbol, target_type); | 1744 val = x_get_local_selection (selection_symbol, target_type); |
1761 | 1745 |
1762 if (NILP (val)) | 1746 if (NILP (val)) |
1763 { | 1747 { |
1764 val = x_get_foreign_selection (selection_symbol, | 1748 val = x_get_foreign_selection (selection_symbol, target_type); |
1765 target_type); | 1749 } |
1766 goto DONE_LABEL; | 1750 else |
1767 } | 1751 { |
1768 | 1752 if (CONSP (val) && SYMBOLP (XCAR (val))) |
1769 if (CONSP (val) && | 1753 { |
1770 SYMBOLP (XCAR (val))) | 1754 val = XCDR (val); |
1771 { | 1755 if (CONSP (val) && NILP (XCDR (val))) |
1772 val = XCDR (val); | 1756 val = XCAR (val); |
1773 if (CONSP (val) && NILP (XCDR (val))) | 1757 } |
1774 val = XCAR (val); | 1758 val = clean_local_selection_data (val); |
1775 } | 1759 } |
1776 val = clean_local_selection_data (val); | |
1777 DONE_LABEL: | |
1778 UNGCPRO; | 1760 UNGCPRO; |
1779 return val; | 1761 return val; |
1780 } | 1762 } |
1781 | 1763 |
1782 DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal, 1, 2, 0, /* | 1764 DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal, 1, 2, 0, /* |
1834 */ | 1816 */ |
1835 (selection)) | 1817 (selection)) |
1836 { | 1818 { |
1837 CHECK_SYMBOL (selection); | 1819 CHECK_SYMBOL (selection); |
1838 if (EQ (selection, Qnil)) selection = QPRIMARY; | 1820 if (EQ (selection, Qnil)) selection = QPRIMARY; |
1839 if (EQ (selection, Qt)) selection = QSECONDARY; | 1821 if (EQ (selection, Qt)) selection = QSECONDARY; |
1840 | 1822 |
1841 if (NILP (Fassq (selection, Vselection_alist))) | 1823 return NILP (Fassq (selection, Vselection_alist)) ? Qnil: Qt; |
1842 return Qnil; | |
1843 return Qt; | |
1844 } | 1824 } |
1845 | 1825 |
1846 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, 0, 1, 0, /* | 1826 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, 0, 1, 0, /* |
1847 Whether there is an owner for the given X Selection. | 1827 Whether there is an owner for the given X Selection. |
1848 The arg should be the name of the selection in question, typically one of | 1828 The arg should be the name of the selection in question, typically one of |
1849 the symbols PRIMARY, SECONDARY, or CLIPBOARD. (For convenience, the symbol | 1829 the symbols PRIMARY, SECONDARY, or CLIPBOARD. (For convenience, the symbol |
1850 nil is the same as PRIMARY, and t is the same as SECONDARY.) | 1830 nil is the same as PRIMARY, and t is the same as SECONDARY.) |
1851 */ | 1831 */ |
1852 (selection)) | 1832 (selection)) |
1853 { | 1833 { |
1854 Window owner; | |
1855 struct device *d = decode_x_device (Qnil); | 1834 struct device *d = decode_x_device (Qnil); |
1856 Display *dpy = DEVICE_X_DISPLAY (d); | 1835 Display *dpy = DEVICE_X_DISPLAY (d); |
1857 CHECK_SYMBOL (selection); | 1836 CHECK_SYMBOL (selection); |
1858 if (!NILP (Fx_selection_owner_p (selection))) | 1837 if (!NILP (Fx_selection_owner_p (selection))) |
1859 return Qt; | 1838 return Qt; |
1860 owner = XGetSelectionOwner (dpy, symbol_to_x_atom (d, selection, 0)); | 1839 return XGetSelectionOwner (dpy, symbol_to_x_atom (d, selection, 0)) != NULL ? |
1861 return (owner ? Qt : Qnil); | 1840 Qt : Qnil; |
1862 } | 1841 } |
1863 | 1842 |
1864 | 1843 |
1865 #ifdef CUT_BUFFER_SUPPORT | 1844 #ifdef CUT_BUFFER_SUPPORT |
1866 | 1845 |
1969 /* We use the STRING encoding (Latin-1 only) if we can, else COMPOUND_TEXT. | 1948 /* We use the STRING encoding (Latin-1 only) if we can, else COMPOUND_TEXT. |
1970 We cheat and use type = `STRING' even when using COMPOUND_TEXT. | 1949 We cheat and use type = `STRING' even when using COMPOUND_TEXT. |
1971 The ICCCM requires that this be so, and other clients assume it, | 1950 The ICCCM requires that this be so, and other clients assume it, |
1972 as we do ourselves in initialize_cut_buffers. */ | 1951 as we do ourselves in initialize_cut_buffers. */ |
1973 | 1952 |
1974 #ifdef MULE | 1953 #ifdef MULE |
1975 /* Optimize for the common ASCII case */ | 1954 /* Optimize for the common ASCII case */ |
1976 for (ptr = data, end = ptr + bytes; ptr <= end; ) | 1955 for (ptr = data, end = ptr + bytes; ptr <= end; ) |
1977 { | 1956 { |
1978 if (BYTE_ASCII_P (*ptr)) | 1957 if (BYTE_ASCII_P (*ptr)) |
1979 { | 1958 { |
1980 ptr++; | 1959 ptr++; |
1981 continue; | 1960 continue; |
1982 } | 1961 } |
1983 | 1962 |
1984 if ((*ptr) == LEADING_BYTE_LATIN_ISO8859_1 || | 1963 if ((*ptr) == LEADING_BYTE_LATIN_ISO8859_1 || |
1985 (*ptr) == LEADING_BYTE_CONTROL_1) | 1964 (*ptr) == LEADING_BYTE_CONTROL_1) |
1986 { | 1965 { |
1987 chartypes = LATIN_1; | 1966 chartypes = LATIN_1; |
1988 ptr += 2; | 1967 ptr += 2; |
1989 continue; | 1968 continue; |
1990 } | 1969 } |
1991 | 1970 |
1992 chartypes = WORLD; | 1971 chartypes = WORLD; |
1993 break; | 1972 break; |
1994 } | 1973 } |
1995 | 1974 |
1996 if (chartypes == LATIN_1) | 1975 if (chartypes == LATIN_1) |
1997 GET_STRING_BINARY_DATA_ALLOCA (string, data, bytes); | 1976 GET_STRING_BINARY_DATA_ALLOCA (string, data, bytes); |
1998 else if (chartypes == WORLD) | 1977 else if (chartypes == WORLD) |
1999 GET_STRING_CTEXT_DATA_ALLOCA (string, data, bytes); | 1978 GET_STRING_CTEXT_DATA_ALLOCA (string, data, bytes); |
2000 #endif /* MULE */ | 1979 #endif /* MULE */ |
2001 | 1980 |
2002 bytes_remaining = bytes; | 1981 bytes_remaining = bytes; |
2003 | 1982 |
2004 while (bytes_remaining) | 1983 while (bytes_remaining) |
2005 { | 1984 { |
2006 int chunk = bytes_remaining < max_bytes ? bytes_remaining : max_bytes; | 1985 int chunk = bytes_remaining < max_bytes ? bytes_remaining : max_bytes; |
2102 defsymbol (&QRECTANGLE, "RECTANGLE"); | 2081 defsymbol (&QRECTANGLE, "RECTANGLE"); |
2103 defsymbol (&QWINDOW, "WINDOW"); | 2082 defsymbol (&QWINDOW, "WINDOW"); |
2104 defsymbol (&QWM_HINTS, "WM_HINTS"); | 2083 defsymbol (&QWM_HINTS, "WM_HINTS"); |
2105 defsymbol (&QWM_SIZE_HINTS, "WM_SIZE_HINTS"); | 2084 defsymbol (&QWM_SIZE_HINTS, "WM_SIZE_HINTS"); |
2106 #endif /* EPOCH */ | 2085 #endif /* EPOCH */ |
2107 | 2086 |
2108 #ifdef CUT_BUFFER_SUPPORT | 2087 #ifdef CUT_BUFFER_SUPPORT |
2109 defsymbol (&QCUT_BUFFER0, "CUT_BUFFER0"); | 2088 defsymbol (&QCUT_BUFFER0, "CUT_BUFFER0"); |
2110 defsymbol (&QCUT_BUFFER1, "CUT_BUFFER1"); | 2089 defsymbol (&QCUT_BUFFER1, "CUT_BUFFER1"); |
2111 defsymbol (&QCUT_BUFFER2, "CUT_BUFFER2"); | 2090 defsymbol (&QCUT_BUFFER2, "CUT_BUFFER2"); |
2112 defsymbol (&QCUT_BUFFER3, "CUT_BUFFER3"); | 2091 defsymbol (&QCUT_BUFFER3, "CUT_BUFFER3"); |
2113 defsymbol (&QCUT_BUFFER4, "CUT_BUFFER4"); | 2092 defsymbol (&QCUT_BUFFER4, "CUT_BUFFER4"); |
2114 defsymbol (&QCUT_BUFFER5, "CUT_BUFFER5"); | 2093 defsymbol (&QCUT_BUFFER5, "CUT_BUFFER5"); |
2115 defsymbol (&QCUT_BUFFER6, "CUT_BUFFER6"); | 2094 defsymbol (&QCUT_BUFFER6, "CUT_BUFFER6"); |
2116 defsymbol (&QCUT_BUFFER7, "CUT_BUFFER7"); | 2095 defsymbol (&QCUT_BUFFER7, "CUT_BUFFER7"); |
2117 #endif | 2096 #endif /* CUT_BUFFER_SUPPORT */ |
2097 | |
2098 deferror (&Qselection_conversion_error, | |
2099 "selection-conversion-error", | |
2100 "selection-conversion error", Qio_error); | |
2118 } | 2101 } |
2119 | 2102 |
2120 void | 2103 void |
2121 vars_of_xselect (void) | 2104 vars_of_xselect (void) |
2122 { | 2105 { |