--- vnc_unixsrc.orig/vncviewer/desktop.c	2004-05-28 13:29:29.000000000 -0400
+++ vnc_unixsrc/vncviewer/desktop.c	2007-01-13 13:59:51.000000000 -0500
@@ -50,6 +50,30 @@
   },
 };
 
+void create_image() {
+  image = NULL;
+
+#ifdef MITSHM
+  if (appData.useShm) {
+    image = CreateShmImage();
+    if (!image)
+      appData.useShm = False;
+  }
+#endif
+
+  if (!image) {
+    image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
+			 si.framebufferWidth, si.framebufferHeight,
+			 BitmapPad(dpy), 0);
+
+    image->data = malloc(image->bytes_per_line * image->height);
+    if (!image->data) {
+      fprintf(stderr,"malloc failed\n");
+      exit(1);
+    }
+  }
+}
+
 
 /*
  * DesktopInitBeforeRealization creates the "desktop" widget and the viewport
@@ -82,30 +106,9 @@
   for (i = 0; i < 256; i++)
     modifierPressed[i] = False;
 
-  image = NULL;
-
-#ifdef MITSHM
-  if (appData.useShm) {
-    image = CreateShmImage();
-    if (!image)
-      appData.useShm = False;
-  }
-#endif
-
-  if (!image) {
-    image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-			 si.framebufferWidth, si.framebufferHeight,
-			 BitmapPad(dpy), 0);
-
-    image->data = malloc(image->bytes_per_line * image->height);
-    if (!image->data) {
-      fprintf(stderr,"malloc failed\n");
-      exit(1);
-    }
-  }
+  create_image();
 }
 
-
 /*
  * DesktopInitAfterRealization does things which require the X windows to
  * exist.  It creates some GCs and sets the dot cursor.
@@ -460,3 +463,70 @@
     break;
   }
 }
+
+static void reset_image(void) {
+	if (UsingShm()) {
+		ShmCleanup();
+	} else {
+		if (image && image->data) {
+			free(image->data);
+			/* see manpage XDestroyImage may also free data, so we skip and have a tiny leak instead */
+			if (0) XDestroyImage(image);
+			image = NULL;
+		}
+	}
+	create_image();
+	XFlush(dpy);
+}
+
+void ReDoDesktop(void) {
+	int w, h, x, y, dw, dh;
+
+	if (appData.fullScreen) {
+		if (image && image->data) {
+			int len;
+			int h = image->height;
+			int w = image->width;
+			len = image->bytes_per_line * image->height;
+			/* black out window first: */
+			memset(image->data, 0, len);
+  			XPutImage(dpy, XtWindow(desktop), gc, image, 0, 0, 0, 0, w, h);
+			XFlush(dpy);
+		}
+		XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0);
+		XSync(dpy, False);
+		usleep(100*1000);
+		FullScreenOn();
+		XSync(dpy, False);
+		usleep(100*1000);
+		reset_image();
+		return;
+	}
+
+	dw = appData.wmDecorationWidth;
+	dh = appData.wmDecorationHeight;
+
+	w = si.framebufferWidth;
+	h = si.framebufferHeight;
+
+	if (w + dw >= dpyWidth) {
+		w = dpyWidth - dw;
+	}
+	if (h + dh >= dpyHeight) {
+		h = dpyHeight - dh;
+	}
+
+	XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL);
+
+	XtVaSetValues(desktop, XtNwidth, si.framebufferWidth,
+	    XtNheight, si.framebufferHeight, NULL);
+
+	x = (dpyWidth  - w - dw)/2;
+	y = (dpyHeight - h - dh)/2;
+
+	XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0);
+
+	XtConfigureWidget(toplevel, x + dw, y + dh, w, h, 0);
+
+	reset_image();
+}
--- vnc_unixsrc.orig/vncviewer/fullscreen.c	2003-10-09 05:23:49.000000000 -0400
+++ vnc_unixsrc/vncviewer/fullscreen.c	2006-07-27 14:36:06.000000000 -0400
@@ -85,10 +85,13 @@
   Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight;
   Position viewportX, viewportY;
 
+  Bool fsAlready = appData.fullScreen, toobig = False;
+
   appData.fullScreen = True;
 
   if (si.framebufferWidth > dpyWidth || si.framebufferHeight > dpyHeight) {
 
+    toobig = True;
     XtVaSetValues(viewport, XtNforceBars, True, NULL);
     XtVaGetValues(viewport, XtNwidth, &oldViewportWidth,
 		  XtNheight, &oldViewportHeight, NULL);
@@ -129,6 +132,7 @@
      reparenting our window to the root.  The window manager will get a
      ReparentNotify and hopefully clean up its frame window. */
 
+if (! fsAlready) {
   XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL);
 
   XReparentWindow(dpy, XtWindow(toplevel), DefaultRootWindow(dpy), 0, 0);
@@ -164,10 +168,22 @@
 
   XtManageChild(viewport);
 
-  /* Now we can set "toplevel" to its proper size. */
+} else {
+	XSync(dpy, False);
+}
 
+  /* Now we can set "toplevel" to its proper size. */
   XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
 
+if (fsAlready) {
+  XtResizeWidget(viewport, viewportWidth, viewportHeight, 0);
+  if (! toobig) {
+	XtVaSetValues(viewport, XtNforceBars, False, NULL);
+  }
+  XMoveWindow(dpy, XtWindow(viewport), viewportX, viewportY);
+  XSync(dpy, False);
+}
+
   /* Set the popup to overrideRedirect too */
 
   XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
--- vnc_unixsrc.orig/vncviewer/rfbproto.c	2004-03-11 13:14:39.000000000 -0500
+++ vnc_unixsrc/vncviewer/rfbproto.c	2006-07-25 21:51:20.000000000 -0400
@@ -177,6 +177,9 @@
 	  sig_rfbEncodingPointerPos, "Pointer position update");
   CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
 	  sig_rfbEncodingLastRect, "LastRect protocol extension");
+
+  CapsAdd(encodingCaps, rfbEncodingNewFBSize, rfbTightVncVendor,
+	  sig_rfbEncodingNewFBSize, "New FB size protocol extension");
 }
 
 
@@ -729,6 +732,7 @@
   Bool requestCompressLevel = False;
   Bool requestQualityLevel = False;
   Bool requestLastRectEncoding = False;
+  Bool requestNewFBSizeEncoding = True;
 
   spf.type = rfbSetPixelFormat;
   spf.format = myFormat;
@@ -806,6 +810,10 @@
     if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
       encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
     }
+
+    if (se->nEncodings < MAX_ENCODINGS && requestNewFBSizeEncoding) {
+      encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
+    }
   }
   else {
     if (SameMachine(rfbsock)) {
@@ -849,6 +857,7 @@
     }
 
     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
+    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
   }
 
   len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
@@ -1038,6 +1047,16 @@
 	}
 	continue;
       }
+      if (rect.encoding == rfbEncodingNewFBSize) {
+	  fprintf(stderr,"New Size: %dx%d at (%d, %d)\n",
+		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
+	si.framebufferWidth = rect.r.w;
+	si.framebufferHeight = rect.r.h;
+        fprintf(stderr, "si: %d %d\n", si.framebufferWidth, si.framebufferHeight);
+	ReDoDesktop();
+
+	continue;
+      }
 
       if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
 	  (rect.r.y + rect.r.h > si.framebufferHeight))
--- vnc_unixsrc.orig/vncviewer/shm.c	2000-06-11 08:00:53.000000000 -0400
+++ vnc_unixsrc/vncviewer/shm.c	2006-07-26 23:30:42.000000000 -0400
@@ -41,6 +41,10 @@
   }
 }
 
+Bool UsingShm() {
+	return needShmCleanup;
+}
+
 static int
 ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error)
 {
--- vnc_unixsrc.orig/vncviewer/vncviewer.h	2004-03-11 13:14:40.000000000 -0500
+++ vnc_unixsrc/vncviewer/vncviewer.h	2006-07-26 23:31:25.000000000 -0400
@@ -162,6 +162,8 @@
 extern void CopyDataToScreen(char *buf, int x, int y, int width, int height);
 extern void SynchroniseScreen();
 
+extern void ReDoDesktop();
+
 /* dialogs.c */
 
 extern void ServerDialogDone(Widget w, XEvent *event, String *params,
@@ -243,6 +245,7 @@
 
 extern XImage *CreateShmImage();
 extern void ShmCleanup();
+extern Bool UsingShm();
 
 /* sockets.c */
 
--- vnc_unixsrc.orig/vncviewer/vncviewer.c	2004-01-13 09:22:05.000000000 -0500
+++ vnc_unixsrc/vncviewer/vncviewer.c	2006-07-27 19:00:25.000000000 -0400
@@ -57,6 +57,11 @@
     }
   }
 
+  if (argc > 1 && strstr(argv[1], "-h") == argv[1]) {
+  	usage();
+	return 0;
+  }
+
   /* Call the main Xt initialisation function.  It parses command-line options,
      generating appropriate resource specs, and makes a connection to the X
      display. */
