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

virtual void setColourMapEntries(int firstColour, int nColours, virtual void setColourMapEntries(int firstColour, int nColours,
rdr::U16* rgbs) = 0; rdr::U16* rgbs) = 0;
virtual void bell() = 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); virtual void setLEDState(unsigned int state);



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

CharArray ca(len); CharArray ca(len);
is->readBytes(ca.buf, len); is->readBytes(ca.buf, len);
CharArray filtered(convertLF(ca.buf, len)); CharArray filtered(convertLF(ca.buf, len));
handler->serverCutText(filtered.buf, strlen(filtered.buf));
handler->serverCutText(filtered.buf);
} }


void CMsgReader::readFence() void CMsgReader::readFence()

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

} }




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"); throw Exception("Invalid carriage return in clipboard data");


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

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



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


protected: protected:
void startMsg(int type); void startMsg(int type);

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

bool __unused_attr down) { } bool __unused_attr down) { }
virtual void pointerEvent(const Point& __unused_attr pos, virtual void pointerEvent(const Point& __unused_attr pos,
int __unused_attr buttonMask) { } 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

CharArray ca(len); CharArray ca(len);
is->readBytes(ca.buf, len); is->readBytes(ca.buf, len);
CharArray filtered(convertLF(ca.buf, len)); CharArray filtered(convertLF(ca.buf, len));
handler->clientCutText(filtered.buf, strlen(filtered.buf));
handler->clientCutText(filtered.buf);
} }


void SMsgReader::readQEMUMessage() void SMsgReader::readQEMUMessage()

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

endMsg(); 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"); throw Exception("Invalid carriage return in clipboard data");


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

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



// writeBell() and writeServerCutText() do the obvious thing. // writeBell() and writeServerCutText() do the obvious thing.
void writeBell(); 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. // writeFence() sends a new fence request or response to the client.
void writeFence(rdr::U32 flags, unsigned len, const char data[]); void writeFence(rdr::U32 flags, unsigned len, const char data[]);

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

} }
} }


void VNCSConnectionST::serverCutTextOrClose(const char *str, int len)
void VNCSConnectionST::serverCutTextOrClose(const char *str)
{ {
try { try {
if (!accessCheck(AccessCutText)) return; if (!accessCheck(AccessCutText)) return;
if (!rfb::Server::sendCutText) return; if (!rfb::Server::sendCutText) return;
if (state() == RFBSTATE_NORMAL) if (state() == RFBSTATE_NORMAL)
writer()->writeServerCutText(str, len);
writer()->writeServerCutText(str);
} catch(rdr::Exception& e) { } catch(rdr::Exception& e) {
close(e.str()); close(e.str());
} }
server->keyEvent(keysym, keycode, 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 (!accessCheck(AccessCutText)) return;
if (!rfb::Server::acceptCutText) return; if (!rfb::Server::acceptCutText) return;
server->clientCutText(str, len);
server->clientCutText(str);
} }


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

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

void screenLayoutChangeOrClose(rdr::U16 reason); void screenLayoutChangeOrClose(rdr::U16 reason);
void setCursorOrClose(); void setCursorOrClose();
void bellOrClose(); void bellOrClose();
void serverCutTextOrClose(const char *str, int len);
void serverCutTextOrClose(const char *str);
void setDesktopNameOrClose(const char *name); void setDesktopNameOrClose(const char *name);
void setLEDStateOrClose(unsigned int state); void setLEDStateOrClose(unsigned int state);
void approveConnectionOrClose(bool accept, const char* reason); void approveConnectionOrClose(bool accept, const char* reason);
virtual void setPixelFormat(const PixelFormat& pf); virtual void setPixelFormat(const PixelFormat& pf);
virtual void pointerEvent(const Point& pos, int buttonMask); virtual void pointerEvent(const Point& pos, int buttonMask);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); 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 framebufferUpdateRequest(const Rect& r, bool incremental);
virtual void setDesktopSize(int fb_width, int fb_height, virtual void setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout); const ScreenSet& layout);

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



// serverCutText() tells the server that the cut text has changed. This // serverCutText() tells the server that the cut text has changed. This
// will normally be sent to all clients. // 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. // bell() tells the server that it should make all clients make a bell sound.
virtual void bell() = 0; virtual void bell() = 0;

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

} }
} }


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"); throw Exception("Invalid carriage return in clipboard data");
std::list<VNCSConnectionST*>::iterator ci, ci_next; std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) { for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++; ci_next = ci; ci_next++;
(*ci)->serverCutTextOrClose(str, len);
(*ci)->serverCutTextOrClose(str);
} }
} }


desktop->pointerEvent(pos, buttonMask); 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, unsigned int VNCServerST::setDesktopSize(VNCSConnectionST* requester,

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

virtual void setPixelBuffer(PixelBuffer* pb); virtual void setPixelBuffer(PixelBuffer* pb);
virtual void setScreenLayout(const ScreenSet& layout); virtual void setScreenLayout(const ScreenSet& layout);
virtual const PixelBuffer* getPixelBuffer() const { return pb; } 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, virtual void approveConnection(network::Socket* sock, bool accept,
const char* reason); const char* reason);
// Event handlers // Event handlers
void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
void pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask); 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, unsigned int setDesktopSize(VNCSConnectionST* requester,
int fb_width, int fb_height, int fb_width, int fb_height,

+ 2
- 2
tests/decperf.cxx View File

virtual void framebufferUpdateEnd(); virtual void framebufferUpdateEnd();
virtual void setColourMapEntries(int, int, rdr::U16*); virtual void setColourMapEntries(int, int, rdr::U16*);
virtual void bell(); virtual void bell();
virtual void serverCutText(const char*, rdr::U32);
virtual void serverCutText(const char*);


public: public:
double cpuTime; double cpuTime;
{ {
} }


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



+ 2
- 2
tests/encperf.cxx View File

virtual void dataRect(const rfb::Rect&, int); virtual void dataRect(const rfb::Rect&, int);
virtual void setColourMapEntries(int, int, rdr::U16*); virtual void setColourMapEntries(int, int, rdr::U16*);
virtual void bell(); virtual void bell();
virtual void serverCutText(const char*, rdr::U32);
virtual void serverCutText(const char*);


public: public:
double decodeTime; double decodeTime;
{ {
} }


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



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

#endif #endif
} }


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


ScreenSet XDesktop::computeScreenLayout() ScreenSet XDesktop::computeScreenLayout()

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

virtual void pointerEvent(const rfb::Point& pos, int buttonMask); virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym); KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down); 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, virtual unsigned int setScreenLayout(int fb_width, int fb_height,
const rfb::ScreenSet& layout); const rfb::ScreenSet& layout);



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

server->setLEDState(state); server->setLEDState(state);
} }


void XserverDesktop::serverCutText(const char* str, int len)
void XserverDesktop::serverCutText(const char* str)
{ {
try { try {
server->serverCutText(str, len);
server->serverCutText(str);
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vlog.error("XserverDesktop::serverCutText: %s",e.str()); vlog.error("XserverDesktop::serverCutText: %s",e.str());
} }
vncPointerButtonAction(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, unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height,

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

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



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

desktop[scr]->setDesktopName(desktopName); desktop[scr]->setDesktopName(desktopName);
} }


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


int vncConnectClient(const char *addr) int vncConnectClient(const char *addr)

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



void vncUpdateDesktopName(void); void vncUpdateDesktopName(void);


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


int vncConnectClient(const char *addr); int vncConnectClient(const char *addr);



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

static Window wid; static Window wid;


static char* clientCutText; static char* clientCutText;
static int clientCutTextLen;


static int vncCreateSelectionWindow(void); static int vncCreateSelectionWindow(void);
static int vncOwnSelection(Atom selection); static int vncOwnSelection(Atom selection);
FatalError("Add VNC SelectionCallback failed\n"); FatalError("Add VNC SelectionCallback failed\n");
} }


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


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


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


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

if (vncGetSetPrimary()) { if (vncGetSetPrimary()) {
rc = vncOwnSelection(xaPRIMARY); rc = vncOwnSelection(xaPRIMARY);
if (rc != Success) if (rc != Success)
} else if ((target == xaSTRING) || (target == xaTEXT)) { } else if ((target == xaSTRING) || (target == xaTEXT)) {
rc = dixChangeWindowProperty(serverClient, pWin, realProperty, rc = dixChangeWindowProperty(serverClient, pWin, realProperty,
XA_STRING, 8, PropModeReplace, XA_STRING, 8, PropModeReplace,
clientCutTextLen, clientCutText,
strlen(clientCutText), clientCutText,
TRUE); TRUE);
if (rc != Success) if (rc != Success)
return rc; return rc;
const unsigned char* in; const unsigned char* in;
size_t in_len; size_t in_len;


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


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


if (filtered == NULL) if (filtered == NULL)
return; return;


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


vncStrFree(filtered); vncStrFree(filtered);
} else if (target == xaUTF8_STRING) { } else if (target == xaUTF8_STRING) {
if (filtered == NULL) if (filtered == NULL)
return; return;


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


vncStrFree(filtered); vncStrFree(filtered);
} }

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

/* 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 * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by


void vncSelectionInit(void); void vncSelectionInit(void);


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


#ifdef __cplusplus #ifdef __cplusplus
} }

+ 2
- 2
vncviewer/CConn.cxx View File

fl_beep(); 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) void CConn::dataRect(const Rect& r, int encoding)

+ 1
- 1
vncviewer/CConn.h View File



void bell(); void bell();


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


void framebufferUpdateStart(); void framebufferUpdateStart();
void framebufferUpdateEnd(); void framebufferUpdateEnd();

+ 2
- 2
vncviewer/DesktopWindow.cxx View File

} }




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

void resizeFramebuffer(int new_w, int new_h); void resizeFramebuffer(int new_w, int new_h);


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


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

+ 5
- 5
vncviewer/Viewport.cxx View File

damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height()); 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; char *buffer;
int size, ret; int size, ret;
if (!acceptClipboard) if (!acceptClipboard)
return; return;


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




buffer = new char[size]; buffer = new char[size];


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


vlog.debug("Got clipboard data (%d bytes)", (int)strlen(buffer)); vlog.debug("Got clipboard data (%d bytes)", (int)strlen(buffer));
vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(filtered)); vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(filtered));


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

+ 2
- 2
vncviewer/Viewport.h View File

/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. /* 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 * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
void updateWindow(); void updateWindow();


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


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

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

// Notify clients // Notify clients
if (notifier) { if (notifier) {
if (!clipdata) { if (!clipdata) {
notifier->notifyClipboardChanged(0, 0);
notifier->notifyClipboardChanged(0);
} else { } else {
CharArray unix_text(convertLF(clipdata, strlen(clipdata))); CharArray unix_text(convertLF(clipdata, strlen(clipdata)));
removeNonISOLatin1Chars(unix_text.buf); removeNonISOLatin1Chars(unix_text.buf);
notifier->notifyClipboardChanged(unix_text.buf, strlen(unix_text.buf));
notifier->notifyClipboardChanged(unix_text.buf);
} }
} else { } else {
vlog.debug("no clipboard notifier registered"); vlog.debug("no clipboard notifier registered");

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

/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. /* 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 * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
// -=- Abstract base class for callback recipients // -=- Abstract base class for callback recipients
class Notifier { class Notifier {
public: public:
virtual void notifyClipboardChanged(const char* text, int len) = 0;
virtual void notifyClipboardChanged(const char* text) = 0;
virtual ~Notifier() {}; virtual ~Notifier() {};
}; };



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

/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. /* 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 * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
return false; 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 void
SDisplay::notifyClipboardChanged(const char* text, int len) {
SDisplay::notifyClipboardChanged(const char* text) {
vlog.debug("clipboard text changed"); vlog.debug("clipboard text changed");
if (server) if (server)
server->serverCutText(text, len);
server->serverCutText(text);
} }





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

/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. /* 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 * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
const char* userName); const char* userName);
virtual void pointerEvent(const Point& pos, int buttonmask); virtual void pointerEvent(const Point& pos, int buttonmask);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); 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 // -=- Clipboard
virtual void notifyClipboardChanged(const char* text, int len);
virtual void notifyClipboardChanged(const char* text);


// -=- Display events // -=- Display events

Loading…
Cancel
Save