diff options
-rw-r--r-- | common/rfb/CMsgReader.cxx | 13 | ||||
-rw-r--r-- | common/rfb/CMsgReader.h | 1 | ||||
-rw-r--r-- | common/rfb/CMsgReaderV3.cxx | 3 | ||||
-rw-r--r-- | common/rfb/CMsgWriter.cxx | 2 | ||||
-rw-r--r-- | common/rfb/ConnParams.cxx | 4 | ||||
-rw-r--r-- | common/rfb/ConnParams.h | 1 | ||||
-rw-r--r-- | common/rfb/SMsgWriter.h | 2 | ||||
-rw-r--r-- | common/rfb/SMsgWriterV3.cxx | 23 | ||||
-rw-r--r-- | common/rfb/SMsgWriterV3.h | 2 | ||||
-rw-r--r-- | common/rfb/VNCSConnectionST.cxx | 16 | ||||
-rw-r--r-- | common/rfb/VNCSConnectionST.h | 1 | ||||
-rw-r--r-- | common/rfb/VNCServerST.cxx | 10 | ||||
-rw-r--r-- | common/rfb/VNCServerST.h | 2 | ||||
-rw-r--r-- | common/rfb/encodings.h | 1 | ||||
-rw-r--r-- | unix/tx/TXWindow.cxx | 5 | ||||
-rw-r--r-- | unix/tx/TXWindow.h | 2 | ||||
-rw-r--r-- | unix/vncviewer/CConn.cxx | 9 | ||||
-rw-r--r-- | unix/vncviewer/CConn.h | 1 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.cc | 9 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.h | 1 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncExtInit.cc | 25 | ||||
-rw-r--r-- | win/vncviewer/CConn.cxx | 1 |
22 files changed, 130 insertions, 4 deletions
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx index cc288462..0e3d9679 100644 --- a/common/rfb/CMsgReader.cxx +++ b/common/rfb/CMsgReader.cxx @@ -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); diff --git a/common/rfb/CMsgReader.h b/common/rfb/CMsgReader.h index 7a611fc8..ebf69da1 100644 --- a/common/rfb/CMsgReader.h +++ b/common/rfb/CMsgReader.h @@ -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); diff --git a/common/rfb/CMsgReaderV3.cxx b/common/rfb/CMsgReaderV3.cxx index ae5f4557..b2ba1137 100644 --- a/common/rfb/CMsgReaderV3.cxx +++ b/common/rfb/CMsgReaderV3.cxx @@ -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; diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx index cdfb4e5f..26e0d50c 100644 --- a/common/rfb/CMsgWriter.cxx +++ b/common/rfb/CMsgWriter.cxx @@ -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; } diff --git a/common/rfb/ConnParams.cxx b/common/rfb/ConnParams.cxx index 446c3ad5..b328a1f8 100644 --- a/common/rfb/ConnParams.cxx +++ b/common/rfb/ConnParams.cxx @@ -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 && diff --git a/common/rfb/ConnParams.h b/common/rfb/ConnParams.h index e29adf87..f00b1d6e 100644 --- a/common/rfb/ConnParams.h +++ b/common/rfb/ConnParams.h @@ -73,6 +73,7 @@ namespace rfb { bool supportsLocalCursor; bool supportsLocalXCursor; bool supportsDesktopResize; + bool supportsDesktopRename; bool supportsLastRect; bool customCompressLevel; diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index 6f7feeb5..959f865d 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -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() diff --git a/common/rfb/SMsgWriterV3.cxx b/common/rfb/SMsgWriterV3.cxx index a85f85ea..12716195 100644 --- a/common/rfb/SMsgWriterV3.cxx +++ b/common/rfb/SMsgWriterV3.cxx @@ -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) diff --git a/common/rfb/SMsgWriterV3.h b/common/rfb/SMsgWriterV3.h index 501fa489..d2c13df9 100644 --- a/common/rfb/SMsgWriterV3.h +++ b/common/rfb/SMsgWriterV3.h @@ -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; }; } diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index 7153dd4e..9fe644cc 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -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 { diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index d48c8c73..d1c08573 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -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 diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index fc2e931b..d36354c8 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -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) { diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 90bbeb5c..0b8a2e67 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -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. diff --git a/common/rfb/encodings.h b/common/rfb/encodings.h index 51f6f1ec..1021be96 100644 --- a/common/rfb/encodings.h +++ b/common/rfb/encodings.h @@ -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; diff --git a/unix/tx/TXWindow.cxx b/unix/tx/TXWindow.cxx index 6d211beb..4bab2d9b 100644 --- a/unix/tx/TXWindow.cxx +++ b/unix/tx/TXWindow.cxx @@ -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; diff --git a/unix/tx/TXWindow.h b/unix/tx/TXWindow.h index 5ada181b..45ee28fb 100644 --- a/unix/tx/TXWindow.h +++ b/unix/tx/TXWindow.h @@ -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. diff --git a/unix/vncviewer/CConn.cxx b/unix/vncviewer/CConn.cxx index cb330661..711bd521 100644 --- a/unix/vncviewer/CConn.cxx +++ b/unix/vncviewer/CConn.cxx @@ -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 diff --git a/unix/vncviewer/CConn.h b/unix/vncviewer/CConn.h index a81af48c..d969a68c 100644 --- a/unix/vncviewer/CConn.h +++ b/unix/vncviewer/CConn.h @@ -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); diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 91941406..203ad5ad 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -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 { diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 5137249e..fb758470 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -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); diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc index 97df6585..9707d5de 100644 --- a/unix/xserver/hw/vnc/vncExtInit.cc +++ b/unix/xserver/hw/vnc/vncExtInit.cc @@ -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); diff --git a/win/vncviewer/CConn.cxx b/win/vncviewer/CConn.cxx index 1f4bbc2b..d2697488 100644 --- a/win/vncviewer/CConn.cxx +++ b/win/vncviewer/CConn.cxx @@ -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; |