Add parameter to make client attempt to resize server desktop on connect.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3712 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/unix/vncviewer/CConn.cxx b/unix/vncviewer/CConn.cxx
index 47ccbb2..135794a 100644
--- a/unix/vncviewer/CConn.cxx
+++ b/unix/vncviewer/CConn.cxx
@@ -62,7 +62,7 @@
     encodingChange(false), sameMachine(false), fullScreen(::fullScreen),
     ctrlDown(false), altDown(false),
     menuKeysym(0), menu(dpy, this), options(dpy, this), about(dpy), info(dpy),
-    reverseConnection(reverse)
+    reverseConnection(reverse), firstUpdate(true)
 {
   CharArray menuKeyStr(menuKey.getData());
   menuKeysym = XStringToKeysym(menuKeyStr.buf);
@@ -277,8 +277,10 @@
                                    const rfb::ScreenSet& layout) {
   CConnection::setExtendedDesktopSize(reason, result, w, h, layout);
 
-  if ((reason == reasonClient) && (result != resultSuccess))
+  if ((reason == reasonClient) && (result != resultSuccess)) {
+    vlog.error("SetDesktopSize failed: %d", result);
     return;
+  }
 
   resizeFramebuffer();
 }
@@ -316,6 +318,43 @@
     debugRects.clear();
   }
   desktop->framebufferUpdateEnd();
+
+  if (firstUpdate) {
+    int width, height;
+
+    if (cp.supportsSetDesktopSize &&
+        sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) == 2) {
+      ScreenSet layout;
+
+      layout = cp.screenLayout;
+
+      if (layout.num_screens() == 0)
+        layout.add_screen(rfb::Screen());
+      else if (layout.num_screens() != 1) {
+        ScreenSet::iterator iter;
+
+        while (true) {
+          iter = layout.begin();
+          ++iter;
+
+          if (iter == layout.end())
+            break;
+
+          layout.remove_screen(iter->id);
+        }
+      }
+
+      layout.begin()->dimensions.tl.x = 0;
+      layout.begin()->dimensions.tl.y = 0;
+      layout.begin()->dimensions.br.x = width;
+      layout.begin()->dimensions.br.y = height;
+
+      writer()->writeSetDesktopSize(width, height, layout);
+    }
+
+    firstUpdate = false;
+  }
+
   if (autoSelect)
     autoSelectFormatAndEncoding();
   requestNewUpdate();
diff --git a/unix/vncviewer/CConn.h b/unix/vncviewer/CConn.h
index 10a12e4..96a76fe 100644
--- a/unix/vncviewer/CConn.h
+++ b/unix/vncviewer/CConn.h
@@ -130,6 +130,7 @@
   AboutDialog about;
   InfoDialog info;
   bool reverseConnection;
+  bool firstUpdate;
 };
 
 #endif
diff --git a/unix/vncviewer/parameters.h b/unix/vncviewer/parameters.h
index 6505aa8..7e4960a 100644
--- a/unix/vncviewer/parameters.h
+++ b/unix/vncviewer/parameters.h
@@ -35,6 +35,7 @@
 extern rfb::BoolParameter acceptClipboard;
 extern rfb::BoolParameter sendClipboard;
 extern rfb::BoolParameter sendPrimary;
+extern rfb::StringParameter desktopSize;
 extern rfb::BoolParameter fullScreen;
 extern rfb::StringParameter geometry;
 extern rfb::BoolParameter customCompressLevel;
diff --git a/unix/vncviewer/vncviewer.cxx b/unix/vncviewer/vncviewer.cxx
index dc49430..4a47788 100644
--- a/unix/vncviewer/vncviewer.cxx
+++ b/unix/vncviewer/vncviewer.cxx
@@ -98,6 +98,10 @@
                           "server as well as the clipboard selection",
                           true);
 
+StringParameter desktopSize("DesktopSize",
+                            "Reconfigure desktop size on the server on "
+                            "connect (if possible)", "");
+
 BoolParameter listenMode("listen", "Listen for connections from VNC servers",
                          false);
 StringParameter geometry("geometry", "X geometry specification", "");