1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   All rights reserved.
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatThis file is part of x11vnc.
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is free software; you can redistribute it and/or modify
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatit under the terms of the GNU General Public License as published by
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe Free Software Foundation; either version 2 of the License, or (at
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatyour option) any later version.
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is distributed in the hope that it will be useful,
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatbut WITHOUT ANY WARRANTY; without even the implied warranty of
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatGNU General Public License for more details.
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatYou should have received a copy of the GNU General Public License
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatalong with x11vnc; if not, write to the Free Software
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehator see <http://www.gnu.org/licenses/>.
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatIn addition, as a special exception, Karl J. Runge
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatgives permission to link the code of its release of x11vnc with the
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOpenSSL project's "OpenSSL" library (or with modified versions of it
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthat use the same license as the "OpenSSL" library), and distribute
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe linked executables.  You must obey the GNU General Public License
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatin all respects for all of the code used other than "OpenSSL".  If you
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmodify this file, you may extend this exception to your version of the
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfile, but you are not obligated to do so.  If you do not wish to do
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatso, delete this exception statement from your version.
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*/
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* -- selection.c -- */
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "x11vnc.h"
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "cleanup.h"
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "connections.h"
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "unixpw.h"
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "win_utils.h"
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xwrappers.h"
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Selection/Cutbuffer/Clipboard handlers.
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint own_primary = 0;	/* whether we currently own PRIMARY or not */
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint set_primary = 1;
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint own_clipboard = 0;	/* whether we currently own CLIPBOARD or not */
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint set_clipboard = 1;
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint set_cutbuffer = 0;	/* to avoid bouncing the CutText right back */
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint sel_waittime = 15;	/* some seconds to skip before first send */
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow selwin = None;	/* special window for our selection */
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatAtom clipboard_atom = None;
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is where we keep our selection: the string sent TO us from VNC
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * clients, and the string sent BY us to requesting X11 clients.
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *xcut_str_primary = NULL;
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *xcut_str_clipboard = NULL;
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid selection_request(XEvent *ev, char *type);
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint check_sel_direction(char *dir, char *label, char *sel, int len);
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid cutbuffer_send(void);
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid selection_send(XEvent *ev);
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid resend_selection(char *type);
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Our callbacks instruct us to check for changes in the cutbuffer
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and PRIMARY and CLIPBOARD selection on the local X11 display.
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * TODO: check if malloc does not cause performance issues (esp. WRT
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SelectionNotify handling).
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char cutbuffer_str[PROP_MAX+1];
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char primary_str[PROP_MAX+1];
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char clipboard_str[PROP_MAX+1];
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int cutbuffer_len = 0;
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int primary_len   = 0;
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int clipboard_len = 0;
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * An X11 (not VNC) client on the local display has requested the selection
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * from us (because we are the current owner).
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * n.b.: our caller already has the X_LOCK.
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid selection_request(XEvent *ev, char *type) {
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!ev || !type) {}
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return;
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSelectionEvent notify_event;
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSelectionRequestEvent *req_event;
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XErrorHandler old_handler;
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *str;
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int length;
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned char *data;
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static Atom xa_targets = None;
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int sync_it = -1;
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# ifndef XA_LENGTH
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned long XA_LENGTH;
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# endif
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# ifndef XA_LENGTH
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XA_LENGTH = XInternAtom(dpy, "LENGTH", True);
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# endif
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sync_it < 0) {
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (getenv("X11VNC_SENDEVENT_SYNC")) {
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sync_it = 1;
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sync_it = 0;
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	req_event = &(ev->xselectionrequest);
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	notify_event.type 	= SelectionNotify;
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	notify_event.display	= req_event->display;
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	notify_event.requestor	= req_event->requestor;
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	notify_event.selection	= req_event->selection;
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	notify_event.target	= req_event->target;
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	notify_event.time	= req_event->time;
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (req_event->property == None) {
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		notify_event.property = req_event->target;
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		notify_event.property = req_event->property;
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(type, "PRIMARY")) {
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		str = xcut_str_primary;
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(type, "CLIPBOARD")) {
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		str = xcut_str_clipboard;
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (str) {
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		length = strlen(str);
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		length = 0;
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (debug_sel) {
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("%s\trequest event:   owner=0x%x requestor=0x%x sel=%03d targ=%d prop=%d\n",
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			type, req_event->owner, req_event->requestor, req_event->selection,
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			req_event->target, req_event->property);
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (xa_targets == None) {
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		xa_targets = XInternAtom(dpy, "TARGETS", False);
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* the window may have gone away, so trap errors */
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	old_handler = XSetErrorHandler(trap_xerror);
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (ev->xselectionrequest.target == XA_LENGTH) {
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* length request */
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int ret;
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		long llength = (long) length;
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ret = XChangeProperty(ev->xselectionrequest.display,
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.requestor,
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.property,
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.target, 32, PropModeReplace,
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    (unsigned char *) &llength, 1);	/* had sizeof(unsigned int) = 4 before... */
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("LENGTH: XChangeProperty() -> %d\n", ret);
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (xa_targets != None && ev->xselectionrequest.target == xa_targets) {
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* targets request */
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int ret;
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		Atom targets[2];
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		targets[0] = (Atom) xa_targets;
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		targets[1] = (Atom) XA_STRING;
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ret = XChangeProperty(ev->xselectionrequest.display,
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.requestor,
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.property,
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.target, 32, PropModeReplace,
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    (unsigned char *) targets, 2);
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("TARGETS: XChangeProperty() -> %d -- sz1: %d  sz2: %d\n",
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    ret, sizeof(targets[0]), sizeof(targets)/sizeof(targets[0]));
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* data request */
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int ret;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		data = (unsigned char *)str;
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ret = XChangeProperty(ev->xselectionrequest.display,
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.requestor,
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.property,
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselectionrequest.target, 8, PropModeReplace,
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    data, length);
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("DATA: XChangeProperty() -> %d\n", ret);
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! trapped_xerror) {
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int ret = -2, skip_it = 0, ms = 0;
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		double now = dnow();
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		static double last_check = 0.0;
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (now > last_check + 0.2) {
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			XFlush_wr(dpy);
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!valid_window(req_event->requestor , NULL, 1)) {
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sync_it = 1;
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				skip_it = 1;
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (debug_sel) {
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("selection_request: not a valid window: 0x%x\n",
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					    req_event->requestor);
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				ms = 10;
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (trapped_xerror) {
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sync_it = 1;
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				skip_it = 1;
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			last_check = dnow();
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!skip_it) {
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ret = XSendEvent(req_event->display, req_event->requestor, False, 0,
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    (XEvent *)&notify_event);
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("XSendEvent() -> %d\n", ret);
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (ms > 0) {
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(ms * 1000);
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (trapped_xerror) {
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("selection_request: ignored XError while sending "
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    "%s selection to 0x%x.\n", type, req_event->requestor);
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XFlush_wr(dpy);
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sync_it) {
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		usleep(10 * 1000);
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		XSync(dpy, False);
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSetErrorHandler(old_handler);
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint check_sel_direction(char *dir, char *label, char *sel, int len) {
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int db = 0, ok = 1;
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (debug_sel) {
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		db = 1;
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sel_direction) {
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(sel_direction, "debug")) {
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			db = 1;
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strcmp(sel_direction, "debug")) {
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (strstr(sel_direction, dir) == NULL) {
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				ok = 0;
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (db) {
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char str[40];
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int n = 40;
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		strncpy(str, sel, n);
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		str[n-1] = '\0';
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (len < n) {
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			str[len] = '\0';
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("%s: '%s'\n", label, str);
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (ok) {
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("%s: %s-ing it.\n", label, dir);
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("%s: NOT %s-ing it.\n", label, dir);
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return ok;
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * CUT_BUFFER0 property on the local display has changed, we read and
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * store it and send it out to any connected VNC clients.
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * n.b.: our caller already has the X_LOCK.
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid cutbuffer_send(void) {
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return;
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Atom type;
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int format, slen, dlen, len;
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned long nitems = 0, bytes_after = 0;
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned char* data = NULL;
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cutbuffer_str[0] = '\0';
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	slen = 0;
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* read the property value into cutbuffer_str: */
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	do {
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (XGetWindowProperty(dpy, DefaultRootWindow(dpy),
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    XA_CUT_BUFFER0, nitems/4, PROP_MAX/16, False,
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    AnyPropertyType, &type, &format, &nitems, &bytes_after,
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    &data) == Success) {
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			dlen = nitems * (format/8);
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (slen + dlen > PROP_MAX) {
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* too big */
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("warning: truncating large CUT_BUFFER0"
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				   " selection > %d bytes.\n", PROP_MAX);
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				XFree_wr(data);
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			memcpy(cutbuffer_str+slen, data, dlen);
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			slen += dlen;
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			cutbuffer_str[slen] = '\0';
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			XFree_wr(data);
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} while (bytes_after > 0);
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cutbuffer_str[PROP_MAX] = '\0';
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (debug_sel) {
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("cutbuffer_send: '%s'\n", cutbuffer_str);
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! all_clients_initialized()) {
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("cutbuffer_send: no send: uninitialized clients\n");
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return; /* some clients initializing, cannot send */
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_in_progress) {
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* now send it to any connected VNC clients (rfbServerCutText) */
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!screen) {
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cutbuffer_len = len = strlen(cutbuffer_str);
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (check_sel_direction("send", "cutbuffer_send", cutbuffer_str, len)) {
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbSendServerCutText(screen, cutbuffer_str, len);
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * "callback" for our SelectionNotify polling.  We try to determine if
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the PRIMARY selection has changed (checking length and first CHKSZ bytes)
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and if it has we store it and send it off to any connected VNC clients.
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * n.b.: our caller already has the X_LOCK.
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * TODO: if we were willing to use libXt, we could perhaps get selection
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * timestamps to speed up the checking... XtGetSelectionValue().
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Also: XFIXES has XFixesSelectSelectionInput().
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CHKSZ 32
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid selection_send(XEvent *ev) {
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!ev) {}
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return;
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Atom type;
381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int format, slen, dlen, oldlen, newlen, toobig = 0, len;
382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int err = 0, sent_one = 0;
383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char before[CHKSZ], after[CHKSZ];
384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned long nitems = 0, bytes_after = 0;
385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned char* data = NULL;
386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *selection_str;
387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/*
390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * remember info about our last value of PRIMARY (or CUT_BUFFER0)
391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * so we can check for any changes below.
392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 */
393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (ev->xselection.selection == XA_PRIMARY) {
394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! watch_primary) {
395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return;
396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		selection_str = primary_str;
398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("selection_send: event PRIMARY   prop: %d  requestor: 0x%x  atom: %d\n",
400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    ev->xselection.property, ev->xselection.requestor, ev->xselection.selection);
401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (clipboard_atom && ev->xselection.selection == clipboard_atom)  {
403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! watch_clipboard) {
404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return;
405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		selection_str = clipboard_str;
407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("selection_send: event CLIPBOARD prop: %d  requestor: 0x%x atom: %d\n",
409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    ev->xselection.property, ev->xselection.requestor, ev->xselection.selection);
410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	oldlen = strlen(selection_str);
416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	strncpy(before, selection_str, CHKSZ);
417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	selection_str[0] = '\0';
419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	slen = 0;
420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* read in the current value of PRIMARY or CLIPBOARD: */
422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	do {
423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (XGetWindowProperty(dpy, ev->xselection.requestor,
424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselection.property, nitems/4, PROP_MAX/16, True,
425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    AnyPropertyType, &type, &format, &nitems, &bytes_after,
426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    &data) == Success) {
427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			dlen = nitems * (format/8);
429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (slen + dlen > PROP_MAX) {
430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* too big */
431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				toobig = 1;
432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				XFree_wr(data);
433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (err) {	/* cut down on messages */
434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					err = 5;
437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("warning: truncating large PRIMARY"
439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    "/CLIPBOARD selection > %d bytes.\n",
440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    PROP_MAX);
441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (debug_sel) fprintf(stderr, "selection_send: data: '%s' dlen: %d nitems: %lu ba: %lu\n", data, dlen, nitems, bytes_after);
444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			memcpy(selection_str+slen, data, dlen);
445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			slen += dlen;
446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			selection_str[slen] = '\0';
447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			XFree_wr(data);
448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} while (bytes_after > 0);
450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! toobig) {
452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		err = 0;
453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (err) {
454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		err--;
455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! sent_one) {
458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* try to force a send first time in */
459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		oldlen = -1;
460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sent_one = 1;
461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (debug_sel) {
463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("selection_send:  %s '%s'\n",
464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    ev->xselection.selection == XA_PRIMARY ? "PRIMARY  " : "CLIPBOARD",
465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    selection_str);
466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* look for changes in the new value */
469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	newlen = strlen(selection_str);
470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	strncpy(after, selection_str, CHKSZ);
471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (oldlen == newlen && strncmp(before, after, CHKSZ) == 0) {
473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* evidently no change */
474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (debug_sel) {
475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("selection_send:  no change.\n");
476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (newlen == 0) {
480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* do not bother sending a null string out */
481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! all_clients_initialized()) {
485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("selection_send: no send: uninitialized clients\n");
486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return; /* some clients initializing, cannot send */
487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_in_progress) {
490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* now send it to any connected VNC clients (rfbServerCutText) */
494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!screen) {
495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	len = newlen;
499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (ev->xselection.selection == XA_PRIMARY) {
500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		primary_len = len;
501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (clipboard_atom && ev->xselection.selection == clipboard_atom)  {
502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clipboard_len = len;
503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (check_sel_direction("send", "selection_send", selection_str, len)) {
505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbSendServerCutText(screen, selection_str, len);
506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid resend_selection(char *type) {
511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!type) {}
514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return;
515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *selection_str = "";
517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int len = 0;
518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! all_clients_initialized()) {
522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("selection_send: no send: uninitialized clients\n");
523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return; /* some clients initializing, cannot send */
524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_in_progress) {
526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!screen) {
529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(type, "cutbuffer")) {
533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		selection_str = cutbuffer_str;
534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		len = cutbuffer_len;
535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(type, "clipboard")) {
536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		selection_str = clipboard_str;
537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		len = clipboard_len;
538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(type, "primary")) {
539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		selection_str = primary_str;
540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		len = primary_len;
541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (check_sel_direction("send", "selection_send", selection_str, len)) {
543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbSendServerCutText(screen, selection_str, len);
544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
549