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 *)¬ify_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