diff --git a/rfb_win32/SDisplay.cxx b/rfb_win32/SDisplay.cxx
new file mode 100644
index 0000000..6fa3ff0
--- /dev/null
+++ b/rfb_win32/SDisplay.cxx
@@ -0,0 +1,612 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  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.
+ */
+
+// -=- SDisplay.cxx
+//
+// The SDisplay class encapsulates a particular system display.
+
+#include <assert.h>
+
+#include <rfb_win32/SDisplay.h>
+#include <rfb_win32/Service.h>
+#include <rfb_win32/WMShatter.h>
+#include <rfb_win32/osVersion.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/IntervalTimer.h>
+#include <rfb_win32/CleanDesktop.h>
+
+#include <rfb/util.h>
+#include <rfb/LogWriter.h>
+#include <rfb/Exception.h>
+
+#include <rfb/Configuration.h>
+
+using namespace rdr;
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("SDisplay");
+
+// - SDisplay-specific configuration options
+
+BoolParameter rfb::win32::SDisplay::use_hooks("UseHooks",
+  "Set hooks in the operating system to capture display updates more efficiently", true);
+BoolParameter rfb::win32::SDisplay::disableLocalInputs("DisableLocalInputs",
+  "Disable local keyboard and pointer input while the server is in use", false);
+StringParameter rfb::win32::SDisplay::disconnectAction("DisconnectAction",
+  "Action to perform when all clients have disconnected.  (None, Lock, Logoff)", "None");
+
+BoolParameter rfb::win32::SDisplay::removeWallpaper("RemoveWallpaper",
+  "Remove the desktop wallpaper when the server in in use.", false);
+BoolParameter rfb::win32::SDisplay::removePattern("RemovePattern",
+  "Remove the desktop background pattern when the server in in use.", false);
+BoolParameter rfb::win32::SDisplay::disableEffects("DisableEffects",
+  "Disable desktop user interface effects when the server is in use.", false);
+
+
+// - WM_TIMER ID values
+
+#define TIMER_CURSOR 1
+#define TIMER_UPDATE 2
+#define TIMER_UPDATE_AND_POLL 3
+
+
+// -=- Polling settings
+
+const int POLLING_SEGMENTS = 16;
+
+const int FG_POLLING_FPS = 20;
+const int FG_POLLING_FS_INTERVAL = 1000 / FG_POLLING_FPS;
+const int FG_POLLING_INTERVAL = FG_POLLING_FS_INTERVAL / POLLING_SEGMENTS;
+
+const int BG_POLLING_FS_INTERVAL = 5000;
+const int BG_POLLING_INTERVAL = BG_POLLING_FS_INTERVAL / POLLING_SEGMENTS;
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// SDisplayCore
+//
+
+// The SDisplay Core object is created by SDisplay's start() method
+// and deleted by its stop() method.
+// The Core must be created in the current input desktop in order
+// to operate - SDisplay is responsible for ensuring that.
+// The structures contained in the Core are manipulated directly
+// by the SDisplay, which is also responsible for detecting when
+// a desktop-switch is required.
+
+class rfb::win32::SDisplayCore : public MsgWindow {
+public:
+  SDisplayCore(SDisplay* display);
+  ~SDisplayCore();
+
+  void setPixelBuffer(DeviceFrameBuffer* pb_);
+
+  bool isRestartRequired();
+
+  virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+  // -=- Timers
+  IntervalTimer pollTimer;
+  IntervalTimer cursorTimer;
+
+  // -=- Input handling
+  rfb::win32::SPointer ptr;
+  rfb::win32::SKeyboard kbd;
+  rfb::win32::Clipboard clipboard;
+
+  // -=- Hook handling objects used outside thread run() method
+  WMCopyRect wm_copyrect;
+  WMPoller wm_poller;
+  WMCursor cursor;
+  WMMonitor wm_monitor;
+  WMHooks wm_hooks;
+  WMBlockInput wm_input;
+
+  // -=- Tidying the desktop
+  CleanDesktop cleanDesktop;
+  bool isWallpaperRemoved;
+  bool isPatternRemoved;
+  bool areEffectsDisabled;
+
+  // -=- Full screen polling
+  int poll_next_y;
+  int poll_y_increment;
+
+  // Are we using hooks?
+  bool use_hooks;
+  bool using_hooks;
+
+  // State of the display object
+  SDisplay* display;
+};
+
+SDisplayCore::SDisplayCore(SDisplay* display_)
+: MsgWindow(_T("SDisplayCore")), display(display_),
+  using_hooks(0), use_hooks(rfb::win32::SDisplay::use_hooks),
+  isWallpaperRemoved(rfb::win32::SDisplay::removeWallpaper),
+  isPatternRemoved(rfb::win32::SDisplay::removePattern),
+  areEffectsDisabled(rfb::win32::SDisplay::disableEffects),
+  pollTimer(getHandle(), TIMER_UPDATE_AND_POLL),
+  cursorTimer(getHandle(), TIMER_CURSOR) {
+  setPixelBuffer(display->pb);
+}
+
+SDisplayCore::~SDisplayCore() {
+}
+
+void SDisplayCore::setPixelBuffer(DeviceFrameBuffer* pb) {
+  poll_y_increment = (display->pb->height()+POLLING_SEGMENTS-1)/POLLING_SEGMENTS;
+  poll_next_y = display->screenRect.tl.y;
+  wm_hooks.setClipRect(display->screenRect);
+  wm_copyrect.setClipRect(display->screenRect);
+  wm_poller.setClipRect(display->screenRect);
+}
+
+
+bool SDisplayCore::isRestartRequired() {
+  // - We must restart the SDesktop if:
+  // 1. We are no longer in the input desktop.
+  // 2. The use_hooks setting has changed.
+
+  // - Check that we are in the input desktop
+  if (rfb::win32::desktopChangeRequired())
+    return true;
+
+  // - Check that the hooks setting hasn't changed
+  // NB: We can't just check using_hooks because that can be false
+  // because they failed, even though use_hooks is true!
+  if (use_hooks != rfb::win32::SDisplay::use_hooks)
+    return true;
+
+  // - Check that the desktop optimisation settings haven't changed
+  //   This isn't very efficient, but it shouldn't change very often!
+  if ((isWallpaperRemoved != rfb::win32::SDisplay::removeWallpaper) ||
+      (isPatternRemoved != rfb::win32::SDisplay::removePattern) ||
+      (areEffectsDisabled != rfb::win32::SDisplay::disableEffects))
+    return true;
+
+  return false;
+}
+
+LRESULT SDisplayCore::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  switch (msg) {
+
+  case WM_TIMER:
+
+    if (display->server && display->server->clientsReadyForUpdate()) {
+
+      // - Check that the SDesktop doesn't need restarting
+      if (isRestartRequired()) {
+        display->restart();
+        return 0;
+      }
+    
+      // - Action depends on the timer message type
+      switch (wParam) {
+
+        // POLL THE SCREEN
+      case TIMER_UPDATE_AND_POLL:
+        // Handle window dragging, polling of consoles, etc.
+        while (wm_poller.processEvent()) {}
+
+        // Poll the next strip of the screen (in Screen coordinates)
+        {
+          Rect pollrect = display->screenRect;
+          if (poll_next_y >= pollrect.br.y) {
+            // Yes.  Reset the counter and return
+            poll_next_y = pollrect.tl.y;
+          } else {
+            // No.  Poll the next section
+            pollrect.tl.y = poll_next_y;
+            poll_next_y += poll_y_increment;
+            pollrect.br.y = min(poll_next_y, pollrect.br.y);
+            display->add_changed(pollrect);
+          }
+        }
+        break;
+
+      case TIMER_CURSOR:
+        display->triggerUpdate();
+        break;
+
+      };
+
+    }
+    return 0;
+
+  };
+
+  return MsgWindow::processMessage(msg, wParam, lParam);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// SDisplay
+//
+
+// -=- Constructor/Destructor
+
+SDisplay::SDisplay(const TCHAR* devName)
+  : server(0), change_tracker(true), pb(0),
+    deviceName(tstrDup(devName)), device(0), releaseDevice(false),
+    core(0), statusLocation(0)
+{
+  updateEvent.h = CreateEvent(0, TRUE, FALSE, 0);
+}
+
+SDisplay::~SDisplay()
+{
+  // XXX when the VNCServer has been deleted with clients active, stop()
+  // doesn't get called - this ought to be fixed in VNCServerST.  In any event,
+  // we should never call any methods on VNCServer once we're being deleted.
+  // This is because it is supposed to be guaranteed that the SDesktop exists
+  // throughout the lifetime of the VNCServer.  So if we're being deleted, then
+  // the VNCServer ought not to exist and therefore we shouldn't invoke any
+  // methods on it.  Setting server to zero here ensures that stop() doesn't
+  // call setPixelBuffer(0) on the server.
+  server = 0;
+  if (core) stop();
+}
+
+
+// -=- SDesktop interface
+
+void SDisplay::start(VNCServer* vs)
+{
+  vlog.debug("starting");
+  server = vs;
+
+  // Switch to the current input desktop
+  // ***
+  if (rfb::win32::desktopChangeRequired()) {
+    if (!rfb::win32::changeDesktop())
+      throw rdr::Exception("unable to switch into input desktop");
+  }
+
+  // Clear the change tracker
+  change_tracker.clear();
+
+  // Create the framebuffer object
+  recreatePixelBuffer();
+
+  // Create the SDisplayCore
+  core = new SDisplayCore(this);
+  assert(core);
+
+  // Start display monitor and clipboard handler
+  core->wm_monitor.setNotifier(this);
+  core->clipboard.setNotifier(this);
+
+  // Apply desktop optimisations
+  if (removePattern)
+    core->cleanDesktop.disablePattern();
+  if (removeWallpaper)
+    core->cleanDesktop.disableWallpaper();
+  if (disableEffects)
+    core->cleanDesktop.disableEffects();
+
+  // Start hooks
+  core->wm_hooks.setClipRect(screenRect);
+  if (core->use_hooks) {
+    // core->wm_hooks.setDiagnosticRange(0, 0x400-1);
+    core->using_hooks = core->wm_hooks.setUpdateTracker(this);
+    if (!core->using_hooks)
+      vlog.debug("hook subsystem failed to initialise");
+  }
+
+  // Set up timers
+  core->pollTimer.start(core->using_hooks ? BG_POLLING_INTERVAL : FG_POLLING_INTERVAL);
+  core->cursorTimer.start(10);
+
+  // Register an interest in faked copyrect events
+  core->wm_copyrect.setUpdateTracker(&change_tracker);
+  core->wm_copyrect.setClipRect(screenRect);
+
+  // Polling of particular windows on the desktop
+  core->wm_poller.setUpdateTracker(&change_tracker);
+  core->wm_poller.setClipRect(screenRect);
+
+  vlog.debug("started");
+
+  if (statusLocation) *statusLocation = true;
+}
+
+void SDisplay::stop()
+{
+  vlog.debug("stopping");
+  if (core) {
+    // If SDisplay was actually active then perform the disconnect action
+    CharArray action = disconnectAction.getData();
+    if (stricmp(action.buf, "Logoff") == 0) {
+      ExitWindowsEx(EWX_LOGOFF, 0);
+    } else if (stricmp(action.buf, "Lock") == 0) {
+      typedef BOOL (WINAPI *_LockWorkStation_proto)();
+      DynamicFn<_LockWorkStation_proto> _LockWorkStation(_T("user32.dll"), "LockWorkStation");
+      if (_LockWorkStation.isValid())
+        (*_LockWorkStation)();
+      else
+        ExitWindowsEx(EWX_LOGOFF, 0);
+    }
+  }
+  delete core;
+  core = 0;
+  delete pb;
+  pb = 0;
+  if (device) {
+    if (releaseDevice)
+      ReleaseDC(0, device);
+    else
+      DeleteDC(device);
+  }
+  device = 0;
+  if (server)
+    server->setPixelBuffer(0);
+
+  server = 0;
+  vlog.debug("stopped");
+
+  if (statusLocation) *statusLocation = false;
+}
+
+void SDisplay::restart() {
+  vlog.debug("restarting");
+  // Close down the hooks
+  delete core;
+  core = 0;
+  try {
+    // Re-start the hooks if possible
+    start(server);
+    vlog.debug("restarted");
+  } catch (rdr::Exception& e) {
+    // If start() fails then we MUST disconnect all clients,
+    // to cause the server to stop using the desktop.
+    // Otherwise, the SDesktop is in an inconsistent state
+    // and the server will crash
+    server->closeClients(e.str());
+  }
+}
+
+
+void SDisplay::pointerEvent(const Point& pos, rdr::U8 buttonmask) {
+  if (pb->getRect().contains(pos)) {
+    Point screenPos = pos.translate(screenRect.tl);
+    core->ptr.pointerEvent(screenPos, buttonmask);
+  }
+}
+
+void SDisplay::keyEvent(rdr::U32 key, bool down) {
+  core->kbd.keyEvent(key, down);
+}
+
+void SDisplay::clientCutText(const char* text, int len) {
+  CharArray clip_sz(len+1);
+  memcpy(clip_sz.buf, text, len);
+  clip_sz.buf[len] = 0;
+  core->clipboard.setClipText(clip_sz.buf);
+}
+
+
+void SDisplay::framebufferUpdateRequest()
+{
+  triggerUpdate();
+}
+
+Point SDisplay::getFbSize() {
+  bool startAndStop = !core;
+  // If not started, do minimal initialisation to get desktop size.
+  if (startAndStop) recreatePixelBuffer();
+  Point result = Point(pb->width(), pb->height());
+  // Destroy the initialised structures.
+  if (startAndStop) stop();
+  return result;
+}
+
+
+void
+SDisplay::add_changed(const Region& rgn) {
+  change_tracker.add_changed(rgn);
+  triggerUpdate();
+}
+
+void
+SDisplay::add_copied(const Region& dest, const Point& delta) {
+  change_tracker.add_copied(dest, delta);
+  triggerUpdate();
+}
+
+
+void
+SDisplay::notifyClipboardChanged(const char* text, int len) {
+  vlog.debug("clipboard text changed");
+  if (server)
+    server->serverCutText(text, len);
+}
+
+
+void
+SDisplay::notifyDisplayEvent(WMMonitor::Notifier::DisplayEventType evt) {
+  switch (evt) {
+  case WMMonitor::Notifier::DisplaySizeChanged:
+    vlog.debug("desktop size changed");
+    recreatePixelBuffer();
+    break;
+  case WMMonitor::Notifier::DisplayPixelFormatChanged:
+    vlog.debug("desktop format changed");
+    recreatePixelBuffer();
+    break;
+  case WMMonitor::Notifier::DisplayColourMapChanged:
+    vlog.debug("desktop colourmap changed");
+    pb->updateColourMap();
+    if (server)
+      server->setColourMapEntries();
+    break;
+  default:
+    vlog.error("unknown display event received");
+  }
+}
+
+bool
+SDisplay::processEvent(HANDLE event) {
+  if (event == updateEvent) {
+    vlog.info("processEvent");
+    ResetEvent(updateEvent);
+
+    // - If the SDisplay isn't even started then quit now
+    if (!core) {
+      vlog.error("not start()ed");
+      return true;
+    }
+
+    // - Ensure that the disableLocalInputs flag is respected
+    core->wm_input.blockInputs(SDisplay::disableLocalInputs);
+
+    // - Only process updates if the server is ready
+    if (server && server->clientsReadyForUpdate()) {
+      bool try_update = false;
+
+      // - Check that the SDesktop doesn't need restarting
+      if (core->isRestartRequired()) {
+        restart();
+        return true;
+      }
+    
+      // *** window dragging can be improved - more frequent, more cunning about updates
+      while (core->wm_copyrect.processEvent()) {}
+        
+      // Ensure the cursor is up to date
+      WMCursor::Info info = core->cursor.getCursorInfo();
+      if (old_cursor != info) {
+        // Update the cursor shape if the visibility has changed
+        bool set_cursor = info.visible != old_cursor.visible;
+        // OR if the cursor is visible and the shape has changed.
+        set_cursor |= info.visible && (old_cursor.cursor != info.cursor);
+
+        // Update the cursor shape
+        if (set_cursor)
+          pb->setCursor(info.visible ? info.cursor : 0, server);
+
+        // Update the cursor position
+        // NB: First translate from Screen coordinates to Desktop
+        Point desktopPos = info.position.translate(screenRect.tl.negate());
+        server->setCursorPos(desktopPos.x, desktopPos.y);
+        try_update = true;
+
+        old_cursor = info;
+      }
+
+      // Flush any changes to the server
+      try_update = flushChangeTracker() || try_update;
+      if (try_update)
+        server->tryUpdate();
+    }
+  } else {
+    CloseHandle(event);
+    return false;
+  }
+  return true;
+}
+
+
+// -=- Protected methods
+
+void
+SDisplay::recreatePixelBuffer() {
+  vlog.debug("attaching to device %s", deviceName);
+
+  // Open the specified display device
+  HDC new_device;
+  if (deviceName.buf) {
+    new_device = ::CreateDC(_T("DISPLAY"), deviceName.buf, NULL, NULL);
+    releaseDevice = false;
+  } else {
+    // If no device is specified, open entire screen.
+    // Doing this with CreateDC creates problems on multi-monitor systems.
+    new_device = ::GetDC(0);
+    releaseDevice = true;
+  }
+  if (!new_device)
+    throw SystemException("cannot open the display", GetLastError());
+
+  // Get the coordinates of the entire virtual display
+  Rect newScreenRect;
+  {
+    WindowDC rootDC(0);
+    RECT r;
+    if (!GetClipBox(rootDC, &r))
+      throw rdr::SystemException("GetClipBox", GetLastError());
+    newScreenRect = Rect(r.left, r.top, r.right, r.bottom);
+  }
+
+  // Create a DeviceFrameBuffer attached to it
+  DeviceFrameBuffer* new_buffer = new DeviceFrameBuffer(new_device);
+
+  // Has anything actually changed about the screen or the buffer?
+  if (!pb ||
+      (!newScreenRect.equals(screenRect)) ||
+      (!new_buffer->getPF().equal(pb->getPF())))
+  {
+    // Yes.  Update the buffer state.
+    screenRect = newScreenRect;
+    vlog.debug("creating pixel buffer for device");
+
+    // Flush any existing changes to the server
+    flushChangeTracker();
+
+    // Replace the old PixelBuffer
+    if (pb) delete pb;
+    if (device) DeleteDC(device);
+    pb = new_buffer;
+    device = new_device;
+
+    // Initialise the pixels
+    pb->grabRegion(pb->getRect());
+
+    // Prevent future grabRect operations from throwing exceptions
+    pb->setIgnoreGrabErrors(true);
+
+    // Update the SDisplayCore if required
+    if (core)
+      core->setPixelBuffer(pb);
+
+    // Inform the server of the changes
+    if (server)
+      server->setPixelBuffer(pb);
+
+  } else {
+    delete new_buffer;
+    DeleteDC(new_device);
+  }
+}
+
+bool SDisplay::flushChangeTracker() {
+  if (change_tracker.is_empty())
+    return false;
+  // Translate the update coordinates from Screen coords to Desktop
+  change_tracker.translate(screenRect.tl.negate());
+  // Flush the updates through
+  change_tracker.get_update(*server);
+  change_tracker.clear();
+  return true;
+}
+
+void SDisplay::triggerUpdate() {
+  if (core)
+    SetEvent(updateEvent);
+}
