diff --git a/x0vncserver/Image.cxx b/x0vncserver/Image.cxx
index 56a197e..880fa5f 100644
--- a/x0vncserver/Image.cxx
+++ b/x0vncserver/Image.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ * Copyright (C) 2004-2005 Constantin Kaplinsky.  All Rights Reserved.
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,24 +20,31 @@
 // Image.cxx
 //
 
-
 #include <stdio.h>
 #include <sys/types.h>
+
+#ifdef HAVE_MITSHM
 #include <sys/ipc.h>
 #include <sys/shm.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
+#endif
+
 #include "Image.h"
+
+//
+// ImageCleanup is used to delete Image instances automatically on
+// program shutdown. This is important for shared memory images.
+//
+
 #include <list>
 
 class ImageCleanup {
 public:
-  std::list<Image*> images;
+  std::list<Image *> images;
 
   ~ImageCleanup()
   {
-    fprintf(stderr,"~ImageCleanup called\n");
+    // DEBUG:
+    // fprintf(stderr, "~ImageCleanup() called\n");
 
     while (!images.empty()) {
       delete images.front();
@@ -46,6 +54,91 @@
 
 ImageCleanup imageCleanup;
 
+//
+// Image class implementation.
+//
+
+Image::Image(Display *d)
+  : xim(NULL), dpy(d), trueColor(true)
+{
+  imageCleanup.images.push_back(this);
+}
+
+Image::Image(Display *d, int width, int height)
+  : xim(NULL), dpy(d), trueColor(true)
+{
+  imageCleanup.images.push_back(this);
+  Init(width, height);
+}
+
+void Image::Init(int width, int height)
+{
+  Visual* vis = DefaultVisual(dpy, DefaultScreen(dpy));
+  trueColor = (vis->c_class == TrueColor);
+
+  xim = XCreateImage(dpy, vis, DefaultDepth(dpy, DefaultScreen(dpy)),
+                     ZPixmap, 0, 0, width, height, BitmapPad(dpy), 0);
+
+  xim->data = (char *)malloc(xim->bytes_per_line * xim->height);
+  if (xim->data == NULL) {
+    fprintf(stderr, "malloc() failed\n");
+    exit(1);
+  }
+}
+
+Image::~Image()
+{
+  // DEBUG:
+  // fprintf(stderr, "~Image() called\n");
+
+  imageCleanup.images.remove(this);
+  if (xim != NULL)
+    XDestroyImage(xim);
+}
+
+void Image::get(Window wnd, int x, int y)
+{
+  get(wnd, x, y, xim->width, xim->height);
+}
+
+void Image::get(Window wnd, int x, int y, int w, int h)
+{
+  XGetSubImage(dpy, wnd, x, y, w, h, AllPlanes, ZPixmap, xim, 0, 0);
+}
+
+void Image::updateRect(Image *src, int dst_x, int dst_y)
+{
+  updateRect(src->xim, dst_x, dst_y);
+}
+
+void Image::updateRect(XImage *src, int dst_x, int dst_y)
+{
+  // Limit width and height at destination image size
+  int w = src->width;
+  if (dst_x + w > xim->width)
+    w = xim->width - dst_x;
+  int h = src->height;
+  if (dst_y + h > xim->height)
+    h = xim->height - dst_y;
+
+  // Copy pixels
+  const char *srcOffset = src->data;
+  char *dstOffset = xim->data + (dst_y * xim->bytes_per_line +
+                                 dst_x * (xim->bits_per_pixel / 8));
+  int lineLength = w * (xim->bits_per_pixel / 8);
+  for (int i = 0; i < h ; i++) {
+    memcpy(dstOffset, srcOffset, lineLength);
+    srcOffset += src->bytes_per_line;
+    dstOffset += xim->bytes_per_line;
+  }
+}
+
+#ifdef HAVE_MITSHM
+
+//
+// ShmImage class implementation.
+//
+
 static bool caughtShmError = false;
 
 static int ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error)
@@ -54,96 +147,360 @@
   return 0;
 }
 
-Image::Image(Display* d, int width, int height)
-  : xim(0), dpy(d), shminfo(0), usingShm(false)
+ShmImage::ShmImage(Display *d)
+  : Image(d), shminfo(NULL)
 {
-  if (createShmImage(width, height)) return;
-
-  xim = XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)),
-                     DefaultDepth(dpy,DefaultScreen(dpy)), ZPixmap,
-                     0, 0, width, height, BitmapPad(dpy), 0);
-
-  xim->data = (char*)malloc(xim->bytes_per_line * xim->height);
-  if (!xim->data) {
-    fprintf(stderr,"malloc failed\n");
-    exit(1);
-  }
 }
 
-Image::~Image()
+ShmImage::ShmImage(Display *d, int width, int height)
+  : Image(d), shminfo(NULL)
 {
-  fprintf(stderr,"~Image called - usingShm %d\n",usingShm);
-  if (usingShm) {
-    usingShm = false;
+  Init(width, height);
+}
+
+// FIXME: Remove duplication of cleanup operations.
+void ShmImage::Init(int width, int height, const XVisualInfo *vinfo)
+{
+  int major, minor;
+  Bool pixmaps;
+
+  if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps)) {
+    fprintf(stderr, "XShmQueryVersion() failed\n");
+    return;
+  }
+
+  Visual *visual;
+  int depth;
+
+  if (vinfo == NULL) {
+    visual = DefaultVisual(dpy, DefaultScreen(dpy));
+    depth = DefaultDepth(dpy, DefaultScreen(dpy));
+  } else {
+    visual = vinfo->visual;
+    depth = vinfo->depth;
+  }
+
+  trueColor = (visual->c_class == TrueColor);
+
+  shminfo = new XShmSegmentInfo;
+
+  xim = XShmCreateImage(dpy, visual, depth, ZPixmap, 0, shminfo,
+			width, height);
+  if (xim == NULL) {
+    fprintf(stderr, "XShmCreateImage() failed\n");
+    delete shminfo;
+    shminfo = NULL;
+    return;
+  }
+
+  shminfo->shmid = shmget(IPC_PRIVATE,
+                          xim->bytes_per_line * xim->height,
+                          IPC_CREAT|0777);
+  if (shminfo->shmid == -1) {
+    perror("shmget");
+    fprintf(stderr,
+            "shmget() failed (%d bytes requested)\n",
+            int(xim->bytes_per_line * xim->height));
+    XDestroyImage(xim);
+    xim = NULL;
+    delete shminfo;
+    shminfo = NULL;
+    return;
+  }
+
+  shminfo->shmaddr = xim->data = (char *)shmat(shminfo->shmid, 0, 0);
+  if (shminfo->shmaddr == (char *)-1) {
+    perror("shmat");
+    fprintf(stderr,
+            "shmat() failed (%d bytes requested)\n",
+            int(xim->bytes_per_line * xim->height));
+    shmctl(shminfo->shmid, IPC_RMID, 0);
+    XDestroyImage(xim);
+    xim = NULL;
+    delete shminfo;
+    shminfo = NULL;
+    return;
+  }
+
+  shminfo->readOnly = False;
+
+  XErrorHandler oldHdlr = XSetErrorHandler(ShmCreationXErrorHandler);
+  XShmAttach(dpy, shminfo);
+  XSync(dpy, False);
+  XSetErrorHandler(oldHdlr);
+  if (caughtShmError) {
+    fprintf(stderr, "XShmAttach() failed\n");
     shmdt(shminfo->shmaddr);
     shmctl(shminfo->shmid, IPC_RMID, 0);
-    imageCleanup.images.remove(this);
+    XDestroyImage(xim);
+    xim = NULL;
+    delete shminfo;
+    shminfo = NULL;
+    return;
   }
-  delete shminfo;
-  if (xim) XDestroyImage(xim);
+
+  // DEBUG:
+  // fprintf(stderr,
+  //        "Using shared memory XImage (%d bytes image data)\n",
+  //        int(xim->bytes_per_line * xim->height));
 }
 
-void Image::get(Window w)
+ShmImage::~ShmImage()
 {
-  if (usingShm) {
-    XShmGetImage(dpy, w, xim, 0, 0, AllPlanes);
-  } else {
-    XGetSubImage(dpy, w, 0, 0, xim->width, xim->height,
-                 AllPlanes, ZPixmap, xim, 0, 0);
+  // DEBUG:
+  // fprintf(stderr,"~ShmImage called\n");
+
+  // FIXME: Destroy image as described in MIT-SHM documentation.
+  if (shminfo != NULL) {
+    shmdt(shminfo->shmaddr);
+    shmctl(shminfo->shmid, IPC_RMID, 0);
+    delete shminfo;
   }
 }
 
-bool Image::createShmImage(int width, int height)
+void ShmImage::get(Window wnd, int x, int y)
 {
-  if (XShmQueryExtension(dpy)) {
-    shminfo = new XShmSegmentInfo;
+  XShmGetImage(dpy, wnd, xim, x, y, AllPlanes);
+}
 
-    xim = XShmCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)),
-                          DefaultDepth(dpy,DefaultScreen(dpy)), ZPixmap,
-                          0, shminfo, width, height);
+void ShmImage::get(Window wnd, int x, int y, int w, int h)
+{
+  // FIXME: Use SHM for this as well?
+  XGetSubImage(dpy, wnd, x, y, w, h, AllPlanes, ZPixmap, xim, 0, 0);
+}
 
-    if (xim) {
-      shminfo->shmid = shmget(IPC_PRIVATE,
-                              xim->bytes_per_line * xim->height,
-                              IPC_CREAT|0777);
+#ifdef HAVE_READDISPLAY
 
-      if (shminfo->shmid != -1) {
-        shminfo->shmaddr = xim->data = (char*)shmat(shminfo->shmid, 0, 0);
+//
+// IrixOverlayShmImage class implementation.
+//
 
-        if (shminfo->shmaddr != (char *)-1) {
+IrixOverlayShmImage::IrixOverlayShmImage(Display *d)
+  : ShmImage(d), readDisplayBuf(NULL)
+{
+}
 
-          shminfo->readOnly = False;
+IrixOverlayShmImage::IrixOverlayShmImage(Display *d, int width, int height)
+  : ShmImage(d), readDisplayBuf(NULL)
+{
+  Init(width, height);
+}
 
-          XErrorHandler oldHdlr = XSetErrorHandler(ShmCreationXErrorHandler);
-          XShmAttach(dpy, shminfo);
-          XSync(dpy, False);
-          XSetErrorHandler(oldHdlr);
+void IrixOverlayShmImage::Init(int width, int height)
+{
+  // First determine the pixel format used by XReadDisplay.
+  XVisualInfo vinfo;
+  if (!getOverlayVisualInfo(&vinfo))
+    return;
 
-          if (!caughtShmError) {
-            fprintf(stderr,"Using shared memory XImage\n");
-            usingShm = true;
-            imageCleanup.images.push_back(this);
-            return true;
-          }
+  // Create an SHM image of the same format.
+  ShmImage::Init(width, height, &vinfo);
+  if (xim == NULL)
+    return;
 
-          shmdt(shminfo->shmaddr);
-        } else {
-          fprintf(stderr,"shmat failed\n");
-          perror("shmat");
-        }
+  // FIXME: Check if the extension is available at run time.
+  // FIXME: Does XShmCreateReadDisplayBuf() require some cleanup?
+  readDisplayBuf = XShmCreateReadDisplayBuf(dpy, NULL, shminfo, width, height);
+}
 
-        shmctl(shminfo->shmid, IPC_RMID, 0);
-      } else {
-        fprintf(stderr,"shmget failed\n");
-        perror("shmget");
+bool IrixOverlayShmImage::getOverlayVisualInfo(XVisualInfo *vinfo_ret)
+{
+  // First, get an image in the format returned by XReadDisplay.
+  unsigned long hints = 0, hints_ret;
+  XImage *testImage = XReadDisplay(dpy, DefaultRootWindow(dpy),
+				   0, 0, 8, 8, hints, &hints_ret);
+  if (testImage == NULL)
+    return false;
+
+  // Fill in a template for matching visuals.
+  XVisualInfo tmpl;
+  tmpl.c_class = TrueColor;
+  tmpl.depth = 24;
+  tmpl.red_mask = testImage->red_mask;
+  tmpl.green_mask = testImage->green_mask;
+  tmpl.blue_mask = testImage->blue_mask;
+
+  // List fields in template that make sense.
+  long mask = (VisualClassMask |
+	       VisualRedMaskMask |
+	       VisualGreenMaskMask |
+	       VisualBlueMaskMask);
+
+  // We don't need that image any more.
+  XDestroyImage(testImage);
+
+  // Now, get a list of matching visuals available.
+  int nVisuals;
+  XVisualInfo *vinfo = XGetVisualInfo(dpy, mask, &tmpl, &nVisuals);
+  if (vinfo == NULL || nVisuals <= 0) {
+    if (vinfo != NULL) {
+      XFree(vinfo);
+    }
+    return false;
+  }
+
+  // Use first visual from the list.
+  *vinfo_ret = vinfo[0];
+
+  XFree(vinfo);
+
+  return true;
+}
+
+IrixOverlayShmImage::~IrixOverlayShmImage()
+{
+  // DEBUG:
+  // fprintf(stderr,"~IrixOverlayShmImage called\n");
+}
+
+void IrixOverlayShmImage::get(Window wnd, int x, int y)
+{
+    XRectangle rect; 
+    unsigned long hints = XRD_TRANSPARENT | XRD_READ_POINTER;
+
+    rect.x = x;
+    rect.y = y;
+    rect.width = xim->width;
+    rect.height = xim->height;
+
+    XShmReadDisplayRects(dpy, wnd,
+                         &rect, 1, readDisplayBuf, -x, -y,
+                         hints, &hints);
+}
+
+void IrixOverlayShmImage::get(Window wnd, int x, int y, int w, int h)
+{
+  // FIXME: Use XReadDisplay extension here as well!
+  XGetSubImage(dpy, wnd, x, y, w, h, AllPlanes, ZPixmap, xim, 0, 0);
+}
+
+#endif // HAVE_READDISPLAY
+#endif // HAVE_MITSHM
+
+#ifdef HAVE_SUN_OVL
+
+//
+// SolarisOverlayImage class implementation
+//
+
+SolarisOverlayImage::SolarisOverlayImage(Display *d)
+  : Image(d)
+{
+}
+
+SolarisOverlayImage::SolarisOverlayImage(Display *d, int width, int height)
+  : Image(d)
+{
+  Init(width, height);
+}
+
+void SolarisOverlayImage::Init(int width, int height)
+{
+  // FIXME: Check if the extension is available at run time.
+  // FIXME: Maybe just read a small (e.g. 8x8) screen area then
+  //        reallocate xim->data[] and correct width and height?
+  xim = XReadScreen(dpy, DefaultRootWindow(dpy), 0, 0, width, height, True);
+  if (xim == NULL) {
+    fprintf(stderr, "XReadScreen() failed\n");
+    return;
+  }
+}
+
+SolarisOverlayImage::~SolarisOverlayImage()
+{
+  // DEBUG:
+  // fprintf(stderr, "~SolarisOverlayImage() called\n");
+}
+
+void SolarisOverlayImage::get(Window wnd, int x, int y)
+{
+  get(wnd, x, y, xim->width, xim->height);
+}
+
+void SolarisOverlayImage::get(Window wnd, int x, int y, int w, int h)
+{
+  XImage *tmp_xim = XReadScreen(dpy, wnd, x, y, w, h, True);
+  if (tmp_xim == NULL)
+    return;
+
+  updateRect(tmp_xim, 0, 0);
+
+  XDestroyImage(tmp_xim);
+}
+
+#endif // HAVE_SUN_OVL
+
+//
+// ImageFactory class implementation
+//
+
+// Prepare useful shortcuts for compile-time options.
+#if defined(HAVE_READDISPLAY) && defined(HAVE_MITSHM)
+#define HAVE_SHM_READDISPLAY
+#endif
+#if defined(HAVE_SHM_READDISPLAY) || defined(HAVE_SUN_OVL)
+#define HAVE_OVERLAY_EXT
+#endif
+
+ImageFactory::ImageFactory(bool allowShm, bool allowOverlay)
+  : mayUseShm(allowShm), mayUseOverlay(allowOverlay)
+{
+}
+
+ImageFactory::~ImageFactory()
+{
+}
+
+Image *ImageFactory::newImage(Display *d, int width, int height)
+{
+  Image *image = NULL;
+
+  // First, try to create an image with overlay support.
+
+#ifdef HAVE_OVERLAY_EXT
+  if (mayUseOverlay) {
+#if defined(HAVE_SHM_READDISPLAY)
+    if (mayUseShm) {
+      image = new IrixOverlayShmImage(d, width, height);
+      if (image->xim != NULL) {
+        fprintf(stderr, "Using IRIX overlay image with SHM support\n");
+        return image;
       }
-
-      XDestroyImage(xim);
-      xim = 0;
-    } else {
-      fprintf(stderr,"XShmCreateImage failed\n");
+    }
+#elif defined(HAVE_SUN_OVL)
+    image = new SolarisOverlayImage(d, width, height);
+    if (image->xim != NULL) {
+      fprintf(stderr, "Using Solaris overlay image\n");
+      return image;
+    }
+#endif
+    if (image != NULL) {
+      delete image;
+      fprintf(stderr,
+              "Failed to create overlay image, trying other options\n");
     }
   }
+#endif // HAVE_OVERLAY_EXT
 
-  return false;
+  // Now, try to use shared memory image.
+
+#ifdef HAVE_MITSHM
+  if (mayUseShm) {
+    image = new ShmImage(d, width, height);
+    if (image->xim != NULL) {
+      fprintf(stderr, "Using shared memory image\n");
+      return image;
+    }
+
+    delete image;
+    fprintf(stderr, 
+            "Failed to create SHM image, falling back to Xlib image\n");
+  }
+#endif // HAVE_MITSHM
+
+  // Fall back to Xlib image.
+
+  fprintf(stderr, "Using Xlib-based image\n");
+  image = new Image(d, width, height);
+  return image;
 }
diff --git a/x0vncserver/Image.h b/x0vncserver/Image.h
index 1a9ff1c..032e24a 100644
--- a/x0vncserver/Image.h
+++ b/x0vncserver/Image.h
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ * Copyright (C) 2004-2005 Constantin Kaplinsky.  All Rights Reserved.
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,26 +24,159 @@
 #define __IMAGE_H__
 
 #include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
+#include <X11/Xutil.h>
+
+//
+// Image class is an Xlib-based implementation of screen image storage.
+//
 
 class Image {
 
 public:
 
-  Image(Display* dpy, int width, int height);
-  ~Image();
+  Image(Display *d);
+  Image(Display *d, int width, int height);
+  virtual ~Image();
 
-  void get(Window w);
+  bool isTrueColor() { return trueColor; }
 
+  virtual void get(Window wnd, int x = 0, int y = 0);
+  virtual void get(Window wnd, int x, int y, int w, int h);
+
+  virtual void updateRect(Image *src, int dst_x = 0, int dst_y = 0);
+  virtual void updateRect(XImage *src, int dst_x = 0, int dst_y = 0);
+
+  // Pointer to corresponding XImage, made public for efficiency.
+  // NOTE: if this field is NULL, then no methods other than Init()
+  //       may be called.
   XImage* xim;
 
-private:
+protected:
 
-  bool createShmImage(int width, int height);
+  void Init(int width, int height);
 
-  Display* dpy;
-  XShmSegmentInfo* shminfo;
-  bool usingShm;
+  Display *dpy;
+  bool trueColor;
+
 };
 
-#endif
+//
+// ShmImage uses MIT-SHM extension of an X server to get image data.
+//
+
+#ifdef HAVE_MITSHM
+
+#include <X11/extensions/XShm.h>
+
+class ShmImage : public Image {
+
+public:
+
+  ShmImage(Display *d);
+  ShmImage(Display *d, int width, int height);
+  virtual ~ShmImage();
+
+  virtual void get(Window wnd, int x = 0, int y = 0);
+  virtual void get(Window wnd, int x, int y, int w, int h);
+
+protected:
+
+  void Init(int width, int height, const XVisualInfo *vinfo = NULL);
+
+  XShmSegmentInfo *shminfo;
+
+};
+
+//
+// IrixOverlayShmImage uses ReadDisplay extension of an X server to
+// get truecolor image data, regardless of the default X visual type. 
+// This method is available on Irix only.
+//
+
+#ifdef HAVE_READDISPLAY
+
+#include <X11/extensions/readdisplay.h>
+
+class IrixOverlayShmImage : public ShmImage {
+
+public:
+
+  IrixOverlayShmImage(Display *d);
+  IrixOverlayShmImage(Display *d, int width, int height);
+  virtual ~IrixOverlayShmImage();
+
+  virtual void get(Window wnd, int x = 0, int y = 0);
+  virtual void get(Window wnd, int x, int y, int w, int h);
+
+protected:
+
+  void Init(int width, int height);
+
+  // This method searches available X visuals for one that matches
+  // actual pixel format returned by XReadDisplay(). Returns true on
+  // success, false if there is no matching visual. On success, visual
+  // information is placed into the structure pointed by vinfo_ret.
+  bool getOverlayVisualInfo(XVisualInfo *vinfo_ret);
+
+  ShmReadDisplayBuf *readDisplayBuf;
+
+};
+
+#endif // HAVE_READDISPLAY
+#endif // HAVE_MITSHM
+
+//
+// SolarisOverlayImage uses SUN_OVL extension of an X server to get
+// truecolor image data, regardless of the default X visual type. This
+// method is available on Solaris only.
+//
+
+#ifdef HAVE_SUN_OVL
+
+#include <X11/extensions/transovl.h>
+
+class SolarisOverlayImage : public Image {
+
+public:
+
+  SolarisOverlayImage(Display *d);
+  SolarisOverlayImage(Display *d, int width, int height);
+  virtual ~SolarisOverlayImage();
+
+  virtual void get(Window wnd, int x = 0, int y = 0);
+  virtual void get(Window wnd, int x, int y, int w, int h);
+
+protected:
+
+  void Init(int width, int height);
+
+};
+
+#endif // HAVE_SUN_OVL
+
+//
+// ImageFactory class is used to produce instances of Image-derived
+// objects that are most appropriate for current X server and user
+// settings.
+//
+
+class ImageFactory {
+
+public:
+
+  ImageFactory(bool allowShm, bool allowOverlay);
+  virtual ~ImageFactory();
+
+  bool isShmAllowed()     { return mayUseShm; }
+  bool isOverlayAllowed() { return mayUseOverlay; }
+
+  virtual Image *newImage(Display *d, int width, int height);
+
+protected:
+
+  bool mayUseShm;
+  bool mayUseOverlay;
+
+};
+
+#endif // __IMAGE_H__
diff --git a/x0vncserver/x0vncserver.cxx b/x0vncserver/x0vncserver.cxx
index df40c33..e0d05f0 100644
--- a/x0vncserver/x0vncserver.cxx
+++ b/x0vncserver/x0vncserver.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ * Copyright (C) 2004-2005 Constantin Kaplinsky.  All Rights Reserved.
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -15,9 +16,14 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
+
+// FIXME: Check cases when screen width/height is not a multiply of 32.
+//        e.g. 800x600.
+
 #include <strings.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
 #include <rfb/Logger_stdio.h>
@@ -33,8 +39,9 @@
 #include <X11/X.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#ifdef HAVE_XTEST
 #include <X11/extensions/XTest.h>
-
+#endif
 
 #include <rfb/Encoder.h>
 
@@ -44,8 +51,14 @@
 
 LogWriter vlog("main");
 
+IntParameter pollingCycle("PollingCycle", "Milliseconds per one "
+                          "polling cycle", 50);
+BoolParameter useShm("UseSHM", "Use MIT-SHM extension if available", true);
+BoolParameter useOverlay("OverlayMode", "Use overlay mode under "
+                         "IRIX or Solaris", true);
 StringParameter displayname("display", "The X display", "");
 IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol",5900);
+StringParameter hostsFile("HostsFile", "File with IP access control rules", "");
 VncAuthPasswdFileParameter vncAuthPasswdFile;
 
 static void CleanupSignalHandler(int sig)
@@ -61,8 +74,10 @@
 {
 public:
   XDesktop(Display* dpy_)
-    : dpy(dpy_), pb(0), server(0), oldButtonMask(0), haveXtest(false)
+    : dpy(dpy_), pb(0), server(0), oldButtonMask(0), haveXtest(false),
+      maxButtons(0), pollingStep(0)
   {
+#ifdef HAVE_XTEST
     int xtestEventBase;
     int xtestErrorBase;
     int major, minor;
@@ -73,27 +88,41 @@
       vlog.info("XTest extension present - version %d.%d",major,minor);
       haveXtest = true;
     } else {
+#endif
       vlog.info("XTest extension not present");
       vlog.info("unable to inject events or display while server is grabbed");
+#ifdef HAVE_XTEST
     }
+#endif
+
+    // Determine actual number of buttons of the X pointer device.
+    unsigned char btnMap[8];
+    int numButtons = XGetPointerMapping(dpy, btnMap, 8);
+    maxButtons = (numButtons > 8) ? 8 : numButtons;
+    vlog.info("Enabling %d button%s of X pointer device",
+              maxButtons, (maxButtons != 1) ? "s" : "");
 
     int dpyWidth = DisplayWidth(dpy, DefaultScreen(dpy));
     int dpyHeight = DisplayHeight(dpy, DefaultScreen(dpy));
-    Visual* vis = DefaultVisual(dpy, DefaultScreen(dpy));
 
-    image = new Image(dpy, dpyWidth, dpyHeight);
+    // FIXME: verify that all three images use the same pixel format.
+    ImageFactory factory((bool)useShm, (bool)useOverlay);
+    image = factory.newImage(dpy, dpyWidth, dpyHeight);
+    rowImage = factory.newImage(dpy, dpyWidth, 1);
+    tileImage = factory.newImage(dpy, 32, 32);
+
     image->get(DefaultRootWindow(dpy));
 
     pf.bpp = image->xim->bits_per_pixel;
     pf.depth = image->xim->depth;
     pf.bigEndian = (image->xim->byte_order == MSBFirst);
-    pf.trueColour = (vis->c_class == TrueColor);
-    pf.redShift   = ffs(vis->red_mask) - 1;
-    pf.greenShift = ffs(vis->green_mask) - 1;
-    pf.blueShift  = ffs(vis->blue_mask) - 1;
-    pf.redMax     = vis->red_mask   >> pf.redShift;
-    pf.greenMax   = vis->green_mask >> pf.greenShift;
-    pf.blueMax    = vis->blue_mask  >> pf.blueShift;
+    pf.trueColour = image->isTrueColor();
+    pf.redShift   = ffs(image->xim->red_mask) - 1;
+    pf.greenShift = ffs(image->xim->green_mask) - 1;
+    pf.blueShift  = ffs(image->xim->blue_mask) - 1;
+    pf.redMax     = image->xim->red_mask   >> pf.redShift;
+    pf.greenMax   = image->xim->green_mask >> pf.greenShift;
+    pf.blueMax    = image->xim->blue_mask  >> pf.blueShift;
 
     pb = new FullFramePixelBuffer(pf, dpyWidth, dpyHeight,
                                   (rdr::U8*)image->xim->data, this);
@@ -110,10 +139,11 @@
   // -=- SDesktop interface
 
   virtual void pointerEvent(const Point& pos, rdr::U8 buttonMask) {
+#ifdef HAVE_XTEST
     if (!haveXtest) return;
     XTestFakeMotionEvent(dpy, DefaultScreen(dpy), pos.x, pos.y, CurrentTime);
     if (buttonMask != oldButtonMask) {
-      for (int i = 0; i < 5; i++) {
+      for (int i = 0; i < maxButtons; i++) {
 	if ((buttonMask ^ oldButtonMask) & (1<<i)) {
           if (buttonMask & (1<<i)) {
             XTestFakeButtonEvent(dpy, i+1, True, CurrentTime);
@@ -124,13 +154,16 @@
       }
     }
     oldButtonMask = buttonMask;
+#endif
   }
 
   virtual void keyEvent(rdr::U32 key, bool down) {
+#ifdef HAVE_XTEST
     if (!haveXtest) return;
     int keycode = XKeysymToKeycode(dpy, key);
     if (keycode)
       XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);
+#endif
   }
 
   virtual void clientCutText(const char* str, int len) {
@@ -154,12 +187,73 @@
     *b = xc.blue;
   }
 
-  virtual void poll() {
-    if (server && server->clientsReadyForUpdate()) {
-      image->get(DefaultRootWindow(dpy));
-      server->add_changed(pb->getRect());
-      server->tryUpdate();
+  //
+  // DEBUG: a version of poll() measuring time spent in the function.
+  //
+
+  virtual void pollDebug()
+  {
+    struct timeval timeSaved, timeNow;
+    struct timezone tz;
+    timeSaved.tv_sec = 0;
+    timeSaved.tv_usec = 0;
+    gettimeofday(&timeSaved, &tz);
+
+    poll();
+
+    gettimeofday(&timeNow, &tz);
+    int diff = (int)((timeNow.tv_usec - timeSaved.tv_usec + 500) / 1000 +
+                     (timeNow.tv_sec - timeSaved.tv_sec) * 1000);
+    if (diff != 0)
+      fprintf(stderr, "DEBUG: poll(): %4d ms\n", diff);
+  }
+
+  //
+  // Search for changed rectangles on the screen.
+  //
+
+  virtual void poll()
+  {
+    if (server == NULL)
+      return;
+
+    int nTilesChanged = 0;
+    int scanLine = XDesktop::pollingOrder[pollingStep++ % 32];
+    int bytesPerPixel = image->xim->bits_per_pixel / 8;
+    int bytesPerLine = image->xim->bytes_per_line;
+    int w = image->xim->width, h = image->xim->height;
+    Rect rect;
+
+    for (int y = 0; y * 32 < h; y++) {
+      int tile_h = (h - y * 32 >= 32) ? 32 : h - y * 32;
+      if (scanLine >= tile_h)
+        continue;
+      int scan_y = y * 32 + scanLine;
+      rowImage->get(DefaultRootWindow(dpy), 0, scan_y);
+      char *ptr_old = image->xim->data + scan_y * bytesPerLine;
+      char *ptr_new = rowImage->xim->data;
+      for (int x = 0; x * 32 < w; x++) {
+        int tile_w = (w - x * 32 >= 32) ? 32 : w - x * 32;
+        int nBytes = tile_w * bytesPerPixel;
+        if (memcmp(ptr_old, ptr_new, nBytes)) {
+          if (tile_w == 32 && tile_h == 32) {
+            tileImage->get(DefaultRootWindow(dpy), x * 32, y * 32);
+          } else {
+            tileImage->get(DefaultRootWindow(dpy), x * 32, y * 32,
+                           tile_w, tile_h);
+          }
+          image->updateRect(tileImage, x * 32, y * 32);
+          rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
+          server->add_changed(rect);
+          nTilesChanged++;
+        }
+        ptr_old += nBytes;
+        ptr_new += nBytes;
+      }
     }
+
+    if (nTilesChanged)
+      server->tryUpdate();
   }
 
 protected:
@@ -168,10 +262,123 @@
   PixelBuffer* pb;
   VNCServer* server;
   Image* image;
+  Image* rowImage;
+  Image* tileImage;
   int oldButtonMask;
   bool haveXtest;
+  int maxButtons;
+  unsigned int pollingStep;
+  static const int pollingOrder[];
 };
 
+const int XDesktop::pollingOrder[32] = {
+   0, 16,  8, 24,  4, 20, 12, 28,
+  10, 26, 18,  2, 22,  6, 30, 14,
+   1, 17,  9, 25,  7, 23, 15, 31,
+  19,  3, 27, 11, 29, 13,  5, 21
+};
+
+
+class FileTcpFilter : public TcpFilter
+{
+
+public:
+
+  FileTcpFilter(const char *fname)
+    : TcpFilter("-"), fileName(NULL), lastModTime(0)
+  {
+    if (fname != NULL)
+      fileName = strdup((char *)fname);
+  }
+
+  virtual ~FileTcpFilter()
+  {
+    if (fileName != NULL)
+      free(fileName);
+  }
+
+  virtual bool verifyConnection(Socket* s)
+  {
+    if (!reloadRules()) {
+      vlog.error("Could not read IP filtering rules: rejecting all clients");
+      filter.clear();
+      filter.push_back(parsePattern("-"));
+      return false;
+    }
+
+    return TcpFilter::verifyConnection(s);
+  }
+
+protected:
+
+  bool reloadRules()
+  {
+    if (fileName == NULL)
+      return true;
+
+    struct stat st;
+    if (stat(fileName, &st) != 0)
+      return false;
+
+    if (st.st_mtime != lastModTime) {
+      // Actually reload only if the file was modified
+      FILE *fp = fopen(fileName, "r");
+      if (fp == NULL)
+        return false;
+
+      // Remove all the rules from the parent class
+      filter.clear();
+
+      // Parse the file contents adding rules to the parent class
+      char buf[32];
+      while (readLine(buf, 32, fp)) {
+        if (buf[0] && strchr("+-?", buf[0])) {
+          filter.push_back(parsePattern(buf));
+        }
+      }
+
+      fclose(fp);
+      lastModTime = st.st_mtime;
+    }
+    return true;
+  }
+
+protected:
+
+  char *fileName;
+  time_t lastModTime;
+
+private:
+
+  //
+  // NOTE: we silently truncate long lines in this function.
+  //
+
+  bool readLine(char *buf, int bufSize, FILE *fp)
+  {
+    if (fp == NULL || buf == NULL || bufSize == 0)
+      return false;
+
+    if (fgets(buf, bufSize, fp) == NULL)
+      return false;
+
+    char *ptr = strchr(buf, '\n');
+    if (ptr != NULL) {
+      *ptr = '\0';              // remove newline at the end
+    } else {
+      if (!feof(fp)) {
+        int c;
+        do {                    // skip the rest of a long line
+          c = getc(fp);
+        } while (c != '\n' && c != EOF);
+      }
+    }
+    return true;
+  }
+
+};
+
+
 char* programName;
 
 static void usage()
@@ -233,12 +440,21 @@
     TcpListener listener((int)rfbport);
     vlog.info("Listening on port %d", (int)rfbport);
 
+    FileTcpFilter fileTcpFilter(hostsFile.getData());
+    if (strlen(hostsFile.getData()) != 0)
+      listener.setFilter(&fileTcpFilter);
+
+    struct timeval timeSaved, timeNow;
+    struct timezone tz;
+    gettimeofday(&timeSaved, &tz);
+    timeSaved.tv_sec -= 60;
+
     while (true) {
       fd_set rfds;
       struct timeval tv;
 
       tv.tv_sec = 0;
-      tv.tv_usec = 50*1000;
+      tv.tv_usec = (int)pollingCycle * 1000;
 
       FD_ZERO(&rfds);
       FD_SET(listener.getFd(), &rfds);
@@ -255,10 +471,19 @@
 
       if (FD_ISSET(listener.getFd(), &rfds)) {
         Socket* sock = listener.accept();
-        server.addClient(sock);
+        if (sock) {
+          server.addClient(sock);
+        } else {
+          vlog.status("Client connection rejected");
+        }
       }
 
       server.getSockets(&sockets);
+
+      // Nothing more to do if there are no client connections.
+      if (sockets.empty())
+        continue;
+
       for (i = sockets.begin(); i != sockets.end(); i++) {
         if (FD_ISSET((*i)->getFd(), &rfds)) {
           server.processSocketEvent(*i);
@@ -266,7 +491,19 @@
       }
 
       server.checkTimeouts();
-      desktop.poll();
+
+      if (gettimeofday(&timeNow, &tz) == 0) {
+        int diff = (int)((timeNow.tv_usec - timeSaved.tv_usec + 500) / 1000 +
+                         (timeNow.tv_sec - timeSaved.tv_sec) * 1000);
+        if (diff >= (int)pollingCycle) {
+          timeSaved = timeNow;
+          desktop.poll();
+        }
+      } else {
+        // Something strange has happened -- gettimeofday(2) failed.
+        // Poll after each select(), as in the original VNC4 code.
+        desktop.poll();
+      }
     }
 
   } catch (rdr::Exception &e) {
