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
diff --git a/unix/tx/TXWindow.cxx b/unix/tx/TXWindow.cxx
index 6d211be..4bab2d9 100644
--- a/unix/tx/TXWindow.cxx
+++ b/unix/tx/TXWindow.cxx
@@ -286,6 +286,11 @@
   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 5ada181..45ee28f 100644
--- a/unix/tx/TXWindow.h
+++ b/unix/tx/TXWindow.h
@@ -82,6 +82,8 @@
 
   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 cb33066..711bd52 100644
--- a/unix/vncviewer/CConn.cxx
+++ b/unix/vncviewer/CConn.cxx
@@ -74,6 +74,7 @@
     currentEncoding = encNum;
   }
   cp.supportsDesktopResize = true;
+  cp.supportsDesktopRename = true;
   cp.supportsLocalCursor = useLocalCursor;
   cp.customCompressLevel = customCompressLevel;
   cp.compressLevel = compressLevel;
@@ -271,6 +272,14 @@
   }
 }
 
+// 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 a81af48..d969a68 100644
--- a/unix/vncviewer/CConn.h
+++ b/unix/vncviewer/CConn.h
@@ -74,6 +74,7 @@
   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 9194140..203ad5a 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -390,6 +390,15 @@
   }
 }
 
+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 5137249..fb75847 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.h
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
@@ -71,6 +71,7 @@
   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 97df658..9707d5d 100644
--- a/unix/xserver/hw/vnc/vncExtInit.cc
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
@@ -410,7 +410,32 @@
   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);