This source file includes following definitions.
- frame_for_pgtk_selection
- symbol_to_gdk_atom
- gdk_atom_to_symbol
- pgtk_own_selection
- pgtk_get_local_selection
- pgtk_decline_selection_request
- pgtk_push_current_selection_request
- pgtk_pop_current_selection_request
- pgtk_selection_request_lisp_error
- set_property_change_object
- pgtk_reply_selection_request
- pgtk_handle_selection_request
- pgtk_convert_selection
- pgtk_handle_selection_clear
- pgtk_handle_selection_event
- pgtk_clear_frame_selections
- waiting_for_other_props_on_window
- expect_property_change
- unexpect_property_change
- wait_for_property_change_unwind
- wait_for_property_change
- pgtk_handle_property_notify
- pgtk_display_selection_waiting_message
- pgtk_cancel_atimer
- pgtk_get_foreign_selection
- pgtk_size_for_format
- pgtk_get_window_property
- pgtk_get_window_property_as_lisp_data
- selection_data_to_lisp_data
- cons_to_gdk_long
- lisp_data_to_selection_data
- clean_local_selection_data
- pgtk_handle_selection_notify
- syms_of_pgtkselect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include "lisp.h"
25 #include "pgtkterm.h"
26 #include "termhooks.h"
27 #include "keyboard.h"
28 #include "atimer.h"
29 #include "blockinput.h"
30
31
32
33
34
35
36 struct selection_data;
37 struct prop_location;
38
39 static void pgtk_decline_selection_request (struct selection_input_event *);
40 static bool pgtk_convert_selection (Lisp_Object, Lisp_Object, GdkAtom, bool,
41 struct pgtk_display_info *);
42 static bool waiting_for_other_props_on_window (GdkDisplay *, GdkWindow *);
43 #if 0
44 static struct prop_location *expect_property_change (GdkDisplay *, GdkWindow *,
45 GdkAtom, int);
46 #endif
47 static void unexpect_property_change (struct prop_location *);
48 static void wait_for_property_change (struct prop_location *);
49 static Lisp_Object pgtk_get_window_property_as_lisp_data (struct pgtk_display_info *,
50 GdkWindow *, GdkAtom,
51 Lisp_Object, GdkAtom, bool);
52 static Lisp_Object selection_data_to_lisp_data (struct pgtk_display_info *,
53 const unsigned char *,
54 ptrdiff_t, GdkAtom, int);
55 static void lisp_data_to_selection_data (struct pgtk_display_info *, Lisp_Object,
56 struct selection_data *);
57 static Lisp_Object pgtk_get_local_selection (Lisp_Object, Lisp_Object,
58 bool, struct pgtk_display_info *);
59
60
61
62
63
64
65
66 static struct frame *
67 frame_for_pgtk_selection (Lisp_Object object)
68 {
69 Lisp_Object tail, frame;
70 struct frame *f;
71
72 if (NILP (object))
73 {
74 f = XFRAME (selected_frame);
75 if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
76 return f;
77
78 FOR_EACH_FRAME (tail, frame)
79 {
80 f = XFRAME (frame);
81 if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
82 return f;
83 }
84 }
85 else if (TERMINALP (object))
86 {
87 struct terminal *t = decode_live_terminal (object);
88
89 if (t->type == output_pgtk)
90 FOR_EACH_FRAME (tail, frame)
91 {
92 f = XFRAME (frame);
93 if (FRAME_LIVE_P (f) && f->terminal == t)
94 return f;
95 }
96 }
97 else if (FRAMEP (object))
98 {
99 f = XFRAME (object);
100 if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
101 return f;
102 }
103
104 return NULL;
105 }
106
107 #define LOCAL_SELECTION(selection_symbol, dpyinfo) \
108 assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
109
110 static GdkAtom
111 symbol_to_gdk_atom (Lisp_Object sym)
112 {
113 if (NILP (sym))
114 return GDK_NONE;
115
116 if (EQ (sym, QPRIMARY))
117 return GDK_SELECTION_PRIMARY;
118 if (EQ (sym, QSECONDARY))
119 return GDK_SELECTION_SECONDARY;
120 if (EQ (sym, 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
129 static Lisp_Object
130 gdk_atom_to_symbol (GdkAtom atom)
131 {
132 return intern (gdk_atom_name (atom));
133 }
134
135
136
137
138
139
140
141
142 static void
143 pgtk_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
158
159
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
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
181
182 if (!NILP (prev_value))
183 {
184
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
196
197
198 targets = pgtk_get_local_selection (selection_name, QTARGETS,
199 true, dpyinfo);
200
201
202 block_input ();
203 gtk_selection_clear_targets (FRAME_GTK_WIDGET (f), selection_atom);
204
205 if (VECTORP (targets))
206 {
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);
222 }
223 unblock_input ();
224 }
225
226 static Lisp_Object
227 pgtk_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
238 if (EQ (target_type, QTIMESTAMP))
239 {
240 handler_fn = Qnil;
241 value = XCAR (XCDR (XCDR (local_value)));
242 }
243 else
244 {
245
246
247
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);
277 }
278
279
280
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
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
307 static void
308 pgtk_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
316 struct 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
326
327
328 struct prop_location *wait_object;
329 struct selection_data *next;
330 };
331
332 struct pgtk_selection_request
333 {
334
335 struct pgtk_selection_request *last;
336
337
338 struct pgtk_display_info *dpyinfo;
339
340
341 struct selection_input_event *request;
342
343
344 struct selection_data *converted_selections;
345
346
347 GdkAtom conversion_fail_tag;
348
349
350 bool converted;
351 };
352
353
354
355
356 struct pgtk_selection_request *selection_request_stack;
357
358 static void
359 pgtk_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
375 static void
376 pgtk_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
387
388
389
390 static void
391 pgtk_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)
399 {
400 next = cs->next;
401 if (! cs->nofree && cs->data)
402 xfree (cs->data);
403 xfree (cs);
404 }
405 frame->converted_selections = NULL;
406
407 if (!frame->converted && frame->dpyinfo->display)
408 pgtk_decline_selection_request (frame->request);
409 }
410
411
412
413
414
415
416
417 struct 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
430 static int prop_location_identifier;
431
432 #endif
433
434 static Lisp_Object property_change_reply;
435
436 static struct prop_location *property_change_reply_object;
437
438 static struct prop_location *property_change_wait_list;
439
440 static void
441 set_property_change_object (struct prop_location *location)
442 {
443
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
453
454 static void
455 pgtk_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
468
469
470
471
472 for (cs = frame->converted_selections; cs; cs = cs->next)
473 {
474 if (cs->property == GDK_NONE)
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);
484 }
485
486
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
495
496
497
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
504
505
506 set_property_change_object (cs->wait_object);
507 unblock_input ();
508
509 bytes_remaining = cs->size;
510 bytes_remaining *= format_bytes;
511
512
513
514 wait_for_property_change (cs->wait_object);
515
516
517
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 ();
527 }
528
529
530
531
532
533
534 static void
535 pgtk_handle_selection_request (struct selection_input_event *event)
536 {
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)
553 {
554 tem = Qnil;
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 }
566 }
567
568 pushed = false;
569
570 if (!dpyinfo)
571 goto DONE;
572
573 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
574
575
576 if (NILP (local_selection_data)) goto DONE;
577
578
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))
593 {
594
595
596
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
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
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;
636 }
637 else
638 {
639 if (property == GDK_NONE)
640 property = SELECTION_EVENT_TARGET (event);
641
642 success = pgtk_convert_selection (selection_symbol,
643 target_symbol, property,
644 false, dpyinfo);
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);
654 else
655 pgtk_decline_selection_request (event);
656
657
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);
664 }
665
666
667
668
669
670
671
672
673 static bool
674 pgtk_convert_selection (Lisp_Object selection_symbol,
675 Lisp_Object target_symbol, GdkAtom property,
676 bool for_multiple, struct pgtk_display_info *dpyinfo)
677 {
678 Lisp_Object lisp_selection;
679 struct selection_data *cs;
680 struct pgtk_selection_request *frame;
681
682 lisp_selection
683 = pgtk_get_local_selection (selection_symbol, target_symbol,
684 false, dpyinfo);
685
686 frame = selection_request_stack;
687
688
689 if (NILP (lisp_selection)
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
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;
720 }
721
722
723
724
725
726
727
728 static void
729 pgtk_handle_selection_clear (struct selection_input_event *event)
730 {
731 GdkAtom selection = SELECTION_EVENT_SELECTION (event);
732 guint32 changed_owner_time = SELECTION_EVENT_TIME (event);
733
734 Lisp_Object selection_symbol, local_selection_data;
735 guint32 local_selection_time;
736 struct pgtk_display_info *dpyinfo = SELECTION_EVENT_DPYINFO (event);
737 Lisp_Object Vselection_alist;
738
739 if (!dpyinfo) return;
740
741 selection_symbol = gdk_atom_to_symbol (selection);
742 local_selection_data = LOCAL_SELECTION (selection_symbol, dpyinfo);
743
744
745 if (NILP (local_selection_data)) return;
746
747 CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))),
748 guint32, local_selection_time);
749
750
751
752 if (changed_owner_time != GDK_CURRENT_TIME
753 && local_selection_time > changed_owner_time)
754 return;
755
756
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
773 CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions, selection_symbol);
774
775 redisplay_preserve_echo_area (20);
776 }
777
778 void
779 pgtk_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
788
789
790 void
791 pgtk_clear_frame_selections (struct frame *f)
792 {
793 Lisp_Object frame, rest, timestamp, symbol;
794 guint32 time;
795 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
796 struct terminal *t = dpyinfo->terminal;
797
798 XSETFRAME (frame, f);
799
800
801 while (CONSP (t->Vselection_alist)
802 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist)))))))
803 {
804 symbol = Fcar (Fcar (t->Vselection_alist));
805
806
807 CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions,
808 symbol);
809
810 timestamp = Fcar (Fcdr (Fcdr (Fcar (t->Vselection_alist))));
811 CONS_TO_INTEGER (timestamp, guint32, time);
812
813
814
815
816 gdk_selection_owner_set_for_display (dpyinfo->display,
817 NULL,
818 symbol_to_gdk_atom (symbol),
819 time, TRUE);
820
821 tset_selection_alist (t, XCDR (t->Vselection_alist));
822 }
823
824
825 for (rest = t->Vselection_alist; CONSP (rest); rest = XCDR (rest))
826 if (CONSP (XCDR (rest))
827 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
828 {
829 symbol = XCAR (XCAR (XCDR (rest)));
830 CALLN (Frun_hook_with_args, Qpgtk_lost_selection_functions,
831 symbol);
832
833 timestamp = XCAR (XCDR (XCDR (XCAR (XCDR (rest)))));
834 CONS_TO_INTEGER (timestamp, guint32, time);
835
836 gdk_selection_owner_set_for_display (dpyinfo->display,
837 NULL,
838 symbol_to_gdk_atom (symbol),
839 time, TRUE);
840
841 XSETCDR (rest, XCDR (XCDR (rest)));
842 break;
843 }
844 }
845
846
847
848
849 static bool
850 waiting_for_other_props_on_window (GdkDisplay *display, GdkWindow *window)
851 {
852 for (struct prop_location *p = property_change_wait_list; p; p = p->next)
853 if (p->display == display && p->window == window)
854 return true;
855 return false;
856 }
857
858
859
860
861
862
863
864
865
866 #if 0
867
868 static struct prop_location *
869 expect_property_change (GdkDisplay *display, GdkWindow *window,
870 GdkAtom property, int state)
871 {
872 struct prop_location *pl = xmalloc (sizeof *pl);
873 pl->identifier = ++prop_location_identifier;
874 pl->display = display;
875 pl->window = window;
876 pl->property = property;
877 pl->desired_state = state;
878 pl->next = property_change_wait_list;
879 pl->arrived = false;
880 property_change_wait_list = pl;
881 return pl;
882 }
883
884 #endif
885
886
887
888
889 static void
890 unexpect_property_change (struct prop_location *location)
891 {
892 struct prop_location *prop, **pprev = &property_change_wait_list;
893
894 for (prop = property_change_wait_list; prop; prop = *pprev)
895 {
896 if (prop == location)
897 {
898 *pprev = prop->next;
899 xfree (prop);
900 break;
901 }
902 else
903 pprev = &prop->next;
904 }
905 }
906
907
908
909 static void
910 wait_for_property_change_unwind (void *loc)
911 {
912 struct prop_location *location = loc;
913
914 unexpect_property_change (location);
915 if (location == property_change_reply_object)
916 property_change_reply_object = 0;
917 }
918
919
920
921
922 static void
923 wait_for_property_change (struct prop_location *location)
924 {
925 specpdl_ref count = SPECPDL_INDEX ();
926
927
928 record_unwind_protect_ptr (wait_for_property_change_unwind, location);
929
930
931
932
933
934
935 if (! location->arrived)
936 {
937 intmax_t timeout = max (0, pgtk_selection_timeout);
938 intmax_t secs = timeout / 1000;
939 int nsecs = (timeout % 1000) * 1000000;
940
941 wait_reading_process_output (secs, nsecs, 0, false,
942 property_change_reply, NULL, 0);
943
944 if (NILP (XCAR (property_change_reply)))
945 error ("Timed out waiting for property-notify event");
946 }
947
948 unbind_to (count, Qnil);
949 }
950
951
952
953
954 void
955 pgtk_handle_property_notify (GdkEventProperty *event)
956 {
957 struct prop_location *rest;
958 GdkDisplay *dpy;
959
960 dpy = gdk_window_get_display (event->window);
961
962 for (rest = property_change_wait_list; rest; rest = rest->next)
963 {
964 if (!rest->arrived
965 && rest->property == event->atom
966 && rest->window == event->window
967 && rest->display == dpy
968 && rest->desired_state == event->state)
969 {
970 rest->arrived = true;
971
972
973
974 if (rest == property_change_reply_object)
975 XSETCAR (property_change_reply, Qt);
976
977 return;
978 }
979 }
980 }
981
982 static void
983 pgtk_display_selection_waiting_message (struct atimer *timer)
984 {
985 Lisp_Object val;
986
987 val = build_string ("Waiting for reply from selection owner...");
988 message3_nolog (val);
989 }
990
991 static void
992 pgtk_cancel_atimer (void *atimer)
993 {
994 cancel_atimer (atimer);
995 }
996
997
998
999 static GdkAtom reading_which_selection;
1000 static Lisp_Object reading_selection_reply;
1001 static GdkWindow *reading_selection_window;
1002
1003
1004
1005
1006
1007 static Lisp_Object
1008 pgtk_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1009 Lisp_Object time_stamp, Lisp_Object frame)
1010 {
1011 struct frame *f = XFRAME (frame);
1012 struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1013 GdkWindow *requestor_window = FRAME_GDK_WINDOW (f);
1014 guint32 requestor_time = dpyinfo->last_user_time;
1015 GdkAtom selection_atom = symbol_to_gdk_atom (selection_symbol);
1016 GdkAtom type_atom = (CONSP (target_type)
1017 ? symbol_to_gdk_atom (XCAR (target_type))
1018 : symbol_to_gdk_atom (target_type));
1019 struct atimer *delayed_message;
1020 struct timespec message_interval;
1021 specpdl_ref count;
1022
1023 count = SPECPDL_INDEX ();
1024
1025 if (!FRAME_LIVE_P (f))
1026 return unbind_to (count, Qnil);
1027
1028 if (!NILP (time_stamp))
1029 CONS_TO_INTEGER (time_stamp, guint32, requestor_time);
1030
1031 block_input ();
1032
1033 reading_selection_window = requestor_window;
1034 reading_which_selection = selection_atom;
1035 XSETCAR (reading_selection_reply, Qnil);
1036
1037 gdk_selection_convert (requestor_window, selection_atom,
1038 type_atom, requestor_time);
1039 unblock_input ();
1040
1041
1042
1043
1044
1045
1046 message_interval = make_timespec (1, 0);
1047 delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
1048 pgtk_display_selection_waiting_message,
1049 NULL);
1050 record_unwind_protect_ptr (pgtk_cancel_atimer, delayed_message);
1051
1052
1053 intmax_t timeout = max (0, pgtk_selection_timeout);
1054 intmax_t secs = timeout / 1000;
1055 int nsecs = (timeout % 1000) * 1000000;
1056
1057 wait_reading_process_output (secs, nsecs, 0, false,
1058 reading_selection_reply, NULL, 0);
1059
1060 if (NILP (XCAR (reading_selection_reply)))
1061 error ("Timed out waiting for reply from selection owner");
1062 if (EQ (XCAR (reading_selection_reply), Qlambda))
1063 return unbind_to (count, Qnil);
1064
1065
1066 return unbind_to (count,
1067 pgtk_get_window_property_as_lisp_data (dpyinfo,
1068 requestor_window,
1069 GDK_NONE,
1070 target_type,
1071 selection_atom,
1072 false));
1073 }
1074
1075
1076
1077 static ptrdiff_t
1078 pgtk_size_for_format (gint format)
1079 {
1080 switch (format)
1081 {
1082 case 8:
1083 return sizeof (unsigned char);
1084 case 16:
1085 return sizeof (unsigned short);
1086 case 32:
1087 return sizeof (unsigned long);
1088
1089 default:
1090 emacs_abort ();
1091 }
1092 }
1093
1094
1095
1096 static void
1097 pgtk_get_window_property (GdkWindow *window, unsigned char **data_ret,
1098 ptrdiff_t *bytes_ret, GdkAtom *actual_type_ret,
1099 int *actual_format_ret, unsigned long *actual_size_ret)
1100 {
1101 gint length, actual_format;
1102 unsigned char *data;
1103 ptrdiff_t element_size;
1104 void *xdata;
1105 GdkAtom actual_type;
1106 unsigned long i;
1107 unsigned int *idata;
1108 unsigned long *ldata;
1109
1110 data = NULL;
1111
1112 length = gdk_selection_property_get (window, &data,
1113 &actual_type,
1114 &actual_format);
1115
1116 if (!data)
1117 {
1118 *data_ret = NULL;
1119 *actual_type_ret = GDK_NONE;
1120 *bytes_ret = 0;
1121 *actual_format_ret = 8;
1122 *actual_size_ret = 0;
1123
1124 return;
1125 }
1126
1127 if (actual_type == GDK_SELECTION_TYPE_ATOM
1128 || actual_type == gdk_atom_intern_static_string ("ATOM_PAIR"))
1129 {
1130
1131 eassert (actual_format == 32);
1132
1133 length = length / sizeof (GdkAtom);
1134 xdata = xmalloc (sizeof (GdkAtom) * length + 1);
1135 memcpy (xdata, data, 1 + length * sizeof (GdkAtom));
1136
1137 g_free (data);
1138
1139 *data_ret = xdata;
1140 *actual_type_ret = actual_type;
1141 *bytes_ret = length * sizeof (GdkAtom);
1142 *actual_format_ret = 32;
1143 *actual_size_ret = length;
1144
1145 return;
1146 }
1147
1148 element_size = pgtk_size_for_format (actual_format);
1149 length = length / element_size;
1150
1151
1152
1153 xdata = xmalloc (1 + element_size * length);
1154 memcpy (xdata, data, 1 + element_size * length);
1155
1156 if (actual_format == 32 && LONG_WIDTH > 32)
1157 {
1158 ldata = (typeof (ldata)) data;
1159 idata = xdata;
1160
1161 for (i = 0; i < length; ++i)
1162 idata[i] = ldata[i];
1163
1164
1165 idata[length] = 0;
1166 *bytes_ret = sizeof *idata * length;
1167 }
1168 else
1169
1170
1171 *bytes_ret = element_size * length;
1172
1173
1174 g_free (data);
1175
1176 *data_ret = xdata;
1177 *actual_type_ret = GDK_NONE;
1178 *actual_size_ret = length;
1179 *actual_format_ret = actual_format;
1180 *actual_type_ret = actual_type;
1181 }
1182
1183 static Lisp_Object
1184 pgtk_get_window_property_as_lisp_data (struct pgtk_display_info *dpyinfo,
1185 GdkWindow *window, GdkAtom property,
1186 Lisp_Object target_type, GdkAtom selection_atom,
1187 bool for_multiple)
1188 {
1189 GdkAtom actual_type;
1190 int actual_format;
1191 unsigned long actual_size;
1192 unsigned char *data = 0;
1193 ptrdiff_t bytes = 0;
1194 Lisp_Object val;
1195 GdkDisplay *display = dpyinfo->display;
1196
1197 pgtk_get_window_property (window, &data, &bytes,
1198 &actual_type, &actual_format,
1199 &actual_size);
1200
1201 if (!data)
1202 {
1203 if (for_multiple)
1204 return Qnil;
1205
1206 if (gdk_selection_owner_get_for_display (display, selection_atom))
1207 {
1208 AUTO_STRING (format, "Selection owner couldn't convert: %s");
1209 CALLN (Fmessage, format,
1210 actual_type
1211 ? list2 (target_type,
1212 gdk_atom_to_symbol (actual_type))
1213 : target_type);
1214 return Qnil;
1215 }
1216 else
1217 {
1218 AUTO_STRING (format, "No selection: %s");
1219 CALLN (Fmessage, format,
1220 gdk_atom_to_symbol (selection_atom));
1221 return Qnil;
1222 }
1223 }
1224
1225 if (!for_multiple && property != GDK_NONE)
1226 gdk_property_delete (window, property);
1227
1228
1229
1230 val = selection_data_to_lisp_data (dpyinfo, data, bytes,
1231 actual_type, actual_format);
1232
1233
1234
1235 xfree (data);
1236 return val;
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264 static Lisp_Object
1265 selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo,
1266 const unsigned char *data,
1267 ptrdiff_t size, GdkAtom type, int format)
1268 {
1269 if (type == gdk_atom_intern_static_string ("NULL"))
1270 return QNULL;
1271
1272 else if (format == 8)
1273 {
1274 Lisp_Object str, lispy_type;
1275
1276 str = make_unibyte_string ((char *) data, size);
1277
1278
1279
1280
1281 if (type == gdk_atom_intern_static_string ("COMPOUND_TEXT"))
1282 lispy_type = QCOMPOUND_TEXT;
1283 else if (type == gdk_atom_intern_static_string ("UTF8_STRING"))
1284 lispy_type = QUTF8_STRING;
1285 else
1286 lispy_type = QSTRING;
1287
1288 Fput_text_property (make_fixnum (0), make_fixnum (size),
1289 Qforeign_selection, lispy_type, str);
1290 return str;
1291 }
1292
1293
1294 else if (format == 32
1295 && (type == GDK_SELECTION_TYPE_ATOM
1296
1297 || type == gdk_atom_intern_static_string ("ATOM_PAIR")))
1298 {
1299 ptrdiff_t i;
1300 GdkAtom *idata = (GdkAtom *) data;
1301
1302 if (size == sizeof (GdkAtom))
1303 return gdk_atom_to_symbol (idata[0]);
1304 else
1305 {
1306 Lisp_Object v = make_nil_vector (size / sizeof (GdkAtom));
1307
1308 for (i = 0; i < size / sizeof (GdkAtom); i++)
1309 ASET (v, i, gdk_atom_to_symbol (idata[i]));
1310 return v;
1311 }
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321 else if (format == 32 && size == sizeof (int))
1322 {
1323 if (type == GDK_SELECTION_TYPE_INTEGER)
1324 return INT_TO_INTEGER (((int *) data) [0]);
1325 else
1326 return INT_TO_INTEGER (((unsigned int *) data) [0]);
1327 }
1328 else if (format == 16 && size == sizeof (short))
1329 {
1330 if (type == GDK_SELECTION_TYPE_INTEGER)
1331 return make_fixnum (((short *) data) [0]);
1332 else
1333 return make_fixnum (((unsigned short *) data) [0]);
1334 }
1335
1336
1337
1338 else if (format == 16)
1339 {
1340 ptrdiff_t i;
1341 Lisp_Object v = make_uninit_vector (size / 2);
1342
1343 if (type == GDK_SELECTION_TYPE_INTEGER)
1344 {
1345 for (i = 0; i < size / 2; i++)
1346 {
1347 short j = ((short *) data) [i];
1348 ASET (v, i, make_fixnum (j));
1349 }
1350 }
1351 else
1352 {
1353 for (i = 0; i < size / 2; i++)
1354 {
1355 unsigned short j = ((unsigned short *) data) [i];
1356 ASET (v, i, make_fixnum (j));
1357 }
1358 }
1359 return v;
1360 }
1361 else
1362 {
1363 ptrdiff_t i;
1364 Lisp_Object v = make_nil_vector (size / sizeof (gint));
1365
1366 if (type == GDK_SELECTION_TYPE_INTEGER)
1367 {
1368 for (i = 0; i < size / sizeof (gint); i++)
1369 {
1370 int j = ((gint *) data) [i];
1371 ASET (v, i, INT_TO_INTEGER (j));
1372 }
1373 }
1374 else
1375 {
1376 for (i = 0; i < size / sizeof (gint); i++)
1377 {
1378 unsigned int j = ((unsigned int *) data) [i];
1379 ASET (v, i, INT_TO_INTEGER (j));
1380 }
1381 }
1382 return v;
1383 }
1384 }
1385
1386
1387
1388
1389
1390
1391
1392 static unsigned long
1393 cons_to_gdk_long (Lisp_Object obj)
1394 {
1395 if (G_MAXUINT32 <= INTMAX_MAX
1396 || NILP (Fnatnump (CONSP (obj) ? XCAR (obj) : obj)))
1397 return cons_to_signed (obj, 0, min (G_MAXUINT32, INTMAX_MAX));
1398 else
1399 return cons_to_unsigned (obj, G_MAXUINT32);
1400 }
1401
1402
1403
1404 static void
1405 lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo,
1406 Lisp_Object obj, struct selection_data *cs)
1407 {
1408 Lisp_Object type = Qnil;
1409
1410 eassert (cs != NULL);
1411 cs->nofree = false;
1412
1413 if (CONSP (obj) && SYMBOLP (XCAR (obj)))
1414 {
1415 type = XCAR (obj);
1416 obj = XCDR (obj);
1417 if (CONSP (obj) && NILP (XCDR (obj)))
1418 obj = XCAR (obj);
1419 }
1420
1421 if (EQ (obj, QNULL) || (EQ (type, QNULL)))
1422 {
1423 cs->format = 32;
1424 cs->size = 0;
1425 cs->data = NULL;
1426 type = QNULL;
1427 }
1428 else if (STRINGP (obj))
1429 {
1430 if (SCHARS (obj) < SBYTES (obj))
1431
1432 signal_error ("Non-ASCII string must be encoded in advance", obj);
1433 if (NILP (type))
1434 type = QSTRING;
1435 cs->format = 8;
1436 cs->size = SBYTES (obj);
1437 cs->data = SDATA (obj);
1438 cs->nofree = true;
1439 }
1440 else if (SYMBOLP (obj))
1441 {
1442 void *data = xmalloc (sizeof (GdkAtom) + 1);
1443 GdkAtom *x_atom_ptr = data;
1444 cs->data = data;
1445 cs->format = 32;
1446 cs->size = 1;
1447 cs->data[sizeof (GdkAtom)] = 0;
1448 *x_atom_ptr = symbol_to_gdk_atom (obj);
1449 if (NILP (type)) type = QATOM;
1450 }
1451 else if (RANGED_FIXNUMP (SHRT_MIN, obj, SHRT_MAX))
1452 {
1453 void *data = xmalloc (sizeof (short) + 1);
1454 short *short_ptr = data;
1455 cs->data = data;
1456 cs->format = 16;
1457 cs->size = 1;
1458 cs->data[sizeof (short)] = 0;
1459 *short_ptr = XFIXNUM (obj);
1460 if (NILP (type)) type = QINTEGER;
1461 }
1462 else if (INTEGERP (obj)
1463 || (CONSP (obj) && INTEGERP (XCAR (obj))
1464 && (FIXNUMP (XCDR (obj))
1465 || (CONSP (XCDR (obj))
1466 && FIXNUMP (XCAR (XCDR (obj)))))))
1467 {
1468 void *data = xmalloc (sizeof (unsigned long) + 1);
1469 unsigned long *x_long_ptr = data;
1470 cs->data = data;
1471 cs->format = 32;
1472 cs->size = 1;
1473 cs->data[sizeof (unsigned long)] = 0;
1474 *x_long_ptr = cons_to_gdk_long (obj);
1475 if (NILP (type)) type = QINTEGER;
1476 }
1477 else if (VECTORP (obj))
1478 {
1479
1480
1481
1482
1483 ptrdiff_t i;
1484 ptrdiff_t size = ASIZE (obj);
1485
1486 if (SYMBOLP (AREF (obj, 0)))
1487
1488 {
1489 void *data;
1490 GdkAtom *x_atoms;
1491 if (NILP (type)) type = QATOM;
1492 for (i = 0; i < size; i++)
1493 if (!SYMBOLP (AREF (obj, i)))
1494 signal_error ("All elements of selection vector must have same type", obj);
1495
1496 cs->data = data = xnmalloc (size, sizeof *x_atoms);
1497 x_atoms = data;
1498 cs->format = 32;
1499 cs->size = size;
1500 for (i = 0; i < size; i++)
1501 x_atoms[i] = symbol_to_gdk_atom (AREF (obj, i));
1502 }
1503 else
1504
1505 {
1506 int format = 16;
1507 int data_size = sizeof (short);
1508 void *data;
1509 unsigned long *x_atoms;
1510 short *shorts;
1511 if (NILP (type)) type = QINTEGER;
1512 for (i = 0; i < size; i++)
1513 {
1514 if (! RANGED_FIXNUMP (SHRT_MIN, AREF (obj, i), SHRT_MAX))
1515 {
1516
1517
1518
1519 data_size = sizeof (long);
1520 format = 32;
1521 break;
1522 }
1523 }
1524 cs->data = data = xnmalloc (size, data_size);
1525 x_atoms = data;
1526 shorts = data;
1527 cs->format = format;
1528 cs->size = size;
1529 for (i = 0; i < size; i++)
1530 {
1531 if (format == 32)
1532 x_atoms[i] = cons_to_gdk_long (AREF (obj, i));
1533 else
1534 shorts[i] = XFIXNUM (AREF (obj, i));
1535 }
1536 }
1537 }
1538 else
1539 signal_error ( "Unrecognized selection data", obj);
1540
1541 cs->type = symbol_to_gdk_atom (type);
1542 }
1543
1544 static Lisp_Object
1545 clean_local_selection_data (Lisp_Object obj)
1546 {
1547 if (CONSP (obj)
1548 && INTEGERP (XCAR (obj))
1549 && CONSP (XCDR (obj))
1550 && FIXNUMP (XCAR (XCDR (obj)))
1551 && NILP (XCDR (XCDR (obj))))
1552 obj = Fcons (XCAR (obj), XCDR (obj));
1553
1554 if (CONSP (obj)
1555 && INTEGERP (XCAR (obj))
1556 && FIXNUMP (XCDR (obj)))
1557 {
1558 if (BASE_EQ (XCAR (obj), make_fixnum (0)))
1559 return XCDR (obj);
1560 if (BASE_EQ (XCAR (obj), make_fixnum (-1)))
1561 return make_fixnum (- XFIXNUM (XCDR (obj)));
1562 }
1563 if (VECTORP (obj))
1564 {
1565 ptrdiff_t i;
1566 ptrdiff_t size = ASIZE (obj);
1567 Lisp_Object copy;
1568 if (size == 1)
1569 return clean_local_selection_data (AREF (obj, 0));
1570 copy = make_nil_vector (size);
1571 for (i = 0; i < size; i++)
1572 ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
1573 return copy;
1574 }
1575 return obj;
1576 }
1577
1578 DEFUN ("pgtk-own-selection-internal", Fpgtk_own_selection_internal,
1579 Spgtk_own_selection_internal, 2, 3, 0,
1580 doc:
1581
1582
1583
1584
1585
1586
1587 )
1588 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
1589 {
1590 if (NILP (frame)) frame = selected_frame;
1591 if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame)))
1592 error ("GDK selection unavailable for this frame");
1593
1594 CHECK_SYMBOL (selection);
1595 if (NILP (value)) error ("VALUE may not be nil");
1596 pgtk_own_selection (selection, value, frame);
1597 return value;
1598 }
1599
1600
1601
1602
1603
1604 DEFUN ("pgtk-get-selection-internal", Fpgtk_get_selection_internal,
1605 Spgtk_get_selection_internal, 2, 4, 0,
1606 doc:
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616 )
1617 (Lisp_Object selection_symbol, Lisp_Object target_type,
1618 Lisp_Object time_stamp, Lisp_Object terminal)
1619 {
1620 Lisp_Object val = Qnil;
1621 Lisp_Object maybe_alias;
1622 struct frame *f = frame_for_pgtk_selection (terminal);
1623
1624 CHECK_SYMBOL (selection_symbol);
1625 CHECK_SYMBOL (target_type);
1626
1627 if (EQ (target_type, QMULTIPLE))
1628 error ("Retrieving MULTIPLE selections is currently unimplemented");
1629 if (!f)
1630 error ("GDK selection unavailable for this frame");
1631
1632
1633
1634 maybe_alias = Fassq (selection_symbol, Vpgtk_selection_alias_alist);
1635
1636 if (!NILP (maybe_alias))
1637 {
1638 selection_symbol = XCDR (maybe_alias);
1639 CHECK_SYMBOL (selection_symbol);
1640 }
1641
1642 val = pgtk_get_local_selection (selection_symbol, target_type, true,
1643 FRAME_DISPLAY_INFO (f));
1644
1645 if (NILP (val) && FRAME_LIVE_P (f))
1646 {
1647 Lisp_Object frame;
1648 XSETFRAME (frame, f);
1649 return pgtk_get_foreign_selection (selection_symbol, target_type,
1650 time_stamp, frame);
1651 }
1652
1653 if (CONSP (val) && SYMBOLP (XCAR (val)))
1654 {
1655 val = XCDR (val);
1656 if (CONSP (val) && NILP (XCDR (val)))
1657 val = XCAR (val);
1658 }
1659 return clean_local_selection_data (val);
1660 }
1661
1662 DEFUN ("pgtk-disown-selection-internal", Fpgtk_disown_selection_internal,
1663 Spgtk_disown_selection_internal, 1, 3, 0,
1664 doc:
1665
1666
1667
1668
1669
1670
1671
1672 )
1673 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
1674 {
1675 guint32 timestamp;
1676 GdkAtom selection_atom;
1677 struct frame *f = frame_for_pgtk_selection (terminal);
1678 struct pgtk_display_info *dpyinfo;
1679
1680 if (!f)
1681 return Qnil;
1682
1683 dpyinfo = FRAME_DISPLAY_INFO (f);
1684 CHECK_SYMBOL (selection);
1685
1686
1687 if (NILP (LOCAL_SELECTION (selection, dpyinfo)))
1688 return Qnil;
1689
1690 selection_atom = symbol_to_gdk_atom (selection);
1691
1692 block_input ();
1693 if (NILP (time_object))
1694 timestamp = dpyinfo->last_user_time;
1695 else
1696 CONS_TO_INTEGER (time_object, guint32, timestamp);
1697 gdk_selection_owner_set_for_display (dpyinfo->display, NULL,
1698 selection_atom, timestamp,
1699 TRUE);
1700 unblock_input ();
1701
1702 return Qt;
1703 }
1704
1705 DEFUN ("pgtk-selection-owner-p", Fpgtk_selection_owner_p, Spgtk_selection_owner_p,
1706 0, 2, 0,
1707 doc:
1708
1709
1710
1711
1712
1713
1714
1715
1716 )
1717 (Lisp_Object selection, Lisp_Object terminal)
1718 {
1719 struct frame *f = frame_for_pgtk_selection (terminal);
1720
1721 CHECK_SYMBOL (selection);
1722 if (NILP (selection)) selection = QPRIMARY;
1723 if (EQ (selection, Qt)) selection = QSECONDARY;
1724
1725 if (f && !NILP (LOCAL_SELECTION (selection, FRAME_DISPLAY_INFO (f))))
1726 return Qt;
1727 else
1728 return Qnil;
1729 }
1730
1731 DEFUN ("pgtk-selection-exists-p", Fpgtk_selection_exists_p, Spgtk_selection_exists_p,
1732 0, 2, 0,
1733 doc:
1734
1735
1736
1737
1738
1739
1740
1741 )
1742 (Lisp_Object selection, Lisp_Object terminal)
1743 {
1744 GdkWindow *owner;
1745 GdkAtom atom;
1746 struct frame *f = frame_for_pgtk_selection (terminal);
1747 struct pgtk_display_info *dpyinfo;
1748
1749 CHECK_SYMBOL (selection);
1750 if (NILP (selection)) selection = QPRIMARY;
1751 if (EQ (selection, Qt)) selection = QSECONDARY;
1752
1753 if (!f)
1754 return Qnil;
1755
1756 dpyinfo = FRAME_DISPLAY_INFO (f);
1757
1758 if (!NILP (LOCAL_SELECTION (selection, dpyinfo)))
1759 return Qt;
1760
1761 atom = symbol_to_gdk_atom (selection);
1762 if (atom == 0) return Qnil;
1763 block_input ();
1764 owner = gdk_selection_owner_get_for_display (dpyinfo->display, atom);
1765 unblock_input ();
1766 return (owner ? Qt : Qnil);
1767 }
1768
1769
1770
1771
1772
1773
1774 void
1775 pgtk_handle_selection_notify (GdkEventSelection *event)
1776 {
1777
1778
1779
1780 if (event->selection != reading_which_selection)
1781 return;
1782
1783 XSETCAR (reading_selection_reply,
1784 (event->property != GDK_NONE ? Qt : Qlambda));
1785 }
1786
1787
1788
1789
1790
1791
1792 DEFUN ("pgtk-register-dnd-targets", Fpgtk_register_dnd_targets,
1793 Spgtk_register_dnd_targets, 2, 2, 0,
1794 doc:
1795
1796 )
1797 (Lisp_Object frame, Lisp_Object targets)
1798 {
1799 struct frame *f;
1800 GtkTargetEntry *entries;
1801 GtkTargetList *list;
1802 ptrdiff_t length, n;
1803 Lisp_Object tem, t;
1804 char *buf;
1805 USE_SAFE_ALLOCA;
1806
1807 f = decode_window_system_frame (frame);
1808 CHECK_LIST (targets);
1809 length = list_length (targets);
1810 n = 0;
1811 entries = SAFE_ALLOCA (sizeof *entries * length);
1812 memset (entries, 0, sizeof *entries * length);
1813 tem = targets;
1814
1815 FOR_EACH_TAIL (tem)
1816 {
1817 if (!CONSP (tem))
1818 continue;
1819
1820 t = XCAR (tem);
1821
1822 CHECK_STRING (t);
1823 SAFE_ALLOCA_STRING (buf, t);
1824
1825 entries[n++].target = buf;
1826 }
1827 CHECK_LIST_END (tem, targets);
1828
1829 if (n != length)
1830 emacs_abort ();
1831
1832 list = gtk_target_list_new (entries, n);
1833 gtk_drag_dest_set_target_list (FRAME_GTK_WIDGET (f), list);
1834 gtk_target_list_unref (list);
1835
1836 SAFE_FREE ();
1837
1838 return Qnil;
1839 }
1840
1841 DEFUN ("pgtk-drop-finish", Fpgtk_drop_finish, Spgtk_drop_finish, 3, 3, 0,
1842 doc:
1843
1844
1845
1846
1847 )
1848 (Lisp_Object success, Lisp_Object timestamp, Lisp_Object delete)
1849 {
1850 pgtk_finish_drop (success, timestamp, delete);
1851
1852 return Qnil;
1853 }
1854
1855 DEFUN ("pgtk-update-drop-status", Fpgtk_update_drop_status,
1856 Spgtk_update_drop_status, 2, 2, 0,
1857 doc:
1858
1859 )
1860 (Lisp_Object action, Lisp_Object timestamp)
1861 {
1862 pgtk_update_drop_status (action, timestamp);
1863
1864 return Qnil;
1865 }
1866
1867 void
1868 syms_of_pgtkselect (void)
1869 {
1870 DEFSYM (QCLIPBOARD, "CLIPBOARD");
1871 DEFSYM (QSECONDARY, "SECONDARY");
1872 DEFSYM (QTEXT, "TEXT");
1873 DEFSYM (QFILE_NAME, "FILE_NAME");
1874 DEFSYM (QSTRING, "STRING");
1875 DEFSYM (QINTEGER, "INTEGER");
1876 DEFSYM (QTIMESTAMP, "TIMESTAMP");
1877 DEFSYM (QTEXT, "TEXT");
1878 DEFSYM (QMULTIPLE, "MULTIPLE");
1879 DEFSYM (QNULL, "NULL");
1880 DEFSYM (QATOM, "ATOM");
1881 DEFSYM (QTARGETS, "TARGETS");
1882 DEFSYM (QUTF8_STRING, "UTF8_STRING");
1883 DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT");
1884
1885 DEFSYM (Qforeign_selection, "foreign-selection");
1886
1887 DEFSYM (Qpgtk_sent_selection_functions, "pgtk-sent-selection-functions");
1888 DEFSYM (Qpgtk_lost_selection_functions, "pgtk-lost-selection-functions");
1889
1890 defsubr (&Spgtk_disown_selection_internal);
1891 defsubr (&Spgtk_get_selection_internal);
1892 defsubr (&Spgtk_own_selection_internal);
1893 defsubr (&Spgtk_selection_exists_p);
1894 defsubr (&Spgtk_selection_owner_p);
1895 defsubr (&Spgtk_register_dnd_targets);
1896 defsubr (&Spgtk_update_drop_status);
1897 defsubr (&Spgtk_drop_finish);
1898
1899 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
1900 doc: );
1901 Vselection_converter_alist = Qnil;
1902
1903 DEFVAR_LISP ("pgtk-lost-selection-functions", Vpgtk_lost_selection_functions,
1904 doc:
1905
1906
1907
1908 );
1909 Vpgtk_lost_selection_functions = Qnil;
1910
1911 DEFVAR_LISP ("pgtk-sent-selection-functions", Vpgtk_sent_selection_functions,
1912 doc:
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922 );
1923 Vpgtk_sent_selection_functions = Qnil;
1924
1925 DEFVAR_LISP ("pgtk-sent-selection-hooks", Vpgtk_sent_selection_hooks,
1926 doc:
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936 );
1937 Vpgtk_sent_selection_hooks = Qnil;
1938
1939 DEFVAR_INT ("pgtk-selection-timeout", pgtk_selection_timeout,
1940 doc:
1941
1942 );
1943 pgtk_selection_timeout = 0;
1944
1945 DEFVAR_LISP ("pgtk-selection-alias-alist", Vpgtk_selection_alias_alist,
1946 doc:
1947
1948
1949
1950
1951 );
1952 Vpgtk_selection_alias_alist = Qnil;
1953
1954 reading_selection_reply = Fcons (Qnil, Qnil);
1955 staticpro (&reading_selection_reply);
1956
1957 property_change_reply = Fcons (Qnil, Qnil);
1958 staticpro (&property_change_reply);
1959 }