[Bugfix] Defer all format changes till requested framebuffer updates are
received. Viewer can crash otherwise. Thanks to Jan Gorig for the patch. 


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4004 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/unix/vncviewer/CConn.cxx b/unix/vncviewer/CConn.cxx
index 76dd4ec..46e8bf8 100644
--- a/unix/vncviewer/CConn.cxx
+++ b/unix/vncviewer/CConn.cxx
@@ -33,6 +33,7 @@
 #include <rfb/Password.h>
 #include <rfb/screenTypes.h>
 #include <network/TcpSocket.h>
+#include <cassert>
 
 #include "TXViewport.h"
 #include "DesktopWindow.h"
@@ -62,7 +63,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), firstUpdate(true)
+    reverseConnection(reverse), firstUpdate(true), pendingUpdate(false)
 {
   CharArray menuKeyStr(menuKey.getData());
   menuKeysym = XStringToKeysym(menuKeyStr.buf);
@@ -306,8 +307,11 @@
 // one. We cannot do this if we're in the middle of a format change
 // though.
 void CConn::framebufferUpdateStart() {
-  if (!formatChange)
+  if (!formatChange) {
+    pendingUpdate = true;
     requestNewUpdate();
+  } else
+    pendingUpdate = false;
 }
 
 // framebufferUpdateEnd() is called at the end of an update.
@@ -367,7 +371,7 @@
 
   // A format change prevented us from sending this before the update,
   // so make sure to send it now.
-  if (formatChange)
+  if (formatChange && !pendingUpdate)
     requestNewUpdate();
 
   // Compute new settings based on updated bandwidth values
@@ -536,8 +540,11 @@
     break;
   case ID_REFRESH:
     menu.unmap();
-    writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height),
-                                            false);
+    if (!formatChange) {
+      writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height),
+                                              false);
+      pendingUpdate = true;
+    }
     break;
   case ID_F8:
     menu.unmap();
@@ -840,6 +847,10 @@
 void CConn::requestNewUpdate()
 {
   if (formatChange) {
+
+    /* Catch incorrect requestNewUpdate calls */
+    assert(pendingUpdate == false);
+
     if (fullColour) {
       desktop->setPF(fullColourPF);
     } else {
diff --git a/unix/vncviewer/CConn.h b/unix/vncviewer/CConn.h
index 294b9b1..94fa18c 100644
--- a/unix/vncviewer/CConn.h
+++ b/unix/vncviewer/CConn.h
@@ -132,6 +132,7 @@
   InfoDialog info;
   bool reverseConnection;
   bool firstUpdate;
+  bool pendingUpdate;
 };
 
 #endif