Browse Source

Clean up internal clipboard handling

We now filter incoming data, which means we can start assuming the
clipboard data is always null terminated. This allows us to clean
up a lot of the internal handling.
tags/v1.9.90
Pierre Ossman 5 years ago
parent
commit
66f1db543b

+ 1
- 1
common/rfb/CMsgHandler.h View File

@@ -70,7 +70,7 @@ namespace rfb {
virtual void setColourMapEntries(int firstColour, int nColours,
rdr::U16* rgbs) = 0;
virtual void bell() = 0;
virtual void serverCutText(const char* str, rdr::U32 len) = 0;
virtual void serverCutText(const char* str) = 0;

virtual void setLEDState(unsigned int state);


+ 1
- 1
common/rfb/CMsgReader.cxx View File

@@ -160,7 +160,7 @@ void CMsgReader::readServerCutText()
CharArray ca(len);
is->readBytes(ca.buf, len);
CharArray filtered(convertLF(ca.buf, len));
handler->serverCutText(filtered.buf, strlen(filtered.buf));
handler->serverCutText(filtered.buf);
}

void CMsgReader::readFence()

+ 5
- 2
common/rfb/CMsgWriter.cxx View File

@@ -179,11 +179,14 @@ void CMsgWriter::writePointerEvent(const Point& pos, int buttonMask)
}


void CMsgWriter::writeClientCutText(const char* str, rdr::U32 len)
void CMsgWriter::writeClientCutText(const char* str)
{
if (memchr(str, '\r', len) != NULL)
size_t len;

if (strchr(str, '\r') != NULL)
throw Exception("Invalid carriage return in clipboard data");

len = strlen(str);
startMsg(msgTypeClientCutText);
os->pad(3);
os->writeU32(len);

+ 1
- 1
common/rfb/CMsgWriter.h View File

@@ -55,7 +55,7 @@ namespace rfb {

void writeKeyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
void writePointerEvent(const Point& pos, int buttonMask);
void writeClientCutText(const char* str, rdr::U32 len);
void writeClientCutText(const char* str);

protected:
void startMsg(int type);

+ 1
- 2
common/rfb/InputHandler.h View File

@@ -37,8 +37,7 @@ namespace rfb {
bool __unused_attr down) { }
virtual void pointerEvent(const Point& __unused_attr pos,
int __unused_attr buttonMask) { }
virtual void clientCutText(const char* __unused_attr str,
int __unused_attr len) { }
virtual void clientCutText(const char* __unused_attr str) { }
};

}

+ 1
- 1
common/rfb/SMsgReader.cxx View File

@@ -215,7 +215,7 @@ void SMsgReader::readClientCutText()
CharArray ca(len);
is->readBytes(ca.buf, len);
CharArray filtered(convertLF(ca.buf, len));
handler->clientCutText(filtered.buf, strlen(filtered.buf));
handler->clientCutText(filtered.buf);
}

void SMsgReader::readQEMUMessage()

+ 5
- 2
common/rfb/SMsgWriter.cxx View File

@@ -78,11 +78,14 @@ void SMsgWriter::writeBell()
endMsg();
}

void SMsgWriter::writeServerCutText(const char* str, int len)
void SMsgWriter::writeServerCutText(const char* str)
{
if (memchr(str, '\r', len) != NULL)
size_t len;

if (strchr(str, '\r') != NULL)
throw Exception("Invalid carriage return in clipboard data");

len = strlen(str);
startMsg(msgTypeServerCutText);
os->pad(3);
os->writeU32(len);

+ 1
- 1
common/rfb/SMsgWriter.h View File

@@ -56,7 +56,7 @@ namespace rfb {

// writeBell() and writeServerCutText() do the obvious thing.
void writeBell();
void writeServerCutText(const char* str, int len);
void writeServerCutText(const char* str);

// writeFence() sends a new fence request or response to the client.
void writeFence(rdr::U32 flags, unsigned len, const char data[]);

+ 4
- 4
common/rfb/VNCSConnectionST.cxx View File

@@ -282,13 +282,13 @@ void VNCSConnectionST::bellOrClose()
}
}

void VNCSConnectionST::serverCutTextOrClose(const char *str, int len)
void VNCSConnectionST::serverCutTextOrClose(const char *str)
{
try {
if (!accessCheck(AccessCutText)) return;
if (!rfb::Server::sendCutText) return;
if (state() == RFBSTATE_NORMAL)
writer()->writeServerCutText(str, len);
writer()->writeServerCutText(str);
} catch(rdr::Exception& e) {
close(e.str());
}
@@ -596,11 +596,11 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
server->keyEvent(keysym, keycode, down);
}

void VNCSConnectionST::clientCutText(const char* str, int len)
void VNCSConnectionST::clientCutText(const char* str)
{
if (!accessCheck(AccessCutText)) return;
if (!rfb::Server::acceptCutText) return;
server->clientCutText(str, len);
server->clientCutText(str);
}

void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental)

+ 2
- 2
common/rfb/VNCSConnectionST.h View File

@@ -72,7 +72,7 @@ namespace rfb {
void screenLayoutChangeOrClose(rdr::U16 reason);
void setCursorOrClose();
void bellOrClose();
void serverCutTextOrClose(const char *str, int len);
void serverCutTextOrClose(const char *str);
void setDesktopNameOrClose(const char *name);
void setLEDStateOrClose(unsigned int state);
void approveConnectionOrClose(bool accept, const char* reason);
@@ -115,7 +115,7 @@ namespace rfb {
virtual void setPixelFormat(const PixelFormat& pf);
virtual void pointerEvent(const Point& pos, int buttonMask);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
virtual void clientCutText(const char* str);
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
virtual void setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout);

+ 1
- 1
common/rfb/VNCServer.h View File

@@ -57,7 +57,7 @@ namespace rfb {

// serverCutText() tells the server that the cut text has changed. This
// will normally be sent to all clients.
virtual void serverCutText(const char* str, int len) = 0;
virtual void serverCutText(const char* str) = 0;

// bell() tells the server that it should make all clients make a bell sound.
virtual void bell() = 0;

+ 5
- 5
common/rfb/VNCServerST.cxx View File

@@ -340,14 +340,14 @@ void VNCServerST::bell()
}
}

void VNCServerST::serverCutText(const char* str, int len)
void VNCServerST::serverCutText(const char* str)
{
if (memchr(str, '\r', len) != NULL)
if (strchr(str, '\r') != NULL)
throw Exception("Invalid carriage return in clipboard data");
std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
(*ci)->serverCutTextOrClose(str, len);
(*ci)->serverCutTextOrClose(str);
}
}

@@ -461,9 +461,9 @@ void VNCServerST::pointerEvent(VNCSConnectionST* client,
desktop->pointerEvent(pos, buttonMask);
}

void VNCServerST::clientCutText(const char* str, int len)
void VNCServerST::clientCutText(const char* str)
{
desktop->clientCutText(str, len);
desktop->clientCutText(str);
}

unsigned int VNCServerST::setDesktopSize(VNCSConnectionST* requester,

+ 2
- 2
common/rfb/VNCServerST.h View File

@@ -85,7 +85,7 @@ namespace rfb {
virtual void setPixelBuffer(PixelBuffer* pb);
virtual void setScreenLayout(const ScreenSet& layout);
virtual const PixelBuffer* getPixelBuffer() const { return pb; }
virtual void serverCutText(const char* str, int len);
virtual void serverCutText(const char* str);

virtual void approveConnection(network::Socket* sock, bool accept,
const char* reason);
@@ -115,7 +115,7 @@ namespace rfb {
// Event handlers
void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
void pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask);
void clientCutText(const char* str, int len);
void clientCutText(const char* str);

unsigned int setDesktopSize(VNCSConnectionST* requester,
int fb_width, int fb_height,

+ 2
- 2
tests/decperf.cxx View File

@@ -54,7 +54,7 @@ public:
virtual void framebufferUpdateEnd();
virtual void setColourMapEntries(int, int, rdr::U16*);
virtual void bell();
virtual void serverCutText(const char*, rdr::U32);
virtual void serverCutText(const char*);

public:
double cpuTime;
@@ -122,7 +122,7 @@ void CConn::bell()
{
}

void CConn::serverCutText(const char*, rdr::U32)
void CConn::serverCutText(const char*)
{
}


+ 2
- 2
tests/encperf.cxx View File

@@ -96,7 +96,7 @@ public:
virtual void dataRect(const rfb::Rect&, int);
virtual void setColourMapEntries(int, int, rdr::U16*);
virtual void bell();
virtual void serverCutText(const char*, rdr::U32);
virtual void serverCutText(const char*);

public:
double decodeTime;
@@ -254,7 +254,7 @@ void CConn::bell()
{
}

void CConn::serverCutText(const char*, rdr::U32)
void CConn::serverCutText(const char*)
{
}


+ 1
- 1
unix/x0vncserver/XDesktop.cxx View File

@@ -406,7 +406,7 @@ void XDesktop::keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down) {
#endif
}

void XDesktop::clientCutText(const char* str, int len) {
void XDesktop::clientCutText(const char* str) {
}

ScreenSet XDesktop::computeScreenLayout()

+ 1
- 1
unix/x0vncserver/XDesktop.h View File

@@ -56,7 +56,7 @@ public:
virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down);
virtual void clientCutText(const char* str, int len);
virtual void clientCutText(const char* str);
virtual unsigned int setScreenLayout(int fb_width, int fb_height,
const rfb::ScreenSet& layout);


+ 4
- 4
unix/xserver/hw/vnc/XserverDesktop.cc View File

@@ -192,10 +192,10 @@ void XserverDesktop::setLEDState(unsigned int state)
server->setLEDState(state);
}

void XserverDesktop::serverCutText(const char* str, int len)
void XserverDesktop::serverCutText(const char* str)
{
try {
server->serverCutText(str, len);
server->serverCutText(str);
} catch (rdr::Exception& e) {
vlog.error("XserverDesktop::serverCutText: %s",e.str());
}
@@ -436,9 +436,9 @@ void XserverDesktop::pointerEvent(const Point& pos, int buttonMask)
vncPointerButtonAction(buttonMask);
}

void XserverDesktop::clientCutText(const char* str, int len)
void XserverDesktop::clientCutText(const char* str)
{
vncClientCutText(str, len);
vncClientCutText(str);
}

unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height,

+ 2
- 2
unix/xserver/hw/vnc/XserverDesktop.h View File

@@ -61,7 +61,7 @@ public:
void refreshScreenLayout();
void bell();
void setLEDState(unsigned int state);
void serverCutText(const char* str, int len);
void serverCutText(const char* str);
void setDesktopName(const char* name);
void setCursor(int width, int height, int hotX, int hotY,
const unsigned char *rgbaData);
@@ -92,7 +92,7 @@ public:
const char* userName);
virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
virtual void clientCutText(const char* str);
virtual unsigned int setScreenLayout(int fb_width, int fb_height,
const rfb::ScreenSet& layout);


+ 2
- 2
unix/xserver/hw/vnc/vncExtInit.cc View File

@@ -285,10 +285,10 @@ void vncUpdateDesktopName(void)
desktop[scr]->setDesktopName(desktopName);
}

void vncServerCutText(const char *text, size_t len)
void vncServerCutText(const char *text)
{
for (int scr = 0; scr < vncGetScreenCount(); scr++)
desktop[scr]->serverCutText(text, len);
desktop[scr]->serverCutText(text);
}

int vncConnectClient(const char *addr)

+ 1
- 1
unix/xserver/hw/vnc/vncExtInit.h View File

@@ -53,7 +53,7 @@ int vncGetSendPrimary(void);

void vncUpdateDesktopName(void);

void vncServerCutText(const char *text, size_t len);
void vncServerCutText(const char *text);

int vncConnectClient(const char *addr);


+ 7
- 14
unix/xserver/hw/vnc/vncSelection.c View File

@@ -48,7 +48,6 @@ static WindowPtr pWindow;
static Window wid;

static char* clientCutText;
static int clientCutTextLen;

static int vncCreateSelectionWindow(void);
static int vncOwnSelection(Atom selection);
@@ -82,23 +81,20 @@ void vncSelectionInit(void)
FatalError("Add VNC SelectionCallback failed\n");
}

void vncClientCutText(const char* str, int len)
void vncClientCutText(const char* str)
{
int rc;

if (clientCutText != NULL)
free(clientCutText);

clientCutText = malloc(len);
clientCutText = strdup(str);
if (clientCutText == NULL) {
LOG_ERROR("Could not allocate clipboard buffer");
DeleteWindowFromAnySelections(pWindow);
return;
}

memcpy(clientCutText, str, len);
clientCutTextLen = len;

if (vncGetSetPrimary()) {
rc = vncOwnSelection(xaPRIMARY);
if (rc != Success)
@@ -246,7 +242,7 @@ static int vncConvertSelection(ClientPtr client, Atom selection,
} else if ((target == xaSTRING) || (target == xaTEXT)) {
rc = dixChangeWindowProperty(serverClient, pWin, realProperty,
XA_STRING, 8, PropModeReplace,
clientCutTextLen, clientCutText,
strlen(clientCutText), clientCutText,
TRUE);
if (rc != Success)
return rc;
@@ -258,25 +254,22 @@ static int vncConvertSelection(ClientPtr client, Atom selection,
const unsigned char* in;
size_t in_len;

buffer = malloc(clientCutTextLen*2);
buffer = malloc(strlen(clientCutText)*2);
if (buffer == NULL)
return BadAlloc;

out = buffer;
len = 0;
in = clientCutText;
in_len = clientCutTextLen;
while (in_len > 0) {
while (*in != '\0') {
if (*in & 0x80) {
*out++ = 0xc0 | (*in >> 6);
*out++ = 0x80 | (*in & 0x3f);
len += 2;
in++;
in_len--;
} else {
*out++ = *in++;
len++;
in_len--;
}
}

@@ -426,7 +419,7 @@ static void vncHandleSelection(Atom selection, Atom target,
if (filtered == NULL)
return;

vncServerCutText(filtered, strlen(filtered));
vncServerCutText(filtered);

vncStrFree(filtered);
} else if (target == xaUTF8_STRING) {
@@ -484,7 +477,7 @@ static void vncHandleSelection(Atom selection, Atom target,
if (filtered == NULL)
return;

vncServerCutText(filtered, strlen(filtered));
vncServerCutText(filtered);

vncStrFree(filtered);
}

+ 2
- 2
unix/xserver/hw/vnc/vncSelection.h View File

@@ -1,4 +1,4 @@
/* Copyright 2016 Pierre Ossman for Cendio AB
/* Copyright 2016-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ extern "C" {

void vncSelectionInit(void);

void vncClientCutText(const char* str, int len);
void vncClientCutText(const char* str);

#ifdef __cplusplus
}

+ 2
- 2
vncviewer/CConn.cxx View File

@@ -377,9 +377,9 @@ void CConn::bell()
fl_beep();
}

void CConn::serverCutText(const char* str, rdr::U32 len)
void CConn::serverCutText(const char* str)
{
desktop->serverCutText(str, len);
desktop->serverCutText(str);
}

void CConn::dataRect(const Rect& r, int encoding)

+ 1
- 1
vncviewer/CConn.h View File

@@ -61,7 +61,7 @@ public:

void bell();

void serverCutText(const char* str, rdr::U32 len);
void serverCutText(const char* str);

void framebufferUpdateStart();
void framebufferUpdateEnd();

+ 2
- 2
vncviewer/DesktopWindow.cxx View File

@@ -276,9 +276,9 @@ void DesktopWindow::resizeFramebuffer(int new_w, int new_h)
}


void DesktopWindow::serverCutText(const char* str, rdr::U32 len)
void DesktopWindow::serverCutText(const char* str)
{
viewport->serverCutText(str, len);
viewport->serverCutText(str);
}



+ 1
- 1
vncviewer/DesktopWindow.h View File

@@ -63,7 +63,7 @@ public:
void resizeFramebuffer(int new_w, int new_h);

// Incoming clipboard from server
void serverCutText(const char* str, rdr::U32 len);
void serverCutText(const char* str);

// New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,

+ 5
- 5
vncviewer/Viewport.cxx View File

@@ -232,7 +232,7 @@ void Viewport::updateWindow()
damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
}

void Viewport::serverCutText(const char* str, rdr::U32 len)
void Viewport::serverCutText(const char* str)
{
char *buffer;
int size, ret;
@@ -242,7 +242,7 @@ void Viewport::serverCutText(const char* str, rdr::U32 len)
if (!acceptClipboard)
return;

size = fl_utf8froma(NULL, 0, str, len);
size = fl_utf8froma(NULL, 0, str, strlen(str));
if (size <= 0)
return;

@@ -250,7 +250,7 @@ void Viewport::serverCutText(const char* str, rdr::U32 len)

buffer = new char[size];

ret = fl_utf8froma(buffer, size, str, len);
ret = fl_utf8froma(buffer, size, str, strlen(str));
assert(ret < size);

vlog.debug("Got clipboard data (%d bytes)", (int)strlen(buffer));
@@ -577,7 +577,7 @@ int Viewport::handle(int event)
vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(filtered));

try {
cc->writer()->writeClientCutText(filtered, strlen(filtered));
cc->writer()->writeClientCutText(filtered);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());
@@ -768,7 +768,7 @@ void Viewport::flushPendingClipboard()
size_t len = strlen(pendingClientCutText);
vlog.debug("Sending pending clipboard data (%d bytes)", (int)len);
try {
cc->writer()->writeClientCutText(pendingClientCutText, len);
cc->writer()->writeClientCutText(pendingClientCutText);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());

+ 2
- 2
vncviewer/Viewport.h View File

@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright 2011-2019 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ public:
void updateWindow();

// Incoming clipboard from server
void serverCutText(const char* str, rdr::U32 len);
void serverCutText(const char* str);

// New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,

+ 2
- 2
win/rfb_win32/Clipboard.cxx View File

@@ -113,11 +113,11 @@ Clipboard::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
// Notify clients
if (notifier) {
if (!clipdata) {
notifier->notifyClipboardChanged(0, 0);
notifier->notifyClipboardChanged(0);
} else {
CharArray unix_text(convertLF(clipdata, strlen(clipdata)));
removeNonISOLatin1Chars(unix_text.buf);
notifier->notifyClipboardChanged(unix_text.buf, strlen(unix_text.buf));
notifier->notifyClipboardChanged(unix_text.buf);
}
} else {
vlog.debug("no clipboard notifier registered");

+ 2
- 1
win/rfb_win32/Clipboard.h View File

@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2016-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,7 +39,7 @@ namespace rfb {
// -=- Abstract base class for callback recipients
class Notifier {
public:
virtual void notifyClipboardChanged(const char* text, int len) = 0;
virtual void notifyClipboardChanged(const char* text) = 0;
virtual ~Notifier() {};
};


+ 5
- 7
win/rfb_win32/SDisplay.cxx View File

@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -328,19 +329,16 @@ bool SDisplay::checkLedState() {
return false;
}

void SDisplay::clientCutText(const char* text, int len) {
CharArray clip_sz(len+1);
memcpy(clip_sz.buf, text, len);
clip_sz.buf[len] = 0;
clipboard->setClipText(clip_sz.buf);
void SDisplay::clientCutText(const char* text) {
clipboard->setClipText(text);
}


void
SDisplay::notifyClipboardChanged(const char* text, int len) {
SDisplay::notifyClipboardChanged(const char* text) {
vlog.debug("clipboard text changed");
if (server)
server->serverCutText(text, len);
server->serverCutText(text);
}



+ 3
- 2
win/rfb_win32/SDisplay.h View File

@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -77,11 +78,11 @@ namespace rfb {
const char* userName);
virtual void pointerEvent(const Point& pos, int buttonmask);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
virtual void clientCutText(const char* str);

// -=- Clipboard
virtual void notifyClipboardChanged(const char* text, int len);
virtual void notifyClipboardChanged(const char* text);

// -=- Display events

Loading…
Cancel
Save