diff --git a/unix/x0vncserver/PollingManager.cxx b/unix/x0vncserver/PollingManager.cxx
new file mode 100644
index 0000000..a823ed4
--- /dev/null
+++ b/unix/x0vncserver/PollingManager.cxx
@@ -0,0 +1,600 @@
+/* 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+//
+// PollingManager.cxx
+//
+
+// FIXME: Don't compare pixels already marked as changed.
+// FIXME: Use Image::copyPixels() instead of Image::updateRect()?
+//        In that case, note the fact that arguments are not checked.
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <X11/Xlib.h>
+#include <rfb/LogWriter.h>
+#include <rfb/VNCServer.h>
+#include <rfb/Configuration.h>
+#include <rfb/ServerCore.h>
+
+#include <x0vncserver/PollingManager.h>
+
+static LogWriter vlog("PollingMgr");
+
+BoolParameter PollingManager::pollPointer
+("PollPointer",
+ "DEBUG: Poll area under the pointer with higher priority",
+ true);
+
+IntParameter PollingManager::pollingType
+("PollingType",
+ "DEBUG: Select particular polling algorithm (0..3)",
+ 3);
+
+const int PollingManager::m_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
+};
+
+//
+// Constructor.
+//
+// Note that dpy and image should remain valid during the object
+// lifetime, while factory is used only in the constructor itself.
+//
+
+PollingManager::PollingManager(Display *dpy, Image *image,
+                               ImageFactory *factory,
+                               int offsetLeft, int offsetTop)
+  : m_dpy(dpy), m_server(0), m_image(image),
+    m_offsetLeft(offsetLeft), m_offsetTop(offsetTop),
+    m_pointerPosKnown(false), m_pollingStep(0)
+{
+  // Save width and height of the screen (and the image).
+  m_width = m_image->xim->width;
+  m_height = m_image->xim->height;
+
+  // Compute width and height in 32x32 tiles.
+  m_widthTiles = (m_width + 31) / 32;
+  m_heightTiles = (m_height + 31) / 32;
+
+  // Get initial screen image.
+  m_image->get(DefaultRootWindow(m_dpy), m_offsetLeft, m_offsetTop);
+
+  // Create additional images used in polling algorithms, warn if
+  // underlying class names are different from the class name of the
+  // primary image.
+  m_rowImage = factory->newImage(m_dpy, m_width, 1);
+  m_tileImage = factory->newImage(m_dpy, 32, 32);
+  m_areaImage = factory->newImage(m_dpy, 128, 128);
+  if (strcmp(m_image->className(), m_rowImage->className()) != 0 ||
+      strcmp(m_image->className(), m_tileImage->className()) != 0 ||
+      strcmp(m_image->className(), m_areaImage->className()) != 0) {
+    vlog.error("Image types do not match (%s, %s, %s)",
+               m_rowImage->className(),
+               m_tileImage->className(),
+               m_areaImage->className());
+  }
+
+  // FIXME: Extend the comment.
+  // Create a matrix with one byte per each 32x32 tile. It will be
+  // used to limit the rate of updates on continuously-changed screen
+  // areas (like video).
+  int numTiles = m_widthTiles * m_heightTiles;
+  m_statusMatrix = new char[numTiles];
+  memset(m_statusMatrix, 0, numTiles);
+
+  // FIXME: Extend the comment.
+  // Create a matrix with one byte per each 32x32 tile. It will be
+  // used to limit the rate of updates on continuously-changed screen
+  // areas (like video).
+  m_rateMatrix = new char[numTiles];
+  m_videoFlags = new char[numTiles];
+  m_changedFlags = new char[numTiles];
+  memset(m_rateMatrix, 0, numTiles);
+  memset(m_videoFlags, 0, numTiles);
+  memset(m_changedFlags, 0, numTiles);
+}
+
+PollingManager::~PollingManager()
+{
+  delete[] m_changedFlags;
+  delete[] m_videoFlags;
+  delete[] m_rateMatrix;
+
+  delete[] m_statusMatrix;
+
+  delete m_areaImage;
+  delete m_tileImage;
+  delete m_rowImage;
+}
+
+//
+// Register VNCServer object.
+//
+
+void PollingManager::setVNCServer(VNCServer *s)
+{
+  m_server = s;
+}
+
+//
+// Update current pointer position which may be used as a hint for
+// polling algorithms.
+//
+
+void PollingManager::setPointerPos(const Point &pos)
+{
+  m_pointerPosTime = time(NULL);
+  m_pointerPos = pos;
+  m_pointerPosKnown = true;
+}
+
+//
+// Indicate that current pointer position is unknown.
+//
+
+void PollingManager::unsetPointerPos()
+{
+  m_pointerPosKnown = false;
+}
+
+//
+// DEBUG: Measuring time spent in the poll() function,
+//        as well as time intervals between poll() calls.
+//
+
+#ifdef DEBUG
+void PollingManager::debugBeforePoll()
+{
+  TimeMillis timeNow;
+  int diff = timeNow.diffFrom(m_timeSaved);
+  fprintf(stderr, "[wait%4dms]\t[step %2d]\t", diff, m_pollingStep % 32);
+  m_timeSaved = timeNow;
+}
+
+void PollingManager::debugAfterPoll()
+{
+  TimeMillis timeNow;
+  int diff = timeNow.diffFrom(m_timeSaved);
+  fprintf(stderr, "[poll%4dms]\n", diff);
+  m_timeSaved = timeNow;
+}
+
+#endif
+
+//
+// Search for changed rectangles on the screen.
+//
+
+void PollingManager::poll()
+{
+#ifdef DEBUG
+  debugBeforePoll();
+#endif
+
+  // First step: full-screen polling.
+
+  bool changes1 = false;
+
+  switch((int)pollingType) {
+  case 0:
+    changes1 = poll_Dumb();
+    break;
+  case 1:
+    changes1 = poll_Traditional();
+    break;
+  case 2:
+    changes1 = poll_SkipCycles();
+    break;
+//case 3:
+  default:
+    changes1 = poll_DetectVideo();
+    break;
+  }
+
+  // Second step: optional thorough polling of the area around the pointer.
+  // We do that only if the pointer position is known and was set recently.
+
+  bool changes2 = false;
+  if (pollPointer) {
+    if (m_pointerPosKnown && time(NULL) - m_pointerPosTime >= 5) {
+      unsetPointerPos();
+    }
+    if (m_pointerPosKnown) {
+      changes2 = pollPointerArea();
+    }
+  }
+
+  // Update if needed.
+
+  if (changes1 || changes2)
+    m_server->tryUpdate();
+
+#ifdef DEBUG
+  debugAfterPoll();
+#endif
+}
+
+bool PollingManager::poll_DetectVideo()
+{
+  if (!m_server)
+    return false;
+
+  const int GRAND_STEP_DIVISOR = 8;
+  const int VIDEO_THRESHOLD_0 = 3;
+  const int VIDEO_THRESHOLD_1 = 5;
+
+  bool grandStep = (m_pollingStep % GRAND_STEP_DIVISOR == 0);
+
+  // FIXME: Save shortcuts in member variables?
+  int scanLine = m_pollingOrder[m_pollingStep++ % 32];
+  int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+  int bytesPerLine = m_image->xim->bytes_per_line;
+
+  Rect rect;
+  int nTilesChanged = 0;
+  int idx = 0;
+
+  for (int y = 0; y * 32 < m_height; y++) {
+    int tile_h = (m_height - y * 32 >= 32) ? 32 : m_height - y * 32;
+    if (scanLine >= tile_h)
+      break;
+    int scan_y = y * 32 + scanLine;
+    getRow(scan_y);
+    char *ptr_old = m_image->xim->data + scan_y * bytesPerLine;
+    char *ptr_new = m_rowImage->xim->data;
+    for (int x = 0; x * 32 < m_width; x++) {
+      int tile_w = (m_width - x * 32 >= 32) ? 32 : m_width - x * 32;
+      int nBytes = tile_w * bytesPerPixel;
+
+      char wasChanged = (memcmp(ptr_old, ptr_new, nBytes) != 0);
+      m_rateMatrix[idx] += wasChanged;
+
+      if (grandStep) {
+        if (m_rateMatrix[idx] <= VIDEO_THRESHOLD_0) {
+          m_videoFlags[idx] = 0;
+        } else if (m_rateMatrix[idx] >= VIDEO_THRESHOLD_1) {
+          m_videoFlags[idx] = 1;
+        }
+        m_rateMatrix[idx] = 0;
+      }
+
+      m_changedFlags[idx] |= wasChanged;
+      if ( m_changedFlags[idx] && (!m_videoFlags[idx] || grandStep) ) {
+        getTile32(x, y, tile_w, tile_h);
+        m_image->updateRect(m_tileImage, x * 32, y * 32);
+        rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
+        m_server->add_changed(rect);
+        nTilesChanged++;
+        m_changedFlags[idx] = 0;
+      }
+
+      ptr_old += nBytes;
+      ptr_new += nBytes;
+      idx++;
+    }
+  }
+
+  if (grandStep)
+    adjustVideoArea();
+
+  return (nTilesChanged != 0);
+}
+
+bool PollingManager::poll_SkipCycles()
+{
+  if (!m_server)
+    return false;
+
+  enum {
+    NOT_CHANGED, CHANGED_ONCE, CHANGED_AGAIN
+  };
+
+  bool grandStep = (m_pollingStep % 8 == 0);
+
+  int nTilesChanged = 0;
+  int scanLine = m_pollingOrder[m_pollingStep++ % 32];
+  int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+  int bytesPerLine = m_image->xim->bytes_per_line;
+  char *pstatus = m_statusMatrix;
+  bool wasChanged;
+  Rect rect;
+
+  for (int y = 0; y * 32 < m_height; y++) {
+    int tile_h = (m_height - y * 32 >= 32) ? 32 : m_height - y * 32;
+    if (scanLine >= tile_h)
+      scanLine %= tile_h;
+    int scan_y = y * 32 + scanLine;
+    getRow(scan_y);
+    char *ptr_old = m_image->xim->data + scan_y * bytesPerLine;
+    char *ptr_new = m_rowImage->xim->data;
+    for (int x = 0; x * 32 < m_width; x++) {
+      int tile_w = (m_width - x * 32 >= 32) ? 32 : m_width - x * 32;
+      int nBytes = tile_w * bytesPerPixel;
+
+      if (grandStep || *pstatus != CHANGED_AGAIN) {
+        wasChanged = (*pstatus == CHANGED_AGAIN) ?
+          true : (memcmp(ptr_old, ptr_new, nBytes) != 0);
+        if (wasChanged) {
+          if (grandStep || *pstatus == NOT_CHANGED) {
+            getTile32(x, y, tile_w, tile_h);
+            m_image->updateRect(m_tileImage, x * 32, y * 32);
+            rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
+            m_server->add_changed(rect);
+            nTilesChanged++;
+            *pstatus = CHANGED_ONCE;
+          } else {
+            *pstatus = CHANGED_AGAIN;
+          }
+        } else if (grandStep) {
+          *pstatus = NOT_CHANGED;
+        }
+      }
+
+      ptr_old += nBytes;
+      ptr_new += nBytes;
+      pstatus++;
+    }
+  }
+
+  return (nTilesChanged != 0);
+}
+
+bool PollingManager::poll_Traditional()
+{
+  if (!m_server)
+    return false;
+
+  int nTilesChanged = 0;
+  int scanLine = m_pollingOrder[m_pollingStep++ % 32];
+  int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+  int bytesPerLine = m_image->xim->bytes_per_line;
+  Rect rect;
+
+  for (int y = 0; y * 32 < m_height; y++) {
+    int tile_h = (m_height - y * 32 >= 32) ? 32 : m_height - y * 32;
+    if (scanLine >= tile_h)
+      break;
+    int scan_y = y * 32 + scanLine;
+    getRow(scan_y);
+    char *ptr_old = m_image->xim->data + scan_y * bytesPerLine;
+    char *ptr_new = m_rowImage->xim->data;
+    for (int x = 0; x * 32 < m_width; x++) {
+      int tile_w = (m_width - x * 32 >= 32) ? 32 : m_width - x * 32;
+      int nBytes = tile_w * bytesPerPixel;
+      if (memcmp(ptr_old, ptr_new, nBytes)) {
+        getTile32(x, y, tile_w, tile_h);
+        m_image->updateRect(m_tileImage, x * 32, y * 32);
+        rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
+        m_server->add_changed(rect);
+        nTilesChanged++;
+      }
+      ptr_old += nBytes;
+      ptr_new += nBytes;
+    }
+  }
+
+  return (nTilesChanged != 0);
+}
+
+//
+// Simplest polling method, from the original x0vncserver of VNC4.
+//
+
+bool PollingManager::poll_Dumb()
+{
+  if (!m_server)
+    return false;
+
+  getScreen();
+  Rect rect(0, 0, m_width, m_height);
+  m_server->add_changed(rect);
+
+  // Report that some changes have been detected.
+  return true;
+}
+
+//
+// Compute coordinates of the rectangle around the pointer.
+//
+// ASSUMES: (m_pointerPosKnown != false)
+//
+
+void PollingManager::computePointerArea(Rect *r)
+{
+  int x = m_pointerPos.x - 64;
+  int y = m_pointerPos.y - 64;
+  int w = 128;
+  int h = 128;
+  if (x < 0) {
+    w += x; x = 0;
+  }
+  if (x + w > m_width) {
+    w = m_width - x;
+  }
+  if (y < 0) {
+    h += y; y = 0;
+  }
+  if (y + h > m_height) {
+    h = m_height - y;
+  }
+
+  r->setXYWH(x, y, w, h);
+}
+
+//
+// Poll the area under current pointer position. Each pixel of the
+// area should be compared. Using such polling option gives higher
+// priority to screen area under the pointer.
+//
+// ASSUMES: (m_server != NULL && m_pointerPosKnown != false)
+//
+
+bool PollingManager::pollPointerArea()
+{
+  Rect r;
+  computePointerArea(&r);
+
+  // Shortcuts for coordinates.
+  int x = r.tl.x, y = r.tl.y;
+  int w = r.width(), h = r.height();
+
+  // Get new pixels.
+  getArea128(x, y, w, h);
+
+  // Now, try to minimize the rectangle by cutting out unchanged
+  // borders (at top and bottom).
+  //
+  // FIXME: Perhaps we should work on 32x32 tiles (properly aligned)
+  //        to produce a region instead of a rectangle. If there would
+  //        be just one universal polling algorithm, it could be
+  //        better to integrate pointer area polling into that
+  //        algorithm, instead of a separate pollPointerArea()
+  //        function.
+
+  // Shortcuts.
+  int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+  int oldBytesPerLine = m_image->xim->bytes_per_line;
+  int newBytesPerLine = m_areaImage->xim->bytes_per_line;
+  char *oldPtr = m_image->xim->data + y * oldBytesPerLine + x * bytesPerPixel;
+  char *newPtr = m_areaImage->xim->data;
+
+  // Check and cut out unchanged rows at the top.
+  int ty;
+  for (ty = 0; ty < h; ty++) {
+    if (memcmp(oldPtr, newPtr, w * bytesPerPixel) != 0)
+      break;
+    oldPtr += oldBytesPerLine;
+    newPtr += newBytesPerLine;
+  }
+  if (ty == h) {
+    return false;               // no changes at all
+  }
+  y += ty; h -= ty;
+
+  // Check and cut out unchanged rows at the bottom.
+  oldPtr = m_image->xim->data + (y+h-1) * oldBytesPerLine + x * bytesPerPixel;
+  newPtr = m_areaImage->xim->data + (ty+h-1) * newBytesPerLine;
+  int by;
+  for (by = 0; by < h - 1; by++) {
+    if (memcmp(oldPtr, newPtr, w * bytesPerPixel) != 0)
+      break;
+    oldPtr -= oldBytesPerLine;
+    newPtr -= newBytesPerLine;
+  }
+  h -= by;
+
+  // Copy pixels.
+  m_image->updateRect(m_areaImage, x, y, 0, ty, w, h);
+
+  // Report updates to the server.
+  Rect rect(x, y, x+w, y+h);
+  m_server->add_changed(rect);
+  return true;
+}
+
+//
+// Make video area pattern more regular.
+//
+// FIXME: Replace the above with a normal comment.
+// FIXME: Is the function efficient enough?
+//
+
+void PollingManager::adjustVideoArea()
+{
+  char newFlags[m_widthTiles * m_heightTiles];
+  char *ptr = newFlags;
+  int x, y;
+
+  // DEBUG:
+  // int nVideoTiles = 0;
+
+  for (y = 0; y < m_heightTiles; y++) {
+    for (x = 0; x < m_widthTiles; x++) {
+
+      // DEBUG:
+      // nVideoTiles += m_videoFlags[y * m_widthTiles + x];
+
+      int weightedSum = 0, n;
+      if (y > 0 && x > 0) {
+        n = (m_videoFlags[ y    * m_widthTiles + (x-1)] +
+             m_videoFlags[(y-1) * m_widthTiles + (x-1)] +
+             m_videoFlags[(y-1) * m_widthTiles +  x   ]);
+        if (n == 3) {
+          *ptr++ = 1;
+          continue;
+        }
+        weightedSum += n;
+      }
+      if (y > 0 && x < m_widthTiles - 1) {
+        n = (m_videoFlags[ y    * m_widthTiles + (x+1)] +
+             m_videoFlags[(y-1) * m_widthTiles + (x+1)] +
+             m_videoFlags[(y-1) * m_widthTiles +  x   ]);
+        if (n == 3) {
+          *ptr++ = 1;
+          continue;
+        }
+        weightedSum += n;
+      }
+      if (y < m_heightTiles - 1 && x > 0) {
+        n = (m_videoFlags[ y    * m_widthTiles + (x-1)] +
+             m_videoFlags[(y+1) * m_widthTiles + (x-1)] +
+             m_videoFlags[(y+1) * m_widthTiles +  x   ]);
+        if (n == 3) {
+          *ptr++ = 1;
+          continue;
+        }
+        weightedSum += n;
+      }
+      if (y < m_heightTiles - 1 && x < m_widthTiles - 1) {
+        n = (m_videoFlags[ y    * m_widthTiles + (x+1)] +
+             m_videoFlags[(y+1) * m_widthTiles + (x+1)] +
+             m_videoFlags[(y+1) * m_widthTiles +  x   ]);
+        if (n == 3) {
+          *ptr++ = 1;
+          continue;
+        }
+        weightedSum += n;
+      }
+      *ptr++ = (weightedSum <= 3) ? 0 : m_videoFlags[y * m_widthTiles + x];
+    }
+  }
+
+  /*
+  /// DEBUG: ------------------------------------------------------
+  if (nVideoTiles) {
+    for (y = 0; y < m_heightTiles; y++) {
+      for (x = 0; x < m_widthTiles; x++) {
+        printf("%c", m_videoFlags[y * m_widthTiles + x] ? '@' : ':');
+      }
+      printf("        ");
+      for (x = 0; x < m_widthTiles; x++) {
+        printf("%c", newFlags[y * m_widthTiles + x] ? '@' : ':');
+      }
+      printf("\n");
+    }
+    printf("\n");
+  }
+  /// -------------------------------------------------------------
+  */
+
+  memcpy(m_videoFlags, newFlags, m_widthTiles * m_heightTiles);
+}
