Browse Source

Implemented support for DesktopName pseudo encoding, which allows

updating the desktop name on the fly.

Tested in ThinLinc since 2008-01-07. 



git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3549 3789f03b-4d11-0410-bbf8-ca57d06f2519
tags/v0.0.90
Peter Åstrand 15 years ago
parent
commit
c39e078968

+ 13
- 0
common/rfb/CMsgReader.cxx View File

@@ -138,6 +138,19 @@ void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
handler->setCursor(width, height, hotspot, data.buf, mask.buf);
}

void CMsgReader::readSetDesktopName(int x, int y, int w, int h)
{
char* name = is->readString();

if (x || y || w || h) {
fprintf(stderr, "Ignoring DesktopName rect with non-zero position/size\n");
} else {
handler->setName(name);
}

delete [] name;
}

rdr::U8* CMsgReader::getImageBuf(int required, int requested, int* nPixels)
{
int requiredBytes = required * (handler->cp.pf().bpp / 8);

+ 1
- 0
common/rfb/CMsgReader.h View File

@@ -60,6 +60,7 @@ namespace rfb {
virtual void readCopyRect(const Rect& r);

virtual void readSetCursor(int width, int height, const Point& hotspot);
virtual void readSetDesktopName(int x, int y, int w, int h);

CMsgReader(CMsgHandler* handler, rdr::InStream* is);


+ 3
- 0
common/rfb/CMsgReaderV3.cxx View File

@@ -84,6 +84,9 @@ void CMsgReaderV3::readMsg()
case pseudoEncodingDesktopSize:
handler->setDesktopSize(w, h);
break;
case pseudoEncodingDesktopName:
readSetDesktopName(x, y, w, h);
break;
case pseudoEncodingCursor:
readSetCursor(w, h, Point(x,y));
break;

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

@@ -64,6 +64,8 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
encodings[nEncodings++] = pseudoEncodingCursor;
if (cp->supportsDesktopResize)
encodings[nEncodings++] = pseudoEncodingDesktopSize;
if (cp->supportsDesktopRename)
encodings[nEncodings++] = pseudoEncodingDesktopName;
if (Decoder::supported(preferredEncoding)) {
encodings[nEncodings++] = preferredEncoding;
}

+ 3
- 1
common/rfb/ConnParams.cxx View File

@@ -29,7 +29,7 @@ using namespace rfb;
ConnParams::ConnParams()
: majorVersion(0), minorVersion(0), tightExtensionsEnabled(false),
width(0), height(0), useCopyRect(false),
supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(true),
supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(true), supportsDesktopRename(false),
supportsLastRect(false), customCompressLevel(false), compressLevel(6),
noJpeg(false), qualityLevel(-1),
name_(0), nEncodings_(0), encodings_(0),
@@ -111,6 +111,8 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings)
supportsLocalXCursor = true;
else if (encodings[i] == pseudoEncodingDesktopSize)
supportsDesktopResize = true;
else if (encodings[i] == pseudoEncodingDesktopName)
supportsDesktopRename = true;
else if (encodings[i] == pseudoEncodingLastRect)
supportsLastRect = true;
else if (encodings[i] >= pseudoEncodingCompressLevel0 &&

+ 1
- 0
common/rfb/ConnParams.h View File

@@ -73,6 +73,7 @@ namespace rfb {
bool supportsLocalCursor;
bool supportsLocalXCursor;
bool supportsDesktopResize;
bool supportsDesktopRename;
bool supportsLastRect;

bool customCompressLevel;

+ 2
- 0
common/rfb/SMsgWriter.h View File

@@ -76,6 +76,8 @@ namespace rfb {
// but will write the relevant pseudo-rectangle as part of the next update.
virtual bool writeSetDesktopSize()=0;

virtual bool writeSetDesktopName()=0;

// Like setDesktopSize, we can't just write out a setCursor message
// immediately on a V3 writer. Instead of calling writeSetCursor()
// directly, you must call cursorChange(), and then invoke writeSetCursor()

+ 21
- 2
common/rfb/SMsgWriterV3.cxx View File

@@ -27,7 +27,7 @@ using namespace rfb;
SMsgWriterV3::SMsgWriterV3(ConnParams* cp, rdr::OutStream* os)
: SMsgWriter(cp, os), updateOS(0), realOS(os), nRectsInUpdate(0),
nRectsInHeader(0), wsccb(0),
needSetDesktopSize(false)
needSetDesktopSize(false), needSetDesktopName(false)
{
}

@@ -64,6 +64,12 @@ bool SMsgWriterV3::writeSetDesktopSize() {
return true;
}

bool SMsgWriterV3::writeSetDesktopName() {
if (!cp->supportsDesktopRename) return false;
needSetDesktopName = true;
return true;
}

void SMsgWriterV3::cursorChange(WriteSetCursorCallback* cb)
{
wsccb = cb;
@@ -118,6 +124,7 @@ void SMsgWriterV3::writeFramebufferUpdateStart(int nRects)
os->pad(1);
if (wsccb) nRects++;
if (needSetDesktopSize) nRects++;
if (needSetDesktopName) nRects++;
os->writeU16(nRects);
nRectsInUpdate = 0;
nRectsInHeader = nRects;
@@ -150,6 +157,18 @@ void SMsgWriterV3::writeFramebufferUpdateEnd()
needSetDesktopSize = false;
}

if (needSetDesktopName) {
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
throw Exception("SMsgWriterV3 setDesktopName: nRects out of sync");
os->writeS16(0);
os->writeS16(0);
os->writeU16(0);
os->writeU16(0);
os->writeU32(pseudoEncodingDesktopName);
os->writeString(cp->name());
needSetDesktopName = false;
}

if (nRectsInUpdate != nRectsInHeader && nRectsInHeader)
throw Exception("SMsgWriterV3::writeFramebufferUpdateEnd: "
"nRects out of sync");
@@ -168,7 +187,7 @@ void SMsgWriterV3::writeFramebufferUpdateEnd()

bool SMsgWriterV3::needFakeUpdate()
{
return wsccb || needSetDesktopSize;
return wsccb || needSetDesktopSize || needSetDesktopName;
}

void SMsgWriterV3::startRect(const Rect& r, unsigned int encoding)

+ 2
- 0
common/rfb/SMsgWriterV3.h View File

@@ -32,6 +32,7 @@ namespace rfb {
virtual void startMsg(int type);
virtual void endMsg();
virtual bool writeSetDesktopSize();
virtual bool writeSetDesktopName();
virtual void cursorChange(WriteSetCursorCallback* cb);
virtual void writeSetCursor(int width, int height, const Point& hotspot,
void* data, void* mask);
@@ -51,6 +52,7 @@ namespace rfb {
int nRectsInHeader;
WriteSetCursorCallback* wsccb;
bool needSetDesktopSize;
bool needSetDesktopName;
bool needLastRect;
};
}

+ 16
- 0
common/rfb/VNCSConnectionST.cxx View File

@@ -232,6 +232,22 @@ void VNCSConnectionST::serverCutText(const char *str, int len)
}
}


void VNCSConnectionST::setDesktopName(const char *name)
{
cp.setName(name);
try {
if (state() == RFBSTATE_NORMAL) {
if (!writer()->writeSetDesktopName()) {
fprintf(stderr, "Client does not support desktop rename\n");
}
}
} catch(rdr::Exception& e) {
close(e.str());
}
}


void VNCSConnectionST::setCursorOrClose()
{
try {

+ 1
- 0
common/rfb/VNCSConnectionST.h View File

@@ -66,6 +66,7 @@ namespace rfb {
void setColourMapEntriesOrClose(int firstColour, int nColours);
void bell();
void serverCutText(const char *str, int len);
void setDesktopName(const char *name);
void setCursorOrClose();

// checkIdleTimeout() returns the number of milliseconds left until the

+ 10
- 0
common/rfb/VNCServerST.cxx View File

@@ -302,6 +302,16 @@ void VNCServerST::serverCutText(const char* str, int len)
}
}

void VNCServerST::setName(const char* name_)
{
name.replaceBuf(strDup(name_));
std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
(*ci)->setDesktopName(name_);
}
}

void VNCServerST::add_changed(const Region& region)
{
if (comparer != 0) {

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

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

// setName() specifies the desktop name that the server should provide to
// clients
void setName(const char* name_) {name.replaceBuf(strDup(name_));}
virtual void setName(const char* name_);

// A QueryConnectionHandler, if supplied, is passed details of incoming
// connections to approve, reject, or query the user about.

+ 1
- 0
common/rfb/encodings.h View File

@@ -33,6 +33,7 @@ namespace rfb {
const unsigned int pseudoEncodingXCursor = 0xffffff10;
const unsigned int pseudoEncodingCursor = 0xffffff11;
const unsigned int pseudoEncodingDesktopSize = 0xffffff21;
const unsigned int pseudoEncodingDesktopName = 0xfffffecdl;

// TightVNC-specific
const unsigned int pseudoEncodingLastRect = 0xFFFFFF20;

+ 5
- 0
unix/tx/TXWindow.cxx View File

@@ -286,6 +286,11 @@ void TXWindow::toplevel(const char* name, TXDeleteWindowCallback* dwc_,
addEventMask(StructureNotifyMask);
}

void TXWindow::setName(const char* name)
{
XStoreName(dpy, win(), name);
}

void TXWindow::setMaxSize(int w, int h)
{
sizeHints.flags |= PMaxSize;

+ 2
- 0
unix/tx/TXWindow.h View File

@@ -82,6 +82,8 @@ public:

void setGeometry(const char* geom, int x, int y, int w, int h);

void setName(const char* name);

// setTransientFor() tells the window manager that this window is "owned" by
// the given window. The window manager can use this information as it sees
// fit.

+ 9
- 0
unix/vncviewer/CConn.cxx View File

@@ -74,6 +74,7 @@ CConn::CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_,
currentEncoding = encNum;
}
cp.supportsDesktopResize = true;
cp.supportsDesktopRename = true;
cp.supportsLocalCursor = useLocalCursor;
cp.customCompressLevel = customCompressLevel;
cp.compressLevel = compressLevel;
@@ -271,6 +272,14 @@ void CConn::setDesktopSize(int w, int h) {
}
}

// setName() is called when the desktop name changes
void CConn::setName(const char* name) {
CConnection::setName(name);
if (viewport) {
viewport->setName(name);
}
}

// framebufferUpdateEnd() is called at the end of an update.
// For each rectangle, the FdInStream will have timed the speed
// of the connection, allowing us to select format and encoding

+ 1
- 0
unix/vncviewer/CConn.h View File

@@ -74,6 +74,7 @@ public:
rfb::CSecurity* getCSecurity(int secType);
void serverInit();
void setDesktopSize(int w, int h);
void setName(const char* name);
void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
void bell();
void serverCutText(const char* str, int len);

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

@@ -390,6 +390,15 @@ void XserverDesktop::serverCutText(const char* str, int len)
}
}

void XserverDesktop::setDesktopName(const char* name)
{
try {
server->setName(name);
} catch (rdr::Exception& e) {
vlog.error("XserverDesktop::setDesktopName: %s",e.str());
}
}

void XserverDesktop::setCursor(CursorPtr cursor)
{
try {

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

@@ -71,6 +71,7 @@ public:
void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef);
void bell();
void serverCutText(const char* str, int len);
void setDesktopName(const char* name);
void setCursor(CursorPtr cursor);
void add_changed(RegionPtr reg);
void add_copied(RegionPtr dst, int dx, int dy);

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

@@ -410,7 +410,32 @@ static int ProcVncExtSetParam(ClientPtr client)
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;

// Retrieve desktop name before setting
char* value1 = 0;
rfb::VoidParameter* desktop1 = rfb::Configuration::getParam("desktop");
if (desktop1)
value1 = desktop1->getValueStr();

rep.success = rfb::Configuration::setParam(param.buf);

// Send DesktopName update if desktop name has been changed
char* value2 = 0;
rfb::VoidParameter* desktop2 = rfb::Configuration::getParam("desktop");
if (desktop2)
value2 = desktop2->getValueStr();
if (value1 && value2 && strcmp(value1, value2)) {
for (int scr = 0; scr < screenInfo.numScreens; scr++) {
if (desktop[scr]) {
desktop[scr]->setDesktopName(value2);
}
}
}
if (value1)
delete [] value1;
if (value2)
delete [] value2;

if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);

+ 1
- 0
win/vncviewer/CConn.cxx View File

@@ -137,6 +137,7 @@ CConn::applyOptions(CConnOptions& opt) {
// - Set optional features in ConnParams
cp.supportsLocalCursor = options.useLocalCursor;
cp.supportsDesktopResize = options.useDesktopResize;
cp.supportsDesktopRename = true;
cp.customCompressLevel = options.customCompressLevel;
cp.compressLevel = options.compressLevel;
cp.noJpeg = options.noJpeg;

Loading…
Cancel
Save