aboutsummaryrefslogtreecommitdiffstats
path: root/src/pgtkselect.c
diff options
context:
space:
mode:
authorPo Lu2022-06-21 22:03:42 +0800
committerPo Lu2022-06-21 22:05:21 +0800
commitbe35c92c90d455739a6ff9d4beefa2b35d044852 (patch)
tree19c5be6b9e09ccb45c58a5008f8f956f3ad92d57 /src/pgtkselect.c
parentb1af8c2c00aefe6aa554a468e65b6e07c9f14722 (diff)
downloademacs-be35c92c90d455739a6ff9d4beefa2b35d044852.tar.gz
emacs-be35c92c90d455739a6ff9d4beefa2b35d044852.zip
Rewrite PGTK selection code from scratch
* src/frame.c (delete_frame): Clear selections and swallow special events. * src/keyboard.c (kbd_buffer_get_event, process_special_events): Also handle selection events on PGTK. * src/keyboard.h (union buffered_input_event): Include selection events on PGTK. * src/pgtkselect.c (symbol_to_gtk_clipboard, LOCAL_SELECTION): New functions and macros. (selection_type_to_quarks, get_func, clear_func): Delete functions. (pgtk_selection_init, pgtk_selection_lost): (pgtk_selection_usable): New functions. (Fpgtk_own_selection_internal, Fpgtk_disown_selection_internal) (Fpgtk_selection_exists_p, Fpgtk_selection_owner_p) (Fpgtk_get_selection_internal): Complete rewrite. (syms_of_pgtkselect): Update defsyms and add more hooks. * src/pgtkselect.h: Delete file. * src/pgtkterm.c (evq_enqueue): Set last user time based on the event. (pgtk_any_window_to_frame, button_event): Fix coding style. (pgtk_set_event_handler): Add selection events. (pgtk_find_selection_owner, pgtk_selection_event): New functions. (pgtk_term_init): Remove call to `pgtk_selection_init'. * src/pgtkterm.h (struct pgtk_display_info): New field `display'. (enum selection_input_event): New struct. New macros for accessing its fields.
Diffstat (limited to 'src/pgtkselect.c')
-rw-r--r--src/pgtkselect.c1871
1 files changed, 1597 insertions, 274 deletions
diff --git a/src/pgtkselect.c b/src/pgtkselect.c
index 76901b9eb1d..a0168c9fad8 100644
--- a/src/pgtkselect.c
+++ b/src/pgtkselect.c
@@ -17,16 +17,6 @@ GNU General Public License for more details.
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ 18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19 19
20/* FIXME: this file needs a major rewrite to replace the use of GTK's
21 own high-level GtkClipboard API with the GDK selection API:
22
23 https://developer-old.gnome.org/gdk3/stable/gdk3-Selections.html
24
25 That way, most of the code can be shared with X, and non-text
26 targets along with drag-and-drop can be supported. GDK implements
27 selections according to the ICCCM, as on X, but its selection API
28 will work on any supported window system. */
29
30/* This should be the first include, as it may set up #defines affecting 20/* This should be the first include, as it may set up #defines affecting
31 interpretation of even the system includes. */ 21 interpretation of even the system includes. */
32#include <config.h> 22#include <config.h>
@@ -35,21 +25,37 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
35#include "pgtkterm.h" 25#include "pgtkterm.h"
36#include "termhooks.h" 26#include "termhooks.h"
37#include "keyboard.h" 27#include "keyboard.h"
38#include "pgtkselect.h" 28#include "atimer.h"
39#include <gdk/gdk.h> 29#include "blockinput.h"
40 30
41static GQuark quark_primary_data = 0; 31/* This file deliberately does not implement INCR, since it adds a
42static GQuark quark_primary_size = 0; 32 bunch of extra code for no real gain, as PGTK isn't supposed to
43static GQuark quark_secondary_data = 0; 33 support X11 anyway. */
44static GQuark quark_secondary_size = 0; 34
45static GQuark quark_clipboard_data = 0; 35/* Advance declaration of structs. */
46static GQuark quark_clipboard_size = 0; 36struct selection_data;
47 37struct prop_location;
48/* ========================================================================== 38
49 39static void pgtk_decline_selection_request (struct selection_input_event *);
50 Internal utility functions 40static bool pgtk_convert_selection (Lisp_Object, Lisp_Object, GdkAtom, bool,
51 41 struct pgtk_display_info *);
52 ========================================================================== */ 42static bool waiting_for_other_props_on_window (GdkDisplay *, GdkWindow *);
43#if 0
44static struct prop_location *expect_property_change (GdkDisplay *, GdkWindow *,
45 GdkAtom, int);
46#endif
47static void unexpect_property_change (struct prop_location *);
48static void wait_for_property_change (struct prop_location *);
49static Lisp_Object pgtk_get_window_property_as_lisp_data (struct pgtk_display_info *,
50 GdkWindow *, GdkAtom,
51 Lisp_Object, GdkAtom, bool);
52static Lisp_Object selection_data_to_lisp_data (struct pgtk_display_info *,
53 const unsigned char *,
54 ptrdiff_t, GdkAtom, int);
55static void lisp_data_to_selection_data (struct pgtk_display_info *, Lisp_Object,
56 struct selection_data *);
57static Lisp_Object pgtk_get_local_selection (Lisp_Object, Lisp_Object,
58 bool, struct pgtk_display_info *);
53 59
54/* From a Lisp_Object, return a suitable frame for selection 60/* From a Lisp_Object, return a suitable frame for selection
55 operations. OBJECT may be a frame, a terminal object, or nil 61 operations. OBJECT may be a frame, a terminal object, or nil
@@ -98,398 +104,1662 @@ frame_for_pgtk_selection (Lisp_Object object)
98 return NULL; 104 return NULL;
99} 105}
100 106
101static GtkClipboard * 107#define LOCAL_SELECTION(selection_symbol, dpyinfo) \
102symbol_to_gtk_clipboard (GtkWidget * widget, Lisp_Object symbol) 108 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
109
110static GdkAtom
111symbol_to_gdk_atom (Lisp_Object sym)
103{ 112{
104 GdkAtom atom; 113 if (NILP (sym))
114 return GDK_NONE;
105 115
106 CHECK_SYMBOL (symbol); 116 if (EQ (sym, QPRIMARY))
107 if (NILP (symbol)) 117 return GDK_SELECTION_PRIMARY;
108 { 118 if (EQ (sym, QSECONDARY))
109 atom = GDK_SELECTION_PRIMARY; 119 return GDK_SELECTION_SECONDARY;
110 } 120 if (EQ (sym, QCLIPBOARD))
111 else if (EQ (symbol, QCLIPBOARD)) 121 return GDK_SELECTION_CLIPBOARD;
122
123 if (!SYMBOLP (sym))
124 emacs_abort ();
125
126 return gdk_atom_intern (SSDATA (SYMBOL_NAME (sym)), FALSE);
127}
128
129static Lisp_Object
130gdk_atom_to_symbol (GdkAtom atom)
131{
132 return intern (gdk_atom_name (atom));
133}
134
135
136
137/* Do protocol to assert ourself as a selection owner.
138 FRAME shall be the owner; it must be a valid GDK frame.
139 Update the Vselection_alist so that we can reply to later requests for
140 our selection. */
141
142static void
143pgtk_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
144 Lisp_Object frame)
145{
146 struct frame *f = XFRAME (frame);
147 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
148 guint32 timestamp = gtk_get_current_event_time ();
149 GdkAtom selection_atom = symbol_to_gdk_atom (selection_name);
150 Lisp_Object targets;
151 ptrdiff_t i, ntargets;
152 GtkTargetEntry *gtargets;
153
154 if (timestamp == GDK_CURRENT_TIME)
155 timestamp = dpyinfo->last_user_time;
156
157 /* Assert ownership over the selection. Ideally we would use the
158 GDK selection API for this as well, but it just doesn't work on
159 Wayland. */
160
161 if (!gdk_selection_owner_set_for_display (dpyinfo->display,
162 FRAME_GDK_WINDOW (f),
163 selection_atom,
164 timestamp, TRUE))
165 signal_error ("Could not assert ownership over selection", selection_name);
166
167 /* Update the local cache */
168 {
169 Lisp_Object selection_data;
170 Lisp_Object prev_value;
171
172 selection_data = list4 (selection_name, selection_value,
173 INT_TO_INTEGER (timestamp), frame);
174 prev_value = LOCAL_SELECTION (selection_name, dpyinfo);
175
176 tset_selection_alist
177 (dpyinfo->terminal,
178 Fcons (selection_data, dpyinfo->terminal->Vselection_alist));
179
180 /* If we already owned the selection, remove the old selection
181 data. Don't use Fdelq as that may quit. */
182 if (!NILP (prev_value))
183 {
184 /* We know it's not the CAR, so it's easy. */
185 Lisp_Object rest = dpyinfo->terminal->Vselection_alist;
186 for (; CONSP (rest); rest = XCDR (rest))
187 if (EQ (prev_value, Fcar (XCDR (rest))))
188 {
189 XSETCDR (rest, XCDR (XCDR (rest)));
190 break;
191 }
192 }
193 }
194
195 /* Announce the targets to the display server. This isn't required
196 on X, but is on Wayland. */
197
198 targets = pgtk_get_local_selection (selection_name, QTARGETS,
199 true, dpyinfo);
200
201 /* GC must not happen inside this segment. */
202 block_input ();
203 gtk_selection_clear_targets (FRAME_GTK_WIDGET (f), selection_atom);
204
205 if (VECTORP (targets))
112 { 206 {
113 atom = GDK_SELECTION_CLIPBOARD; 207 gtargets = xzalloc (sizeof *gtargets * ASIZE (targets));
208 ntargets = 0;
209
210 for (i = 0; i < ASIZE (targets); ++i)
211 {
212 if (SYMBOLP (AREF (targets, i)))
213 gtargets[ntargets++].target
214 = SSDATA (SYMBOL_NAME (AREF (targets, i)));
215 }
216
217 gtk_selection_add_targets (FRAME_GTK_WIDGET (f),
218 selection_atom, gtargets,
219 ntargets);
220
221 xfree (gtargets);
114 } 222 }
115 else if (EQ (symbol, QPRIMARY)) 223 unblock_input ();
224}
225
226static Lisp_Object
227pgtk_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
228 bool local_request, struct pgtk_display_info *dpyinfo)
229{
230 Lisp_Object local_value, tem;
231 Lisp_Object handler_fn, value, check;
232
233 local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
234
235 if (NILP (local_value)) return Qnil;
236
237 /* TIMESTAMP is a special case. */
238 if (EQ (target_type, QTIMESTAMP))
116 { 239 {
117 atom = GDK_SELECTION_PRIMARY; 240 handler_fn = Qnil;
241 value = XCAR (XCDR (XCDR (local_value)));
118 } 242 }
119 else if (EQ (symbol, QSECONDARY)) 243 else
120 { 244 {
121 atom = GDK_SELECTION_SECONDARY; 245 /* Don't allow a quit within the converter.
246 When the user types C-g, he would be surprised
247 if by luck it came during a converter. */
248 specpdl_ref count = SPECPDL_INDEX ();
249 specbind (Qinhibit_quit, Qt);
250
251 CHECK_SYMBOL (target_type);
252 handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
253
254 if (CONSP (handler_fn))
255 handler_fn = XCDR (handler_fn);
256
257 tem = XCAR (XCDR (local_value));
258
259 if (STRINGP (tem))
260 {
261 local_value = Fget_text_property (make_fixnum (0),
262 target_type, tem);
263
264 if (!NILP (local_value))
265 tem = local_value;
266 }
267
268 if (!NILP (handler_fn))
269 value = call3 (handler_fn, selection_symbol,
270 (local_request
271 ? Qnil
272 : target_type),
273 tem);
274 else
275 value = Qnil;
276 value = unbind_to (count, value);
122 } 277 }
123 else if (EQ (symbol, Qt)) 278
279 /* Make sure this value is of a type that we could transmit
280 to another client. */
281
282 check = value;
283 if (CONSP (value)
284 && SYMBOLP (XCAR (value)))
285 check = XCDR (value);
286
287 if (STRINGP (check)
288 || VECTORP (check)
289 || SYMBOLP (check)
290 || INTEGERP (check)
291 || NILP (value))
292 return value;
293 /* Check for a value that CONS_TO_INTEGER could handle. */
294 else if (CONSP (check)
295 && INTEGERP (XCAR (check))
296 && (INTEGERP (XCDR (check))
297 ||
298 (CONSP (XCDR (check))
299 && INTEGERP (XCAR (XCDR (check)))
300 && NILP (XCDR (XCDR (check))))))
301 return value;
302
303 signal_error ("Invalid data returned by selection-conversion function",
304 list2 (handler_fn, value));
305}
306
307static void
308pgtk_decline_selection_request (struct selection_input_event *event)
309{
310 gdk_selection_send_notify (SELECTION_EVENT_REQUESTOR (event),
311 SELECTION_EVENT_SELECTION (event),
312 SELECTION_EVENT_TARGET (event),
313 GDK_NONE, SELECTION_EVENT_TIME (event));
314}
315
316struct selection_data
317{
318 unsigned char *data;
319 ptrdiff_t size;
320 int format;
321 GdkAtom type;
322 bool nofree;
323 GdkAtom property;
324
325 /* This can be set to non-NULL during x_reply_selection_request, if
326 the selection is waiting for an INCR transfer to complete. Don't
327 free these; that's done by unexpect_property_change. */
328 struct prop_location *wait_object;
329 struct selection_data *next;
330};
331
332struct pgtk_selection_request
333{
334 /* The last element in this stack. */
335 struct pgtk_selection_request *last;
336
337 /* Its display info. */
338 struct pgtk_display_info *dpyinfo;
339
340 /* Its selection input event. */
341 struct selection_input_event *request;
342
343 /* Linked list of the above (in support of MULTIPLE targets). */
344 struct selection_data *converted_selections;
345
346 /* "Data" to send a requestor for a failed MULTIPLE subtarget. */
347 GdkAtom conversion_fail_tag;
348
349 /* Whether or not conversion was successful. */
350 bool converted;
351};
352
353/* Stack of selections currently being processed.
354 NULL if all requests have been fully processed. */
355
356struct pgtk_selection_request *selection_request_stack;
357
358static void
359pgtk_push_current_selection_request (struct selection_input_event *se,
360 struct pgtk_display_info *dpyinfo)
361{
362 struct pgtk_selection_request *frame;
363
364 frame = xmalloc (sizeof *frame);
365 frame->converted = false;
366 frame->last = selection_request_stack;
367 frame->request = se;
368 frame->dpyinfo = dpyinfo;
369 frame->converted_selections = NULL;
370 frame->conversion_fail_tag = GDK_NONE;
371
372 selection_request_stack = frame;
373}
374
375static void
376pgtk_pop_current_selection_request (void)
377{
378 struct pgtk_selection_request *tem;
379
380 tem = selection_request_stack;
381 selection_request_stack = selection_request_stack->last;
382
383 xfree (tem);
384}
385
386/* Used as an unwind-protect clause so that, if a selection-converter signals
387 an error, we tell the requestor that we were unable to do what they wanted
388 before we throw to top-level or go into the debugger or whatever. */
389
390static void
391pgtk_selection_request_lisp_error (void)
392{
393 struct selection_data *cs, *next;
394 struct pgtk_selection_request *frame;
395
396 frame = selection_request_stack;
397
398 for (cs = frame->converted_selections; cs; cs = next)
124 { 399 {
125 atom = GDK_SELECTION_SECONDARY; 400 next = cs->next;
401 if (! cs->nofree && cs->data)
402 xfree (cs->data);
403 xfree (cs);
126 } 404 }
127 else 405 frame->converted_selections = NULL;
406
407 if (!frame->converted && frame->dpyinfo->display)
408 pgtk_decline_selection_request (frame->request);
409}
410
411/* This stuff is so that INCR selections are reentrant (that is, so we can
412 be servicing multiple INCR selection requests simultaneously.) I haven't
413 actually tested that yet. */
414
415/* Keep a list of the property changes that are awaited. */
416
417struct prop_location
418{
419 int identifier;
420 GdkDisplay *display;
421 GdkWindow *window;
422 GdkAtom property;
423 int desired_state;
424 bool arrived;
425 struct prop_location *next;
426};
427
428#if 0
429
430static int prop_location_identifier;
431
432#endif
433
434static Lisp_Object property_change_reply;
435
436static struct prop_location *property_change_reply_object;
437
438static struct prop_location *property_change_wait_list;
439
440static void
441set_property_change_object (struct prop_location *location)
442{
443 /* Input must be blocked so we don't get the event before we set these. */
444 if (!input_blocked_p ())
445 emacs_abort ();
446
447 XSETCAR (property_change_reply, Qnil);
448 property_change_reply_object = location;
449}
450
451
452/* Send the reply to a selection request event EVENT. */
453
454static void
455pgtk_reply_selection_request (struct selection_input_event *event,
456 struct pgtk_display_info *dpyinfo)
457{
458 GdkDisplay *display = SELECTION_EVENT_DISPLAY (event);
459 GdkWindow *window = SELECTION_EVENT_REQUESTOR (event);
460 ptrdiff_t bytes_remaining;
461 struct selection_data *cs;
462 struct pgtk_selection_request *frame;
463
464 frame = selection_request_stack;
465
466 block_input ();
467 /* Loop over converted selections, storing them in the requested
468 properties. If data is large, only store the first N bytes
469 (section 2.7.2 of ICCCM). Note that we store the data for a
470 MULTIPLE request in the opposite order; the ICCM says only that
471 the conversion itself must be done in the same order. */
472 for (cs = frame->converted_selections; cs; cs = cs->next)
128 { 473 {
129 atom = 0; 474 if (cs->property == GDK_NONE)
130 error ("Bad selection"); 475 continue;
476
477 bytes_remaining = cs->size;
478 bytes_remaining *= cs->format >> 3;
479
480 gdk_property_change (window, cs->property,
481 cs->type, cs->format,
482 GDK_PROP_MODE_APPEND,
483 cs->data, cs->size);
131 } 484 }
132 485
133 return gtk_widget_get_clipboard (widget, atom); 486 /* Now issue the SelectionNotify event. */
487 gdk_selection_send_notify (window,
488 SELECTION_EVENT_SELECTION (event),
489 SELECTION_EVENT_TARGET (event),
490 SELECTION_EVENT_PROPERTY (event),
491 SELECTION_EVENT_TIME (event));
492 gdk_display_flush (display);
493
494 /* Finish sending the rest of each of the INCR values. This should
495 be improved; there's a chance of deadlock if more than one
496 subtarget in a MULTIPLE selection requires an INCR transfer, and
497 the requestor and Emacs loop waiting on different transfers. */
498 for (cs = frame->converted_selections; cs; cs = cs->next)
499 if (cs->wait_object)
500 {
501 int format_bytes = cs->format / 8;
502
503 /* Must set this inside block_input (). unblock_input may read
504 events and setting property_change_reply in
505 wait_for_property_change is then too late. */
506 set_property_change_object (cs->wait_object);
507 unblock_input ();
508
509 bytes_remaining = cs->size;
510 bytes_remaining *= format_bytes;
511
512 /* Wait for the requestor to ack by deleting the property.
513 This can run Lisp code (process handlers) or signal. */
514 wait_for_property_change (cs->wait_object);
515
516 /* Now write a zero-length chunk to the property to tell the
517 requestor that we're done. */
518 block_input ();
519 if (! waiting_for_other_props_on_window (display, window))
520 gdk_window_set_events (window, 0);
521 gdk_property_change (window, cs->property, cs->type, cs->format,
522 GDK_PROP_MODE_REPLACE, cs->data, 0);
523 }
524
525 gdk_display_sync (display);
526 unblock_input ();
134} 527}
135 528
529
530
531/* Handle a SelectionRequest event EVENT.
532 This is called from keyboard.c when such an event is found in the queue. */
533
136static void 534static void
137selection_type_to_quarks (GdkAtom type, GQuark * quark_data, 535pgtk_handle_selection_request (struct selection_input_event *event)
138 GQuark * quark_size)
139{ 536{
140 if (type == GDK_SELECTION_PRIMARY) 537 guint32 local_selection_time;
538 struct pgtk_display_info *dpyinfo = SELECTION_EVENT_DPYINFO (event);
539 GdkAtom selection = SELECTION_EVENT_SELECTION (event);
540 Lisp_Object selection_symbol = gdk_atom_to_symbol (selection);
541 GdkAtom target = SELECTION_EVENT_TARGET (event);
542 Lisp_Object target_symbol = gdk_atom_to_symbol (target);
543 GdkAtom property = SELECTION_EVENT_PROPERTY (event);
544 Lisp_Object local_selection_data;
545 bool success = false;
546 specpdl_ref count = SPECPDL_INDEX ();
547 bool pushed;
548 Lisp_Object alias, tem;
549
550 alias = Vpgtk_selection_alias_alist;
551
552 FOR_EACH_TAIL_SAFE (alias)
141 { 553 {
142 *quark_data = quark_primary_data; 554 tem = Qnil;
143 *quark_size = quark_primary_size; 555
556 if (CONSP (alias))
557 tem = XCAR (alias);
558
559 if (CONSP (tem)
560 && EQ (XCAR (tem), selection_symbol)
561 && SYMBOLP (XCDR (tem)))
562 {
563 selection_symbol = XCDR (tem);
564 break;
565 }
144 } 566 }
145 else if (type == GDK_SELECTION_SECONDARY) 567
568 pushed = false;
569
570 if (!dpyinfo)
571 goto DONE;
572
573 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
574
575 /* Decline if we don't own any selections. */
576 if (NILP (local_selection_data)) goto DONE;
577
578 /* Decline requests issued prior to our acquiring the selection. */
579 CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
580 guint32, local_selection_time);
581 if (SELECTION_EVENT_TIME (event) != GDK_CURRENT_TIME
582 && local_selection_time > SELECTION_EVENT_TIME (event))
583 goto DONE;
584
585 block_input ();
586 pushed = true;
587 pgtk_push_current_selection_request (event, dpyinfo);
588 record_unwind_protect_void (pgtk_pop_current_selection_request);
589 record_unwind_protect_void (pgtk_selection_request_lisp_error);
590 unblock_input ();
591
592 if (EQ (target_symbol, QMULTIPLE))
146 { 593 {
147 *quark_data = quark_secondary_data; 594 /* For MULTIPLE targets, the event property names a list of atom
148 *quark_size = quark_secondary_size; 595 pairs; the first atom names a target and the second names a
596 non-GDK_NONE property. */
597 GdkWindow *requestor = SELECTION_EVENT_REQUESTOR (event);
598 Lisp_Object multprop;
599 ptrdiff_t j, nselections;
600 struct selection_data cs;
601
602 if (property == GDK_NONE)
603 goto DONE;
604
605 multprop = pgtk_get_window_property_as_lisp_data (dpyinfo,
606 requestor,
607 property,
608 QMULTIPLE,
609 selection,
610 true);
611
612 if (!VECTORP (multprop) || ASIZE (multprop) % 2)
613 goto DONE;
614
615 nselections = ASIZE (multprop) / 2;
616 /* Perform conversions. This can signal. */
617 for (j = 0; j < nselections; j++)
618 {
619 Lisp_Object subtarget = AREF (multprop, 2*j);
620 GdkAtom subproperty = symbol_to_gdk_atom (AREF (multprop, 2 * j + 1));
621 bool subsuccess = false;
622
623 if (subproperty != GDK_NONE)
624 subsuccess = pgtk_convert_selection (selection_symbol, subtarget,
625 subproperty, true, dpyinfo);
626 if (!subsuccess)
627 ASET (multprop, 2*j+1, Qnil);
628 }
629 /* Save conversion results */
630 lisp_data_to_selection_data (dpyinfo, multprop, &cs);
631 gdk_property_change (requestor, property,
632 cs.type, cs.format,
633 GDK_PROP_MODE_REPLACE,
634 cs.data, cs.size);
635 success = true;
149 } 636 }
150 else if (type == GDK_SELECTION_CLIPBOARD) 637 else
151 { 638 {
152 *quark_data = quark_clipboard_data; 639 if (property == GDK_NONE)
153 *quark_size = quark_clipboard_size; 640 property = SELECTION_EVENT_TARGET (event);
641
642 success = pgtk_convert_selection (selection_symbol,
643 target_symbol, property,
644 false, dpyinfo);
154 } 645 }
646
647 DONE:
648
649 if (pushed)
650 selection_request_stack->converted = true;
651
652 if (success)
653 pgtk_reply_selection_request (event, dpyinfo);
155 else 654 else
156 /* FIXME: Is it safe to use 'error' here? */ 655 pgtk_decline_selection_request (event);
157 error ("Unknown selection type."); 656
657 /* Run the `pgtk-sent-selection-functions' abnormal hook. */
658 if (!NILP (Vpgtk_sent_selection_functions)
659 && !BASE_EQ (Vpgtk_sent_selection_functions, Qunbound))
660 CALLN (Frun_hook_with_args, Qpgtk_sent_selection_functions,
661 selection_symbol, target_symbol, success ? Qt : Qnil);
662
663 unbind_to (count, Qnil);
158} 664}
159 665
160static void 666/* Perform the requested selection conversion, and write the data to
161get_func (GtkClipboard * cb, GtkSelectionData * data, guint info, 667 the converted_selections linked list, where it can be accessed by
162 gpointer user_data_or_owner) 668 x_reply_selection_request. If FOR_MULTIPLE, write out
669 the data even if conversion fails, using conversion_fail_tag.
670
671 Return true if (and only if) successful. */
672
673static bool
674pgtk_convert_selection (Lisp_Object selection_symbol,
675 Lisp_Object target_symbol, GdkAtom property,
676 bool for_multiple, struct pgtk_display_info *dpyinfo)
163{ 677{
164 GObject *obj = G_OBJECT (user_data_or_owner); 678 Lisp_Object lisp_selection;
165 const char *str; 679 struct selection_data *cs;
166 int size; 680 struct pgtk_selection_request *frame;
167 GQuark quark_data, quark_size; 681
682 lisp_selection
683 = pgtk_get_local_selection (selection_symbol, target_symbol,
684 false, dpyinfo);
168 685
169 selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data, 686 frame = selection_request_stack;
170 &quark_size);
171 687
172 str = g_object_get_qdata (obj, quark_data); 688 /* A nil return value means we can't perform the conversion. */
173 size = GPOINTER_TO_SIZE (g_object_get_qdata (obj, quark_size)); 689 if (NILP (lisp_selection)
174 gtk_selection_data_set_text (data, str, size); 690 || (CONSP (lisp_selection) && NILP (XCDR (lisp_selection))))
691 {
692 if (for_multiple)
693 {
694 cs = xmalloc (sizeof *cs);
695 cs->data = ((unsigned char *)
696 &selection_request_stack->conversion_fail_tag);
697 cs->size = 1;
698 cs->format = 32;
699 cs->type = GDK_SELECTION_TYPE_ATOM;
700 cs->nofree = true;
701 cs->property = property;
702 cs->wait_object = NULL;
703 cs->next = frame->converted_selections;
704 frame->converted_selections = cs;
705 }
706
707 return false;
708 }
709
710 /* Otherwise, record the converted selection to binary. */
711 cs = xmalloc (sizeof *cs);
712 cs->data = NULL;
713 cs->nofree = true;
714 cs->property = property;
715 cs->wait_object = NULL;
716 cs->next = frame->converted_selections;
717 frame->converted_selections = cs;
718 lisp_data_to_selection_data (dpyinfo, lisp_selection, cs);
719 return true;
175} 720}
176 721
722
723
724/* Handle a SelectionClear event EVENT, which indicates that some
725 client cleared out our previously asserted selection.
726 This is called from keyboard.c when such an event is found in the queue. */
727
177static void 728static void
178clear_func (GtkClipboard * cb, gpointer user_data_or_owner) 729pgtk_handle_selection_clear (struct selection_input_event *event)
179{ 730{
180 GObject *obj = G_OBJECT (user_data_or_owner); 731 GdkAtom selection = SELECTION_EVENT_SELECTION (event);
181 GQuark quark_data, quark_size; 732 guint32 changed_owner_time = SELECTION_EVENT_TIME (event);
182 733
183 selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data, 734 Lisp_Object selection_symbol, local_selection_data;
184 &quark_size); 735 guint32 local_selection_time;
736 struct pgtk_display_info *dpyinfo = SELECTION_EVENT_DPYINFO (event);
737 Lisp_Object Vselection_alist;
185 738
186 g_object_set_qdata (obj, quark_data, NULL); 739 if (!dpyinfo) return;
187 g_object_set_qdata (obj, quark_size, 0);
188}
189 740
741 selection_symbol = gdk_atom_to_symbol (selection);
742 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
190 743
191/* ========================================================================== 744 /* Well, we already believe that we don't own it, so that's just fine. */
745 if (NILP (local_selection_data)) return;
192 746
193 Functions used externally 747 CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
748 guint32, local_selection_time);
194 749
195 ========================================================================== */ 750 /* We have reasserted the selection since this SelectionClear was
751 generated, so we can disregard it. */
752 if (changed_owner_time != GDK_CURRENT_TIME
753 && local_selection_time > changed_owner_time)
754 return;
755
756 /* Otherwise, really clear. Don't use Fdelq as that may quit. */
757 Vselection_alist = dpyinfo->terminal->Vselection_alist;
758 if (EQ (local_selection_data, CAR (Vselection_alist)))
759 Vselection_alist = XCDR (Vselection_alist);
760 else
761 {
762 Lisp_Object rest;
763 for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
764 if (EQ (local_selection_data, CAR (XCDR (rest))))
765 {
766 XSETCDR (rest, XCDR (XCDR (rest)));
767 break;
768 }
769 }
770 tset_selection_alist (dpyinfo->terminal, Vselection_alist);
771
772 /* Run the `pgtk-lost-selection-functions' abnormal hook. */
773 CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions, selection_symbol);
774
775 redisplay_preserve_echo_area (20);
776}
777
778void
779pgtk_handle_selection_event (struct selection_input_event *event)
780{
781 if (event->kind != SELECTION_REQUEST_EVENT)
782 pgtk_handle_selection_clear (event);
783 else
784 pgtk_handle_selection_request (event);
785}
786
787/* Clear all selections that were made from frame F.
788 We do this when about to delete a frame. */
196 789
197void 790void
198pgtk_selection_init (void) 791pgtk_clear_frame_selections (struct frame *f)
792{
793 Lisp_Object frame;
794 Lisp_Object rest;
795 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
796 struct terminal *t = dpyinfo->terminal;
797
798 XSETFRAME (frame, f);
799
800 /* Delete elements from the beginning of Vselection_alist. */
801 while (CONSP (t->Vselection_alist)
802 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist)))))))
803 {
804 /* Run the `pgtk-lost-selection-functions' abnormal hook. */
805 CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions,
806 Fcar (Fcar (t->Vselection_alist)));
807
808 tset_selection_alist (t, XCDR (t->Vselection_alist));
809 }
810
811 /* Delete elements after the beginning of Vselection_alist. */
812 for (rest = t->Vselection_alist; CONSP (rest); rest = XCDR (rest))
813 if (CONSP (XCDR (rest))
814 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
815 {
816 CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions,
817 XCAR (XCAR (XCDR (rest))));
818 XSETCDR (rest, XCDR (XCDR (rest)));
819 break;
820 }
821}
822
823/* True if any properties for DISPLAY and WINDOW
824 are on the list of what we are waiting for. */
825
826static bool
827waiting_for_other_props_on_window (GdkDisplay *display, GdkWindow *window)
828{
829 for (struct prop_location *p = property_change_wait_list; p; p = p->next)
830 if (p->display == display && p->window == window)
831 return true;
832 return false;
833}
834
835/* Add an entry to the list of property changes we are waiting for.
836 DISPLAY, WINDOW, PROPERTY, STATE describe what we will wait for.
837 The return value is a number that uniquely identifies
838 this awaited property change. */
839
840/* Currently unused -- uncomment later if we decide to implement INCR
841 transfer for X. */
842
843#if 0
844
845static struct prop_location *
846expect_property_change (GdkDisplay *display, GdkWindow *window,
847 GdkAtom property, int state)
848{
849 struct prop_location *pl = xmalloc (sizeof *pl);
850 pl->identifier = ++prop_location_identifier;
851 pl->display = display;
852 pl->window = window;
853 pl->property = property;
854 pl->desired_state = state;
855 pl->next = property_change_wait_list;
856 pl->arrived = false;
857 property_change_wait_list = pl;
858 return pl;
859}
860
861#endif
862
863/* Delete an entry from the list of property changes we are waiting for.
864 IDENTIFIER is the number that uniquely identifies the entry. */
865
866static void
867unexpect_property_change (struct prop_location *location)
199{ 868{
200 if (quark_primary_data == 0) 869 struct prop_location *prop, **pprev = &property_change_wait_list;
870
871 for (prop = property_change_wait_list; prop; prop = *pprev)
201 { 872 {
202 quark_primary_data = g_quark_from_static_string ("pgtk-primary-data"); 873 if (prop == location)
203 quark_primary_size = g_quark_from_static_string ("pgtk-primary-size"); 874 {
204 quark_secondary_data = 875 *pprev = prop->next;
205 g_quark_from_static_string ("pgtk-secondary-data"); 876 xfree (prop);
206 quark_secondary_size = 877 break;
207 g_quark_from_static_string ("pgtk-secondary-size"); 878 }
208 quark_clipboard_data = 879 else
209 g_quark_from_static_string ("pgtk-clipboard-data"); 880 pprev = &prop->next;
210 quark_clipboard_size =
211 g_quark_from_static_string ("pgtk-clipboard-size");
212 } 881 }
213} 882}
214 883
884/* Remove the property change expectation element for IDENTIFIER. */
885
886static void
887wait_for_property_change_unwind (void *loc)
888{
889 struct prop_location *location = loc;
890
891 unexpect_property_change (location);
892 if (location == property_change_reply_object)
893 property_change_reply_object = 0;
894}
895
896/* Actually wait for a property change.
897 IDENTIFIER should be the value that expect_property_change returned. */
898
899static void
900wait_for_property_change (struct prop_location *location)
901{
902 specpdl_ref count = SPECPDL_INDEX ();
903
904 /* Make sure to do unexpect_property_change if we quit or err. */
905 record_unwind_protect_ptr (wait_for_property_change_unwind, location);
906
907 /* See comment in x_reply_selection_request about setting
908 property_change_reply. Do not do it here. */
909
910 /* If the event we are waiting for arrives beyond here, it will set
911 property_change_reply, because property_change_reply_object says so. */
912 if (! location->arrived)
913 {
914 intmax_t timeout = max (0, 5000);
915 intmax_t secs = timeout / 1000;
916 int nsecs = (timeout % 1000) * 1000000;
917
918 wait_reading_process_output (secs, nsecs, 0, false,
919 property_change_reply, NULL, 0);
920
921 if (NILP (XCAR (property_change_reply)))
922 error ("Timed out waiting for property-notify event");
923 }
924
925 unbind_to (count, Qnil);
926}
927
928/* Called from the big filter in response to a PropertyNotify
929 event. */
930
215void 931void
216pgtk_selection_lost (GtkWidget * widget, GdkEventSelection * event, 932pgtk_handle_property_notify (GdkEventProperty *event)
217 gpointer user_data)
218{ 933{
219 GQuark quark_data, quark_size; 934 struct prop_location *rest;
935 GdkDisplay *dpy;
936
937 dpy = gdk_window_get_display (event->window);
220 938
221 selection_type_to_quarks (event->selection, &quark_data, &quark_size); 939 for (rest = property_change_wait_list; rest; rest = rest->next)
940 {
941 if (!rest->arrived
942 && rest->property == event->atom
943 && rest->window == event->window
944 && rest->display == dpy
945 && rest->desired_state == event->state)
946 {
947 rest->arrived = true;
222 948
223 g_object_set_qdata (G_OBJECT (widget), quark_data, NULL); 949 /* If this is the one wait_for_property_change is waiting for,
224 g_object_set_qdata (G_OBJECT (widget), quark_size, 0); 950 tell it to wake up. */
951 if (rest == property_change_reply_object)
952 XSETCAR (property_change_reply, Qt);
953
954 return;
955 }
956 }
225} 957}
226 958
227static bool 959static void
228pgtk_selection_usable (void) 960pgtk_display_selection_waiting_message (struct atimer *timer)
229{ 961{
230 if (pgtk_enable_selection_on_multi_display) 962 Lisp_Object val;
231 return true;
232 963
233 /* Gdk uses `gdk_display_get_default' when handling selections, so 964 val = build_string ("Waiting for reply from selection owner...");
234 selections don't work properly when Emacs is connected to 965 message3_nolog (val);
235 multiple displays. */ 966}
236 967
237 GdkDisplayManager *dpyman = gdk_display_manager_get (); 968static void
238 GSList *list = gdk_display_manager_list_displays (dpyman); 969pgtk_cancel_atimer (void *atimer)
239 int len = g_slist_length (list); 970{
240 g_slist_free (list); 971 cancel_atimer (atimer);
241 return len < 2;
242} 972}
243 973
244/* ========================================================================== 974
975/* Variables for communication with pgtk_handle_selection_notify. */
976static GdkAtom reading_which_selection;
977static Lisp_Object reading_selection_reply;
978static GdkWindow *reading_selection_window;
245 979
246 Lisp Defuns 980/* Do protocol to read selection-data from the window server.
981 Converts this to Lisp data and returns it.
982 FRAME is the frame whose window shall request the selection. */
247 983
248 ========================================================================== */ 984static Lisp_Object
985pgtk_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
986 Lisp_Object time_stamp, Lisp_Object frame)
987{
988 struct frame *f = XFRAME (frame);
989 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
990 GdkWindow *requestor_window = FRAME_GDK_WINDOW (f);
991 guint32 requestor_time = dpyinfo->last_user_time;
992 GdkAtom selection_atom = symbol_to_gdk_atom (selection_symbol);
993 GdkAtom type_atom = (CONSP (target_type)
994 ? symbol_to_gdk_atom (XCAR (target_type))
995 : symbol_to_gdk_atom (target_type));
996 struct atimer *delayed_message;
997 struct timespec message_interval;
998 specpdl_ref count;
999
1000 count = SPECPDL_INDEX ();
1001
1002 if (!FRAME_LIVE_P (f))
1003 return unbind_to (count, Qnil);
1004
1005 if (!NILP (time_stamp))
1006 CONS_TO_INTEGER (time_stamp, guint32, requestor_time);
1007
1008 block_input ();
1009 /* Prepare to block until the reply has been read. */
1010 reading_selection_window = requestor_window;
1011 reading_which_selection = selection_atom;
1012 XSETCAR (reading_selection_reply, Qnil);
1013
1014 gdk_selection_convert (requestor_window, selection_atom,
1015 type_atom, requestor_time);
1016 unblock_input ();
1017
1018 /* It should not be necessary to stop handling selection requests
1019 during this time. In fact, the SAVE_TARGETS mechanism requires
1020 us to handle a clipboard manager's requests before it returns
1021 GDK_SELECTION_NOTIFY. */
1022
1023 message_interval = make_timespec (1, 0);
1024 delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
1025 pgtk_display_selection_waiting_message,
1026 NULL);
1027 record_unwind_protect_ptr (pgtk_cancel_atimer, delayed_message);
1028
1029 /* This allows quits. Also, don't wait forever. */
1030 intmax_t timeout = max (0, 5000);
1031 intmax_t secs = timeout / 1000;
1032 int nsecs = (timeout % 1000) * 1000000;
1033
1034 wait_reading_process_output (secs, nsecs, 0, false,
1035 reading_selection_reply, NULL, 0);
1036
1037 if (NILP (XCAR (reading_selection_reply)))
1038 error ("Timed out waiting for reply from selection owner");
1039 if (EQ (XCAR (reading_selection_reply), Qlambda))
1040 return unbind_to (count, Qnil);
1041
1042 /* Otherwise, the selection is waiting for us on the requested property. */
1043 return unbind_to (count,
1044 pgtk_get_window_property_as_lisp_data (dpyinfo,
1045 requestor_window,
1046 GDK_NONE,
1047 target_type,
1048 selection_atom,
1049 false));
1050}
249 1051
1052/* Subroutines of pgtk_get_window_property_as_lisp_data */
250 1053
251DEFUN ("pgtk-own-selection-internal", Fpgtk_own_selection_internal, Spgtk_own_selection_internal, 2, 3, 0, 1054static ptrdiff_t
252 doc: /* Assert an X selection of type SELECTION and value VALUE. 1055pgtk_size_for_format (gint format)
253SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. 1056{
254\(Those are literal upper-case symbol names, since that's what X expects.) 1057 switch (format)
255VALUE is typically a string, or a cons of two markers, but may be 1058 {
256anything that the functions on `selection-converter-alist' know about. 1059 case 8:
1060 return sizeof (unsigned char);
1061 case 16:
1062 return sizeof (unsigned short);
1063 case 32:
1064 return sizeof (unsigned long);
1065
1066 default:
1067 emacs_abort ();
1068 }
1069}
257 1070
258FRAME should be a frame that should own the selection. If omitted or 1071/* Use xfree, not g_free, to free the data obtained with this function. */
259nil, it defaults to the selected frame. */) 1072
260 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame) 1073static void
1074pgtk_get_window_property (GdkWindow *window, unsigned char **data_ret,
1075 ptrdiff_t *bytes_ret, GdkAtom *actual_type_ret,
1076 int *actual_format_ret, unsigned long *actual_size_ret)
261{ 1077{
262 Lisp_Object successful_p = Qnil; 1078 gint length, actual_format;
263 Lisp_Object target_symbol, rest; 1079 unsigned char *data;
264 GtkClipboard *cb; 1080 ptrdiff_t element_size;
265 struct frame *f; 1081 void *xdata;
266 GQuark quark_data, quark_size; 1082 GdkAtom actual_type;
1083 unsigned long i;
1084 unsigned int *idata;
1085 unsigned long *ldata;
1086
1087 data = NULL;
1088
1089 length = gdk_selection_property_get (window, &data,
1090 &actual_type,
1091 &actual_format);
1092
1093 if (!data)
1094 {
1095 *data_ret = NULL;
1096 *actual_type_ret = GDK_NONE;
1097 *bytes_ret = 0;
1098 *actual_format_ret = 8;
1099 *actual_size_ret = 0;
267 1100
268 check_window_system (NULL); 1101 return;
1102 }
269 1103
270 if (!pgtk_selection_usable ()) 1104 if (actual_type == GDK_SELECTION_TYPE_ATOM
271 return Qnil; 1105 || actual_type == gdk_atom_intern_static_string ("ATOM_PAIR"))
1106 {
1107 /* GDK should not allow anything else. */
1108 eassert (actual_format == 32);
272 1109
273 if (NILP (frame)) 1110 length = length / sizeof (GdkAtom);
274 frame = selected_frame; 1111 xdata = xmalloc (sizeof (GdkAtom) * length);
275 if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame))) 1112 memcpy (xdata, data, 1 + length * sizeof (GdkAtom));
276 error ("pgtk selection unavailable for this frame"); 1113
277 f = XFRAME (frame); 1114 g_free (data);
1115
1116 *data_ret = xdata;
1117 *actual_type_ret = actual_type;
1118 *bytes_ret = length * sizeof (GdkAtom);
1119 *actual_format_ret = 32;
1120 *actual_size_ret = length;
278 1121
279 cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection); 1122 return;
280 selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data, 1123 }
281 &quark_size); 1124
1125 element_size = pgtk_size_for_format (actual_format);
1126 length = length / element_size;
282 1127
283 /* We only support copy of text. */ 1128 /* Add an extra byte on the end. GDK guarantees that it is
284 target_symbol = QTEXT; 1129 NULL. */
285 if (STRINGP (value)) 1130 xdata = xmalloc (1 + element_size * length);
1131 memcpy (xdata, data, 1 + element_size * length);
1132
1133 if (actual_format == 32 && LONG_WIDTH > 32)
286 { 1134 {
287 GtkTargetList *list; 1135 ldata = (typeof (ldata)) data;
288 GtkTargetEntry *targets; 1136 idata = xdata;
289 gint n_targets;
290 GtkWidget *widget;
291 1137
292 list = gtk_target_list_new (NULL, 0); 1138 for (i = 0; i < length; ++i)
293 gtk_target_list_add_text_targets (list, 0); 1139 idata[i] = ldata[i];
294 1140
295 { 1141 /* There is always enough space in idata. */
296 /* text/plain: Strings encoded by Gtk are not correctly decoded by Chromium(Wayland). */ 1142 idata[length] = 0;
297 GdkAtom atom_text_plain = gdk_atom_intern ("text/plain", false); 1143 *bytes_ret = sizeof *idata * length;
298 gtk_target_list_remove (list, atom_text_plain); 1144 }
299 } 1145 else
1146 /* I think GDK itself prevents element_size from exceeding the
1147 length at which this computation fails. */
1148 *bytes_ret = element_size * length;
1149
1150 /* Now free the original `data' allocated by GDK. */
1151 g_free (data);
1152
1153 *data_ret = xdata;
1154 *actual_type_ret = GDK_NONE;
1155 *actual_size_ret = length;
1156 *actual_format_ret = actual_format;
1157 *actual_type_ret = actual_type;
1158}
1159
1160static Lisp_Object
1161pgtk_get_window_property_as_lisp_data (struct pgtk_display_info *dpyinfo,
1162 GdkWindow *window, GdkAtom property,
1163 Lisp_Object target_type, GdkAtom selection_atom,
1164 bool for_multiple)
1165{
1166 GdkAtom actual_type;
1167 int actual_format;
1168 unsigned long actual_size;
1169 unsigned char *data = 0;
1170 ptrdiff_t bytes = 0;
1171 Lisp_Object val;
1172 GdkDisplay *display = dpyinfo->display;
1173
1174 pgtk_get_window_property (window, &data, &bytes,
1175 &actual_type, &actual_format,
1176 &actual_size);
1177
1178 if (!data)
1179 {
1180 if (for_multiple)
1181 return Qnil;
1182
1183 if (gdk_selection_owner_get_for_display (display, selection_atom))
1184 {
1185 AUTO_STRING (format, "Selection owner couldn't convert: %s");
1186 CALLN (Fmessage, format,
1187 actual_type
1188 ? list2 (target_type,
1189 gdk_atom_to_symbol (actual_type))
1190 : target_type);
1191 return Qnil;
1192 }
1193 else
1194 {
1195 AUTO_STRING (format, "No selection: %s");
1196 CALLN (Fmessage, format,
1197 gdk_atom_to_symbol (selection_atom));
1198 return Qnil;
1199 }
1200 }
300 1201
301 targets = gtk_target_table_new_from_list (list, &n_targets); 1202 if (!for_multiple && property != GDK_NONE)
1203 gdk_property_delete (window, property);
302 1204
303 int size = SBYTES (value); 1205 /* It's been read. Now convert it to a lisp object in some semi-rational
304 gchar *str = xmalloc (size + 1); 1206 manner. */
305 memcpy (str, SSDATA (value), size); 1207 val = selection_data_to_lisp_data (dpyinfo, data, bytes,
306 str[size] = '\0'; 1208 actual_type, actual_format);
307 1209
308 widget = FRAME_GTK_WIDGET (f); 1210 /* Use xfree, not g_free, because pgtk_get_window_property calls
309 g_object_set_qdata_full (G_OBJECT (widget), quark_data, str, xfree); 1211 xmalloc itself. */
310 g_object_set_qdata_full (G_OBJECT (widget), quark_size, 1212 xfree (data);
311 GSIZE_TO_POINTER (size), NULL); 1213 return val;
1214}
1215
1216
1217
1218/* These functions convert from the selection data read from the
1219 server into something that we can use from Lisp, and vice versa.
1220
1221 Type: Format: Size: Lisp Type:
1222 ----- ------- ----- -----------
1223 * 8 * String
1224 ATOM 32 1 Symbol
1225 ATOM 32 > 1 Vector of Symbols
1226 * 16 1 Integer
1227 * 16 > 1 Vector of Integers
1228 * 32 1 if small enough: fixnum
1229 otherwise: bignum
1230 * 32 > 1 Vector of the above
1231
1232 When converting an object to C, it may be of the form (SYMBOL
1233 . <data>) where SYMBOL is what we should claim that the type is.
1234 Format and representation are as above.
1235
1236 Important: When format is 32, data should contain an array of int,
1237 not an array of long as GDK returns. Unless TYPE is also
1238 GDK_SELECTION_TYPE_ATOM, in which case data should be an array of
1239 GdkAtom. This makes a difference when sizeof (long) != sizeof
1240 (int). */
1241
1242static Lisp_Object
1243selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo,
1244 const unsigned char *data,
1245 ptrdiff_t size, GdkAtom type, int format)
1246{
1247 if (type == gdk_atom_intern_static_string ("NULL"))
1248 return QNULL;
1249 /* Convert any 8-bit data to a string, for compactness. */
1250 else if (format == 8)
1251 {
1252 Lisp_Object str, lispy_type;
1253
1254 str = make_unibyte_string ((char *) data, size);
1255 /* Indicate that this string is from foreign selection by a text
1256 property `foreign-selection' so that the caller of
1257 x-get-selection-internal (usually x-get-selection) can know
1258 that the string must be decode. */
1259 if (type == gdk_atom_intern_static_string ("COMPOUND_TEXT"))
1260 lispy_type = QCOMPOUND_TEXT;
1261 else if (type == gdk_atom_intern_static_string ("UTF8_STRING"))
1262 lispy_type = QUTF8_STRING;
1263 else
1264 lispy_type = QSTRING;
1265
1266 Fput_text_property (make_fixnum (0), make_fixnum (size),
1267 Qforeign_selection, lispy_type, str);
1268 return str;
1269 }
1270 /* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to
1271 a vector of symbols. */
1272 else if (format == 32
1273 && (type == GDK_SELECTION_TYPE_ATOM
1274 /* Treat ATOM_PAIR type similar to list of atoms. */
1275 || type == gdk_atom_intern_static_string ("ATOM_PAIR")))
1276 {
1277 ptrdiff_t i;
1278 GdkAtom *idata = (GdkAtom *) data;
312 1279
313 if (gtk_clipboard_set_with_owner (cb, 1280 if (size == sizeof (GdkAtom))
314 targets, n_targets, 1281 return gdk_atom_to_symbol (idata[0]);
315 get_func, clear_func, 1282 else
316 G_OBJECT (FRAME_GTK_WIDGET (f))))
317 { 1283 {
318 successful_p = Qt; 1284 Lisp_Object v = make_nil_vector (size / sizeof (GdkAtom));
1285
1286 for (i = 0; i < size / sizeof (GdkAtom); i++)
1287 ASET (v, i, gdk_atom_to_symbol (idata[i]));
1288 return v;
319 } 1289 }
320 gtk_clipboard_set_can_store (cb, NULL, 0); 1290 }
1291
1292 /* Convert a single 16-bit number or a small 32-bit number to a Lisp_Int.
1293 If the number is 32 bits and won't fit in a Lisp_Int, convert it
1294 to a bignum.
321 1295
322 gtk_target_table_free (targets, n_targets); 1296 INTEGER is a signed type, CARDINAL is unsigned.
323 gtk_target_list_unref (list); 1297 Assume any other types are unsigned as well.
1298 */
1299 else if (format == 32 && size == sizeof (int))
1300 {
1301 if (type == GDK_SELECTION_TYPE_INTEGER)
1302 return INT_TO_INTEGER (((int *) data) [0]);
1303 else
1304 return INT_TO_INTEGER (((unsigned int *) data) [0]);
1305 }
1306 else if (format == 16 && size == sizeof (short))
1307 {
1308 if (type == GDK_SELECTION_TYPE_INTEGER)
1309 return make_fixnum (((short *) data) [0]);
1310 else
1311 return make_fixnum (((unsigned short *) data) [0]);
1312 }
1313 /* Convert any other kind of data to a vector of numbers, represented
1314 as above (as an integer, or a cons of two 16 bit integers.)
1315 */
1316 else if (format == 16)
1317 {
1318 ptrdiff_t i;
1319 Lisp_Object v = make_uninit_vector (size / 2);
1320
1321 if (type == GDK_SELECTION_TYPE_INTEGER)
1322 {
1323 for (i = 0; i < size / 2; i++)
1324 {
1325 short j = ((short *) data) [i];
1326 ASET (v, i, make_fixnum (j));
1327 }
1328 }
1329 else
1330 {
1331 for (i = 0; i < size / 2; i++)
1332 {
1333 unsigned short j = ((unsigned short *) data) [i];
1334 ASET (v, i, make_fixnum (j));
1335 }
1336 }
1337 return v;
324 } 1338 }
1339 else
1340 {
1341 ptrdiff_t i;
1342 Lisp_Object v = make_nil_vector (size / sizeof (gint));
1343
1344 if (type == GDK_SELECTION_TYPE_INTEGER)
1345 {
1346 for (i = 0; i < size / sizeof (gint); i++)
1347 {
1348 int j = ((gint *) data) [i];
1349 ASET (v, i, INT_TO_INTEGER (j));
1350 }
1351 }
1352 else
1353 {
1354 for (i = 0; i < size / sizeof (gint); i++)
1355 {
1356 unsigned int j = ((unsigned int *) data) [i];
1357 ASET (v, i, INT_TO_INTEGER (j));
1358 }
1359 }
1360 return v;
1361 }
1362}
1363
1364/* Convert OBJ to an X long value, and return it as unsigned long.
1365 OBJ should be an integer or a cons representing an integer.
1366 Treat values in the range X_LONG_MAX + 1 .. X_ULONG_MAX as X
1367 unsigned long values: in theory these values are supposed to be
1368 signed but in practice unsigned 32-bit data are communicated via X
1369 selections and we need to support that. */
1370static unsigned long
1371cons_to_gdk_long (Lisp_Object obj)
1372{
1373 if (G_MAXUINT32 <= INTMAX_MAX
1374 || NILP (Fnatnump (CONSP (obj) ? XCAR (obj) : obj)))
1375 return cons_to_signed (obj, 0, min (G_MAXUINT32, INTMAX_MAX));
1376 else
1377 return cons_to_unsigned (obj, G_MAXUINT32);
1378}
1379
1380/* Use xfree, not XFree, to free the data obtained with this function. */
1381
1382static void
1383lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo,
1384 Lisp_Object obj, struct selection_data *cs)
1385{
1386 Lisp_Object type = Qnil;
325 1387
326 if (!BASE_EQ (Vpgtk_sent_selection_hooks, Qunbound)) 1388 eassert (cs != NULL);
1389 cs->nofree = false;
1390
1391 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
327 { 1392 {
328 /* FIXME: Use run-hook-with-args! */ 1393 type = XCAR (obj);
329 for (rest = Vpgtk_sent_selection_hooks; CONSP (rest); 1394 obj = XCDR (obj);
330 rest = Fcdr (rest)) 1395 if (CONSP (obj) && NILP (XCDR (obj)))
331 call3 (Fcar (rest), selection, target_symbol, successful_p); 1396 obj = XCAR (obj);
332 } 1397 }
333 1398
1399 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
1400 { /* This is not the same as declining */
1401 cs->format = 32;
1402 cs->size = 0;
1403 cs->data = NULL;
1404 type = QNULL;
1405 }
1406 else if (STRINGP (obj))
1407 {
1408 if (SCHARS (obj) < SBYTES (obj))
1409 /* OBJ is a multibyte string containing a non-ASCII char. */
1410 signal_error ("Non-ASCII string must be encoded in advance", obj);
1411 if (NILP (type))
1412 type = QSTRING;
1413 cs->format = 8;
1414 cs->size = SBYTES (obj);
1415 cs->data = SDATA (obj);
1416 cs->nofree = true;
1417 }
1418 else if (SYMBOLP (obj))
1419 {
1420 void *data = xmalloc (sizeof (GdkAtom) + 1);
1421 GdkAtom *x_atom_ptr = data;
1422 cs->data = data;
1423 cs->format = 32;
1424 cs->size = 1;
1425 cs->data[sizeof (GdkAtom)] = 0;
1426 *x_atom_ptr = symbol_to_gdk_atom (obj);
1427 if (NILP (type)) type = QATOM;
1428 }
1429 else if (RANGED_FIXNUMP (SHRT_MIN, obj, SHRT_MAX))
1430 {
1431 void *data = xmalloc (sizeof (short) + 1);
1432 short *short_ptr = data;
1433 cs->data = data;
1434 cs->format = 16;
1435 cs->size = 1;
1436 cs->data[sizeof (short)] = 0;
1437 *short_ptr = XFIXNUM (obj);
1438 if (NILP (type)) type = QINTEGER;
1439 }
1440 else if (INTEGERP (obj)
1441 || (CONSP (obj) && INTEGERP (XCAR (obj))
1442 && (FIXNUMP (XCDR (obj))
1443 || (CONSP (XCDR (obj))
1444 && FIXNUMP (XCAR (XCDR (obj)))))))
1445 {
1446 void *data = xmalloc (sizeof (unsigned long) + 1);
1447 unsigned long *x_long_ptr = data;
1448 cs->data = data;
1449 cs->format = 32;
1450 cs->size = 1;
1451 cs->data[sizeof (unsigned long)] = 0;
1452 *x_long_ptr = cons_to_gdk_long (obj);
1453 if (NILP (type)) type = QINTEGER;
1454 }
1455 else if (VECTORP (obj))
1456 {
1457 /* Lisp_Vectors may represent a set of ATOMs;
1458 a set of 16 or 32 bit INTEGERs;
1459 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
1460 */
1461 ptrdiff_t i;
1462 ptrdiff_t size = ASIZE (obj);
1463
1464 if (SYMBOLP (AREF (obj, 0)))
1465 /* This vector is an ATOM set */
1466 {
1467 void *data;
1468 GdkAtom *x_atoms;
1469 if (NILP (type)) type = QATOM;
1470 for (i = 0; i < size; i++)
1471 if (!SYMBOLP (AREF (obj, i)))
1472 signal_error ("All elements of selection vector must have same type", obj);
1473
1474 cs->data = data = xnmalloc (size, sizeof *x_atoms);
1475 x_atoms = data;
1476 cs->format = 32;
1477 cs->size = size;
1478 for (i = 0; i < size; i++)
1479 x_atoms[i] = symbol_to_gdk_atom (AREF (obj, i));
1480 }
1481 else
1482 /* This vector is an INTEGER set, or something like it */
1483 {
1484 int format = 16;
1485 int data_size = sizeof (short);
1486 void *data;
1487 unsigned long *x_atoms;
1488 short *shorts;
1489 if (NILP (type)) type = QINTEGER;
1490 for (i = 0; i < size; i++)
1491 {
1492 if (! RANGED_FIXNUMP (SHRT_MIN, AREF (obj, i), SHRT_MAX))
1493 {
1494 /* Use sizeof (long) even if it is more than 32 bits.
1495 See comment in x_get_window_property and
1496 x_fill_property_data. */
1497 data_size = sizeof (long);
1498 format = 32;
1499 break;
1500 }
1501 }
1502 cs->data = data = xnmalloc (size, data_size);
1503 x_atoms = data;
1504 shorts = data;
1505 cs->format = format;
1506 cs->size = size;
1507 for (i = 0; i < size; i++)
1508 {
1509 if (format == 32)
1510 x_atoms[i] = cons_to_gdk_long (AREF (obj, i));
1511 else
1512 shorts[i] = XFIXNUM (AREF (obj, i));
1513 }
1514 }
1515 }
1516 else
1517 signal_error (/* Qselection_error */ "Unrecognized selection data", obj);
1518
1519 cs->type = symbol_to_gdk_atom (type);
1520}
1521
1522static Lisp_Object
1523clean_local_selection_data (Lisp_Object obj)
1524{
1525 if (CONSP (obj)
1526 && INTEGERP (XCAR (obj))
1527 && CONSP (XCDR (obj))
1528 && FIXNUMP (XCAR (XCDR (obj)))
1529 && NILP (XCDR (XCDR (obj))))
1530 obj = Fcons (XCAR (obj), XCDR (obj));
1531
1532 if (CONSP (obj)
1533 && INTEGERP (XCAR (obj))
1534 && FIXNUMP (XCDR (obj)))
1535 {
1536 if (BASE_EQ (XCAR (obj), make_fixnum (0)))
1537 return XCDR (obj);
1538 if (BASE_EQ (XCAR (obj), make_fixnum (-1)))
1539 return make_fixnum (- XFIXNUM (XCDR (obj)));
1540 }
1541 if (VECTORP (obj))
1542 {
1543 ptrdiff_t i;
1544 ptrdiff_t size = ASIZE (obj);
1545 Lisp_Object copy;
1546 if (size == 1)
1547 return clean_local_selection_data (AREF (obj, 0));
1548 copy = make_nil_vector (size);
1549 for (i = 0; i < size; i++)
1550 ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
1551 return copy;
1552 }
1553 return obj;
1554}
1555
1556DEFUN ("pgtk-own-selection-internal", Fpgtk_own_selection_internal,
1557 Spgtk_own_selection_internal, 2, 3, 0,
1558 doc: /* Assert a selection of type SELECTION and value VALUE.
1559SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
1560\(Those are literal upper-case symbol names, since that's what GDK expects.)
1561VALUE is typically a string, or a cons of two markers, but may be
1562anything that the functions on `selection-converter-alist' know about.
1563
1564FRAME should be a frame that should own the selection. If omitted or
1565nil, it defaults to the selected frame. */)
1566 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
1567{
1568 if (NILP (frame)) frame = selected_frame;
1569 if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame)))
1570 error ("GDK selection unavailable for this frame");
1571
1572 CHECK_SYMBOL (selection);
1573 if (NILP (value)) error ("VALUE may not be nil");
1574 pgtk_own_selection (selection, value, frame);
334 return value; 1575 return value;
335} 1576}
336 1577
1578/* Request the selection value from the owner. If we are the owner,
1579 simply return our selection value. If we are not the owner, this
1580 will block until all of the data has arrived. */
337 1581
338DEFUN ("pgtk-disown-selection-internal", Fpgtk_disown_selection_internal, 1582DEFUN ("pgtk-get-selection-internal", Fpgtk_get_selection_internal,
339 Spgtk_disown_selection_internal, 1, 2, 0, 1583 Spgtk_get_selection_internal, 2, 4, 0,
340 doc: /* If we own the selection SELECTION, disown it. 1584 doc: /* Return text selected from some X window.
341Disowning it means there is no such selection. 1585SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
1586\(Those are literal upper-case symbol names, since that's what X expects.)
1587TARGET-TYPE is the type of data desired, typically `STRING'.
1588
1589TIME-STAMP is the time to use in the XConvertSelection call for foreign
1590selections. If omitted, defaults to the time for the last event.
342 1591
343TERMINAL should be a terminal object or a frame specifying the X 1592TERMINAL should be a terminal object or a frame specifying the X
344server to query. If omitted or nil, that stands for the selected 1593server to query. If omitted or nil, that stands for the selected
345frame's display, or the first available X display. */) 1594frame's display, or the first available X display. */)
346 (Lisp_Object selection, Lisp_Object terminal) 1595 (Lisp_Object selection_symbol, Lisp_Object target_type,
1596 Lisp_Object time_stamp, Lisp_Object terminal)
347{ 1597{
1598 Lisp_Object val = Qnil;
1599 Lisp_Object maybe_alias;
348 struct frame *f = frame_for_pgtk_selection (terminal); 1600 struct frame *f = frame_for_pgtk_selection (terminal);
349 GtkClipboard *cb;
350 1601
351 if (!pgtk_selection_usable ()) 1602 CHECK_SYMBOL (selection_symbol);
352 return Qnil; 1603 CHECK_SYMBOL (target_type);
353 1604
1605 if (EQ (target_type, QMULTIPLE))
1606 error ("Retrieving MULTIPLE selections is currently unimplemented");
354 if (!f) 1607 if (!f)
355 return Qnil; 1608 error ("GDK selection unavailable for this frame");
356 1609
357 cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection); 1610 /* Quitting inside this function is okay, so we don't have to use
1611 FOR_EACH_TAIL_SAFE. */
1612 maybe_alias = Fassq (selection_symbol, Vpgtk_selection_alias_alist);
358 1613
359 gtk_clipboard_clear (cb); 1614 if (!NILP (maybe_alias))
1615 {
1616 selection_symbol = XCDR (maybe_alias);
1617 CHECK_SYMBOL (selection_symbol);
1618 }
360 1619
361 return Qt; 1620 val = pgtk_get_local_selection (selection_symbol, target_type, true,
1621 FRAME_DISPLAY_INFO (f));
1622
1623 if (NILP (val) && FRAME_LIVE_P (f))
1624 {
1625 Lisp_Object frame;
1626 XSETFRAME (frame, f);
1627 return pgtk_get_foreign_selection (selection_symbol, target_type,
1628 time_stamp, frame);
1629 }
1630
1631 if (CONSP (val) && SYMBOLP (XCAR (val)))
1632 {
1633 val = XCDR (val);
1634 if (CONSP (val) && NILP (XCDR (val)))
1635 val = XCAR (val);
1636 }
1637 return clean_local_selection_data (val);
362} 1638}
363 1639
1640DEFUN ("pgtk-disown-selection-internal", Fpgtk_disown_selection_internal,
1641 Spgtk_disown_selection_internal, 1, 3, 0,
1642 doc: /* If we own the selection SELECTION, disown it.
1643Disowning it means there is no such selection.
364 1644
365DEFUN ("pgtk-selection-exists-p", Fpgtk_selection_exists_p, Spgtk_selection_exists_p, 0, 2, 0, 1645Sets the last-change time for the selection to TIME-OBJECT (by default
366 doc: /* Whether there is an owner for the given X selection. 1646the time of the last event).
367SELECTION should be the name of the selection in question, typically
368one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
369these literal upper-case names.) The symbol nil is the same as
370`PRIMARY', and t is the same as `SECONDARY'.
371 1647
372TERMINAL should be a terminal object or a frame specifying the X 1648TERMINAL should be a terminal object or a frame specifying the X
373server to query. If omitted or nil, that stands for the selected 1649server to query. If omitted or nil, that stands for the selected
374frame's display, or the first available X display. 1650frame's display, or the first available X display. */)
375 1651 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
376On Nextstep, TERMINAL is unused. */)
377 (Lisp_Object selection, Lisp_Object terminal)
378{ 1652{
1653 guint32 timestamp;
1654 GdkAtom selection_atom;
379 struct frame *f = frame_for_pgtk_selection (terminal); 1655 struct frame *f = frame_for_pgtk_selection (terminal);
380 GtkClipboard *cb; 1656 struct pgtk_display_info *dpyinfo;
381 1657
382 if (!pgtk_selection_usable ()) 1658 if (!f)
383 return Qnil; 1659 return Qnil;
384 1660
385 if (!f) 1661 dpyinfo = FRAME_DISPLAY_INFO (f);
1662 CHECK_SYMBOL (selection);
1663
1664 /* Don't disown the selection when we're not the owner. */
1665 if (NILP (LOCAL_SELECTION (selection, dpyinfo)))
386 return Qnil; 1666 return Qnil;
387 1667
388 cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection); 1668 selection_atom = symbol_to_gdk_atom (selection);
389 1669
390 return gtk_clipboard_wait_is_text_available (cb) ? Qt : Qnil; 1670 block_input ();
391} 1671 if (NILP (time_object))
1672 timestamp = dpyinfo->last_user_time;
1673 else
1674 CONS_TO_INTEGER (time_object, guint32, timestamp);
1675 gdk_selection_owner_set_for_display (dpyinfo->display, NULL,
1676 selection_atom, timestamp,
1677 TRUE);
1678 unblock_input ();
392 1679
1680 return Qt;
1681}
393 1682
394DEFUN ("pgtk-selection-owner-p", Fpgtk_selection_owner_p, Spgtk_selection_owner_p, 0, 2, 0, 1683DEFUN ("pgtk-selection-owner-p", Fpgtk_selection_owner_p, Spgtk_selection_owner_p,
395 doc: /* Whether the current Emacs process owns the given X Selection. 1684 0, 2, 0,
1685 doc: /* Whether the current Emacs process owns the given selection.
396The arg should be the name of the selection in question, typically one of 1686The arg should be the name of the selection in question, typically one of
397the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. 1687the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
398\(Those are literal upper-case symbol names, since that's what X expects.) 1688\(Those are literal upper-case symbol names, since that's what GDK expects.)
399For convenience, the symbol nil is the same as `PRIMARY', 1689For convenience, the symbol nil is the same as `PRIMARY',
400and t is the same as `SECONDARY'. 1690and t is the same as `SECONDARY'.
401 1691
402TERMINAL should be a terminal object or a frame specifying the X 1692TERMINAL should be a terminal object or a frame specifying the GDK
403server to query. If omitted or nil, that stands for the selected 1693server to query. If omitted or nil, that stands for the selected
404frame's display, or the first available X display. 1694frame's display, or the first available X display. */)
405
406On Nextstep, TERMINAL is unused. */)
407 (Lisp_Object selection, Lisp_Object terminal) 1695 (Lisp_Object selection, Lisp_Object terminal)
408{ 1696{
409 struct frame *f = frame_for_pgtk_selection (terminal); 1697 struct frame *f = frame_for_pgtk_selection (terminal);
410 GtkClipboard *cb;
411 GObject *obj;
412 GQuark quark_data, quark_size;
413
414 if (!pgtk_selection_usable ())
415 return Qnil;
416 1698
417 cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection); 1699 CHECK_SYMBOL (selection);
418 selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data, 1700 if (NILP (selection)) selection = QPRIMARY;
419 &quark_size); 1701 if (EQ (selection, Qt)) selection = QSECONDARY;
420 1702
421 obj = gtk_clipboard_get_owner (cb); 1703 if (f && !NILP (LOCAL_SELECTION (selection, FRAME_DISPLAY_INFO (f))))
422 1704 return Qt;
423 return obj && g_object_get_qdata (obj, quark_data) != NULL ? Qt : Qnil; 1705 else
1706 return Qnil;
424} 1707}
425 1708
1709DEFUN ("pgtk-selection-exists-p", Fpgtk_selection_exists_p, Spgtk_selection_exists_p,
1710 0, 2, 0,
1711 doc: /* Whether there is an owner for the given selection.
1712SELECTION should be the name of the selection in question, typically
1713one of the symbols `PRIMARY', `SECONDARY', `CLIPBOARD', or
1714`CLIPBOARD_MANAGER' (GDK expects these literal upper-case names.) The
1715symbol nil is the same as `PRIMARY', and t is the same as `SECONDARY'.
426 1716
427DEFUN ("pgtk-get-selection-internal", Fpgtk_get_selection_internal, 1717TERMINAL should be a terminal object or a frame specifying the GDK
428 Spgtk_get_selection_internal, 2, 3, 0,
429 doc: /* Return text selected from some program.
430SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
431\(Those are literal upper-case symbol names, since that's what X expects.)
432TARGET-TYPE is the type of data desired, typically `STRING'.
433
434TERMINAL should be a terminal object or a frame specifying the X
435server to query. If omitted or nil, that stands for the selected 1718server to query. If omitted or nil, that stands for the selected
436frame's display, or the first available display. */) 1719frame's display, or the first available X display. */)
437 (Lisp_Object selection_symbol, Lisp_Object target_type, 1720 (Lisp_Object selection, Lisp_Object terminal)
438 Lisp_Object terminal)
439{ 1721{
1722 GdkWindow *owner;
1723 GdkAtom atom;
440 struct frame *f = frame_for_pgtk_selection (terminal); 1724 struct frame *f = frame_for_pgtk_selection (terminal);
441 GtkClipboard *cb; 1725 struct pgtk_display_info *dpyinfo;
442 1726
443 CHECK_SYMBOL (selection_symbol); 1727 CHECK_SYMBOL (selection);
444 CHECK_SYMBOL (target_type); 1728 if (NILP (selection)) selection = QPRIMARY;
1729 if (EQ (selection, Qt)) selection = QSECONDARY;
445 1730
446 if (EQ (target_type, QMULTIPLE))
447 error ("Retrieving MULTIPLE selections is currently unimplemented");
448 if (!f) 1731 if (!f)
449 error ("PGTK selection unavailable for this frame");
450
451 if (!pgtk_selection_usable ())
452 return Qnil; 1732 return Qnil;
453 1733
454 cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection_symbol); 1734 dpyinfo = FRAME_DISPLAY_INFO (f);
455
456 GdkAtom target_atom = gdk_atom_intern (SSDATA (SYMBOL_NAME (target_type)), false);
457 GtkSelectionData *seldata = gtk_clipboard_wait_for_contents (cb, target_atom);
458 1735
459 if (seldata == NULL) 1736 if (!NILP (LOCAL_SELECTION (selection, dpyinfo)))
460 return Qnil; 1737 return Qt;
461 1738
462 const guchar *sd_data = gtk_selection_data_get_data (seldata); 1739 atom = symbol_to_gdk_atom (selection);
463 int sd_len = gtk_selection_data_get_length (seldata); 1740 if (atom == 0) return Qnil;
464 int sd_format = gtk_selection_data_get_format (seldata); 1741 block_input ();
465 GdkAtom sd_type = gtk_selection_data_get_data_type (seldata); 1742 owner = gdk_selection_owner_get_for_display (dpyinfo->display, atom);
1743 unblock_input ();
1744 return (owner ? Qt : Qnil);
1745}
466 1746
467 if (sd_format == 8) 1747/* Called to handle GDK_SELECTION_NOTIFY events.
468 { 1748 If it's the selection we are waiting for, stop waiting
469 Lisp_Object str, lispy_type; 1749 by setting the car of reading_selection_reply to non-nil.
1750 We store t there if the reply is successful, lambda if not. */
470 1751
471 str = make_unibyte_string ((char *) sd_data, sd_len); 1752void
472 /* Indicate that this string is from foreign selection by a text 1753pgtk_handle_selection_notify (GdkEventSelection *event)
473 property `foreign-selection' so that the caller of 1754{
474 x-get-selection-internal (usually x-get-selection) can know 1755 /* GDK doesn't populate event->requestor, contrary to what the ICCCM
475 that the string must be decode. */ 1756 says should be done with SelectionNotify events. */
476 if (sd_type == gdk_atom_intern ("COMPOUND_TEXT", false))
477 lispy_type = QCOMPOUND_TEXT;
478 else if (sd_type == gdk_atom_intern ("UTF8_STRING", false))
479 lispy_type = QUTF8_STRING;
480 else if (sd_type == gdk_atom_intern ("text/plain;charset=utf-8", false))
481 lispy_type = Qtext_plain_charset_utf_8;
482 else
483 lispy_type = QSTRING;
484 Fput_text_property (make_fixnum (0), make_fixnum (sd_len),
485 Qforeign_selection, lispy_type, str);
486 1757
487 gtk_selection_data_free (seldata); 1758 if (event->selection != reading_which_selection)
488 return str; 1759 return;
489 }
490 1760
491 gtk_selection_data_free (seldata); 1761 XSETCAR (reading_selection_reply,
492 return Qnil; 1762 (event->property != GDK_NONE ? Qt : Qlambda));
493} 1763}
494 1764
495void 1765void
@@ -499,7 +1769,19 @@ syms_of_pgtkselect (void)
499 DEFSYM (QSECONDARY, "SECONDARY"); 1769 DEFSYM (QSECONDARY, "SECONDARY");
500 DEFSYM (QTEXT, "TEXT"); 1770 DEFSYM (QTEXT, "TEXT");
501 DEFSYM (QFILE_NAME, "FILE_NAME"); 1771 DEFSYM (QFILE_NAME, "FILE_NAME");
1772 DEFSYM (QSTRING, "STRING");
1773 DEFSYM (QINTEGER, "INTEGER");
1774 DEFSYM (QTIMESTAMP, "TIMESTAMP");
1775 DEFSYM (QTEXT, "TEXT");
502 DEFSYM (QMULTIPLE, "MULTIPLE"); 1776 DEFSYM (QMULTIPLE, "MULTIPLE");
1777 DEFSYM (QNULL, "NULL");
1778 DEFSYM (QATOM, "ATOM");
1779 DEFSYM (QTARGETS, "TARGETS");
1780
1781 DEFSYM (Qpgtk_sent_selection_functions,
1782 "pgtk-sent-selection-functions");
1783 DEFSYM (Qpgtk_lost_selection_functions,
1784 "pgtk-lost-selection-functions");
503 1785
504 DEFSYM (Qforeign_selection, "foreign-selection"); 1786 DEFSYM (Qforeign_selection, "foreign-selection");
505 DEFSYM (QUTF8_STRING, "UTF8_STRING"); 1787 DEFSYM (QUTF8_STRING, "UTF8_STRING");
@@ -513,6 +1795,32 @@ syms_of_pgtkselect (void)
513 defsubr (&Spgtk_selection_exists_p); 1795 defsubr (&Spgtk_selection_exists_p);
514 defsubr (&Spgtk_selection_owner_p); 1796 defsubr (&Spgtk_selection_owner_p);
515 1797
1798 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
1799 doc: /* SKIP: real doc in xselect.c. */);
1800 Vselection_converter_alist = Qnil;
1801
1802 DEFVAR_LISP ("pgtk-lost-selection-functions", Vpgtk_lost_selection_functions,
1803 doc: /* A list of functions to be called when Emacs loses a selection.
1804\(This happens when some other client makes its own selection
1805or when a Lisp program explicitly clears the selection.)
1806The functions are called with one argument, the selection type
1807\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
1808 Vpgtk_lost_selection_functions = Qnil;
1809
1810 DEFVAR_LISP ("pgtk-sent-selection-functions", Vpgtk_sent_selection_functions,
1811 doc: /* A list of functions to be called when Emacs answers a selection request.
1812The functions are called with three arguments:
1813 - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
1814 - the selection-type which Emacs was asked to convert the
1815 selection into before sending (for example, `STRING' or `LENGTH');
1816 - a flag indicating success or failure for responding to the request.
1817We might have failed (and declined the request) for any number of reasons,
1818including being asked for a selection that we no longer own, or being asked
1819to convert into a type that we don't know about or that is inappropriate.
1820This hook doesn't let you change the behavior of Emacs's selection replies,
1821it merely informs you that they have happened. */);
1822 Vpgtk_sent_selection_functions = Qnil;
1823
516 DEFVAR_LISP ("pgtk-sent-selection-hooks", Vpgtk_sent_selection_hooks, 1824 DEFVAR_LISP ("pgtk-sent-selection-hooks", Vpgtk_sent_selection_hooks,
517 doc: /* A list of functions to be called when Emacs answers a selection request 1825 doc: /* A list of functions to be called when Emacs answers a selection request
518The functions are called with four arguments: 1826The functions are called with four arguments:
@@ -533,4 +1841,19 @@ This may cause crashes due to a GTK bug, which assumes that clients
533will connect to a single display. It might also cause selections to 1841will connect to a single display. It might also cause selections to
534not arrive at the correct display. */); 1842not arrive at the correct display. */);
535 pgtk_enable_selection_on_multi_display = false; 1843 pgtk_enable_selection_on_multi_display = false;
1844
1845 DEFVAR_LISP ("pgtk-selection-alias-alist", Vpgtk_selection_alias_alist,
1846 doc: /* List of selections to alias to another.
1847It should be an alist of a selection name to another. When a
1848selection request arrives for the first selection, Emacs will respond
1849as if the request was meant for the other.
1850
1851Note that this does not affect setting or owning selections. */);
1852 Vpgtk_selection_alias_alist = Qnil;
1853
1854 reading_selection_reply = Fcons (Qnil, Qnil);
1855 staticpro (&reading_selection_reply);
1856
1857 property_change_reply = Fcons (Qnil, Qnil);
1858 staticpro (&property_change_reply);
536} 1859}