Bind text to binary clipboard
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user