Bind text to binary clipboard

pull/69/head
Lauri Kasanen 4 years ago
parent 369bee745e
commit b2cfaafff9

@ -438,11 +438,6 @@ void VNCSConnectionST::sendBinaryClipboardDataOrClose(const char* mime,
try { try {
if (!(accessRights & AccessCutText)) return; if (!(accessRights & AccessCutText)) return;
if (!rfb::Server::sendCutText) return; if (!rfb::Server::sendCutText) return;
if (msSince(&lastClipboardOp) < (unsigned) rfb::Server::DLP_ClipDelay) {
vlog.info("DLP: client %s: refused to send binary clipboard, too soon",
sock->getPeerAddress());
return;
}
if (rfb::Server::DLP_ClipSendMax && len > (unsigned) rfb::Server::DLP_ClipSendMax) { if (rfb::Server::DLP_ClipSendMax && len > (unsigned) rfb::Server::DLP_ClipSendMax) {
vlog.info("DLP: client %s: refused to send binary clipboard, too large", vlog.info("DLP: client %s: refused to send binary clipboard, too large",
sock->getPeerAddress()); sock->getPeerAddress());
@ -454,8 +449,6 @@ void VNCSConnectionST::sendBinaryClipboardDataOrClose(const char* mime,
addBinaryClipboard(mime, data, len); addBinaryClipboard(mime, data, len);
binclipTimer.start(100); binclipTimer.start(100);
gettimeofday(&lastClipboardOp, NULL);
} catch(rdr::Exception& e) { } catch(rdr::Exception& e) {
close(e.str()); close(e.str());
} }
@ -1450,7 +1443,15 @@ void VNCSConnectionST::writeDataUpdate()
void VNCSConnectionST::writeBinaryClipboard() void VNCSConnectionST::writeBinaryClipboard()
{ {
if (msSince(&lastClipboardOp) < (unsigned) rfb::Server::DLP_ClipDelay) {
vlog.info("DLP: client %s: refused to send binary clipboard, too soon",
sock->getPeerAddress());
return;
}
writer()->writeBinaryClipboard(binaryClipboard); writer()->writeBinaryClipboard(binaryClipboard);
gettimeofday(&lastClipboardOp, NULL);
} }
void VNCSConnectionST::screenLayoutChange(rdr::U16 reason) void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)

@ -166,6 +166,7 @@ static void parseClipTypes()
// Hardcoded filters // Hardcoded filters
if (!strcmp(cur, "TEXT") || if (!strcmp(cur, "TEXT") ||
!strcmp(cur, "STRING") || !strcmp(cur, "STRING") ||
strstr(cur, "text/plain") ||
!strcmp(cur, "UTF8_STRING")) !strcmp(cur, "UTF8_STRING"))
continue; continue;

@ -49,6 +49,7 @@ static Bool htmlPngPresent;
static unsigned *mimeIndexesFromClient; static unsigned *mimeIndexesFromClient;
static unsigned numMimesFromClient; static unsigned numMimesFromClient;
static Bool textFromClient;
static WindowPtr pWindow; static WindowPtr pWindow;
static Window wid; static Window wid;
@ -72,8 +73,7 @@ static int vncCreateSelectionWindow(void);
static int vncOwnSelection(Atom selection); static int vncOwnSelection(Atom selection);
static int vncConvertSelection(ClientPtr client, Atom selection, static int vncConvertSelection(ClientPtr client, Atom selection,
Atom target, Atom property, Atom target, Atom property,
Window requestor, CARD32 time, Window requestor, CARD32 time);
const char* data, int len);
static int vncProcConvertSelection(ClientPtr client); static int vncProcConvertSelection(ClientPtr client);
static void vncSelectionRequest(Atom selection, Atom target); static void vncSelectionRequest(Atom selection, Atom target);
static int vncProcSendEvent(ClientPtr client); static int vncProcSendEvent(ClientPtr client);
@ -99,6 +99,7 @@ void vncSelectionInit(void)
unsigned i; unsigned i;
mimeIndexesFromClient = calloc(dlp_num_mimetypes(), sizeof(unsigned)); mimeIndexesFromClient = calloc(dlp_num_mimetypes(), sizeof(unsigned));
numMimesFromClient = 0; numMimesFromClient = 0;
textFromClient = FALSE;
xaBinclips = calloc(dlp_num_mimetypes(), sizeof(Atom)); xaBinclips = calloc(dlp_num_mimetypes(), sizeof(Atom));
htmlPngPresent = FALSE; htmlPngPresent = FALSE;
Bool htmlfound = FALSE, pngfound = FALSE; Bool htmlfound = FALSE, pngfound = FALSE;
@ -132,7 +133,7 @@ void vncSelectionInit(void)
FatalError("Add VNC ClientStateCallback failed\n"); FatalError("Add VNC ClientStateCallback failed\n");
} }
void vncHandleClipboardRequest(void) static void vncHandleClipboardRequest(void)
{ {
if (activeSelection == None) { if (activeSelection == None) {
LOG_DEBUG("Got request for local clipboard although no clipboard is active"); LOG_DEBUG("Got request for local clipboard although no clipboard is active");
@ -217,12 +218,16 @@ void vncHandleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]
break; break;
} }
} }
if (!strcmp(mimes[i], "text/plain"))
textFromClient = TRUE;
} }
numMimesFromClient = valid; numMimesFromClient = valid;
LOG_DEBUG("Client sent %u mimes, %u were valid", num, valid); LOG_DEBUG("Client sent %u mimes, %u were valid", num, valid);
} else { } else {
struct VncDataTarget* next; struct VncDataTarget* next;
numMimesFromClient = 0; numMimesFromClient = 0;
textFromClient = FALSE;
if (pWindow == NULL) if (pWindow == NULL)
return; return;
@ -250,39 +255,6 @@ void vncHandleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]
} }
} }
void vncHandleClipboardData(const char* data, int len)
{
struct VncDataTarget* next;
LOG_DEBUG("Got remote clipboard data, sending to X11 clients");
while (vncDataTargetHead != NULL) {
int rc;
xEvent event;
rc = vncConvertSelection(vncDataTargetHead->client,
vncDataTargetHead->selection,
vncDataTargetHead->target,
vncDataTargetHead->property,
vncDataTargetHead->requestor,
vncDataTargetHead->time,
data, len);
if (rc != Success) {
event.u.u.type = SelectionNotify;
event.u.selectionNotify.time = vncDataTargetHead->time;
event.u.selectionNotify.requestor = vncDataTargetHead->requestor;
event.u.selectionNotify.selection = vncDataTargetHead->selection;
event.u.selectionNotify.target = vncDataTargetHead->target;
event.u.selectionNotify.property = None;
WriteEventsToClient(vncDataTargetHead->client, 1, &event);
}
next = vncDataTargetHead->next;
free(vncDataTargetHead);
vncDataTargetHead = next;
}
}
static int vncCreateSelectionWindow(void) static int vncCreateSelectionWindow(void)
{ {
ScreenPtr pScreen; ScreenPtr pScreen;
@ -381,8 +353,7 @@ static Bool clientHasBinaryAtom(const Atom target, unsigned *which)
static int vncConvertSelection(ClientPtr client, Atom selection, static int vncConvertSelection(ClientPtr client, Atom selection,
Atom target, Atom property, Atom target, Atom property,
Window requestor, CARD32 time, Window requestor, CARD32 time)
const char* data, int len)
{ {
Selection *pSel; Selection *pSel;
WindowPtr pWin; WindowPtr pWin;
@ -392,13 +363,8 @@ static int vncConvertSelection(ClientPtr client, Atom selection,
xEvent event; xEvent event;
if (data == NULL) {
LOG_DEBUG("Selection request for %s (type %s)", LOG_DEBUG("Selection request for %s (type %s)",
NameForAtom(selection), NameForAtom(target)); NameForAtom(selection), NameForAtom(target));
} else {
LOG_DEBUG("Sending data for selection request for %s (type %s)",
NameForAtom(selection), NameForAtom(target));
}
rc = dixLookupSelection(&pSel, selection, client, DixGetAttrAccess); rc = dixLookupSelection(&pSel, selection, client, DixGetAttrAccess);
if (rc != Success) if (rc != Success)
@ -453,37 +419,13 @@ static int vncConvertSelection(ClientPtr client, Atom selection,
len, (unsigned char *) data, TRUE); len, (unsigned char *) data, TRUE);
if (rc != Success) if (rc != Success)
return rc; return rc;
} else { } else if (textFromClient) {
if (data == NULL) { const unsigned char *data;
struct VncDataTarget* vdt; unsigned len;
vncGetBinaryClipboardData("text/plain", &data, &len);
if ((target != xaSTRING) && (target != xaTEXT) &&
(target != xaUTF8_STRING))
return BadMatch;
vdt = calloc(1, sizeof(struct VncDataTarget));
if (vdt == NULL)
return BadAlloc;
vdt->client = client;
vdt->selection = selection;
vdt->target = target;
vdt->property = property;
vdt->requestor = requestor;
vdt->time = time;
vdt->next = vncDataTargetHead;
vncDataTargetHead = vdt;
LOG_DEBUG("Requesting clipboard data from client");
//vncRequestClipboard();
return Success;
} else {
if ((target == xaSTRING) || (target == xaTEXT)) { if ((target == xaSTRING) || (target == xaTEXT)) {
char* latin1; char* latin1;
latin1 = vncUTF8ToLatin1(data, (size_t)-1); latin1 = vncUTF8ToLatin1(data, (size_t)-1);
if (latin1 == NULL) if (latin1 == NULL)
return BadAlloc; return BadAlloc;
@ -505,7 +447,10 @@ static int vncConvertSelection(ClientPtr client, Atom selection,
} else { } else {
return BadMatch; return BadMatch;
} }
} } else {
LOG_ERROR("Text clipboard paste requested, but client sent no text");
return BadMatch;
} }
event.u.u.type = SelectionNotify; event.u.u.type = SelectionNotify;
@ -544,7 +489,7 @@ static int vncProcConvertSelection(ClientPtr client)
pSel->window == wid) { pSel->window == wid) {
rc = vncConvertSelection(client, stuff->selection, rc = vncConvertSelection(client, stuff->selection,
stuff->target, stuff->property, stuff->target, stuff->property,
stuff->requestor, stuff->time, NULL, 0); stuff->requestor, stuff->time);
if (rc != Success) { if (rc != Success) {
xEvent event; xEvent event;
@ -650,6 +595,7 @@ static void vncHandleSelection(Atom selection, Atom target,
LOG_DEBUG("Compatible format found, notifying clients"); LOG_DEBUG("Compatible format found, notifying clients");
activeSelection = selection; activeSelection = selection;
vncAnnounceClipboard(TRUE); vncAnnounceClipboard(TRUE);
vncHandleClipboardRequest();
} }
} else { } else {
if (vncHasAtom(xaUTF8_STRING, (const Atom*)prop->data, prop->size)) if (vncHasAtom(xaUTF8_STRING, (const Atom*)prop->data, prop->size))
@ -697,10 +643,10 @@ static void vncHandleSelection(Atom selection, Atom target,
if (utf8 == NULL) if (utf8 == NULL)
return; return;
LOG_DEBUG("Sending clipboard to clients (%d bytes)", LOG_DEBUG("Sending text part of binary clipboard to clients (%d bytes)",
(int)strlen(utf8)); (int)strlen(utf8));
//vncSendClipboardData(utf8); vncSendBinaryClipboardData("text/plain", utf8, strlen(utf8));
vncStrFree(utf8); vncStrFree(utf8);
} else if (target == xaUTF8_STRING) { } else if (target == xaUTF8_STRING) {
@ -715,10 +661,10 @@ static void vncHandleSelection(Atom selection, Atom target,
if (filtered == NULL) if (filtered == NULL)
return; return;
LOG_DEBUG("Sending clipboard to clients (%d bytes)", LOG_DEBUG("Sending text part of binary clipboard to clients (%d bytes)",
(int)strlen(filtered)); (int)strlen(filtered));
//vncSendClipboardData(filtered); vncSendBinaryClipboardData("text/plain", filtered, strlen(filtered));
vncStrFree(filtered); vncStrFree(filtered);
} else { } else {

Loading…
Cancel
Save