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 {
if (!(accessRights & AccessCutText)) 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) {
vlog.info("DLP: client %s: refused to send binary clipboard, too large",
sock->getPeerAddress());
@ -454,8 +449,6 @@ void VNCSConnectionST::sendBinaryClipboardDataOrClose(const char* mime,
addBinaryClipboard(mime, data, len);
binclipTimer.start(100);
gettimeofday(&lastClipboardOp, NULL);
} catch(rdr::Exception& e) {
close(e.str());
}
@ -1450,7 +1443,15 @@ void VNCSConnectionST::writeDataUpdate()
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);
gettimeofday(&lastClipboardOp, NULL);
}
void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)

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

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

Loading…
Cancel
Save