diff --git a/rfb_win32/AboutDialog.cxx b/rfb_win32/AboutDialog.cxx
new file mode 100644
index 0000000..efb15c0
--- /dev/null
+++ b/rfb_win32/AboutDialog.cxx
@@ -0,0 +1,49 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+#include <rfb_win32/AboutDialog.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/TCharArray.h>
+#include <rfb/LogWriter.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("AboutDialog");
+
+AboutDialog AboutDialog::instance;
+
+
+AboutDialog::AboutDialog() : Dialog(GetModuleHandle(0)) {
+}
+
+bool AboutDialog::showDialog() {
+  return Dialog::showDialog(MAKEINTRESOURCE(DialogId));
+}
+
+void AboutDialog::initDialog() {
+  // Set the build time field
+  SetWindowText(GetDlgItem(handle, BuildTime), TStr(buildTime));
+
+  // Get our executable's version info
+  FileVersionInfo verInfo;
+
+  SetWindowText(GetDlgItem(handle, Version), verInfo.getVerString(_T("FileVersion")));
+  SetWindowText(GetDlgItem(handle, Copyright), verInfo.getVerString(_T("LegalCopyright")));
+  SetWindowText(GetDlgItem(handle, Description), verInfo.getVerString(_T("FileDescription")));
+}
diff --git a/rfb_win32/AboutDialog.h b/rfb_win32/AboutDialog.h
new file mode 100644
index 0000000..cb1713d
--- /dev/null
+++ b/rfb_win32/AboutDialog.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- AboutDialog.h
+
+#ifndef __RFB_WIN32_ABOUT_DIALOG_H__
+#define __RFB_WIN32_ABOUT_DIALOG_H__
+
+#include <rfb_win32/Dialog.h>
+#include <rfb/util.h>
+
+extern const char* buildTime;
+
+namespace rfb {
+
+  namespace win32 {
+
+    class AboutDialog : Dialog {
+    public:
+      AboutDialog();
+      virtual bool showDialog();
+      virtual void initDialog();
+
+      static AboutDialog instance;
+
+      typedef WORD LabelId;
+      static const LabelId DialogId;    // Resource ID of the About dialog
+      static const LabelId BuildTime;   // Resource ID of the BuildTime label in the dialog
+      static const LabelId Version;     // etc...
+      static const LabelId Copyright;
+      static const LabelId Description;
+    protected:
+      WORD dialogId;
+    };
+
+  };
+
+};
+
+#endif
diff --git a/rfb_win32/CKeyboard.cxx b/rfb_win32/CKeyboard.cxx
new file mode 100644
index 0000000..ad852a0
--- /dev/null
+++ b/rfb_win32/CKeyboard.cxx
@@ -0,0 +1,259 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+#include <map>
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_CURRENCY
+#include <rfb/keysymdef.h>
+
+#include <rfb_win32/CKeyboard.h>
+#include <rfb/CMsgWriter.h>
+#include <rfb/LogWriter.h>
+#include <rfb_win32/OSVersion.h>
+#include "keymap.h"
+
+using namespace rfb;
+
+static LogWriter vlog("CKeyboard");
+
+
+// Client-side RFB keyboard event sythesis
+
+class CKeymapper {
+
+public:
+  CKeymapper()
+  {
+    for (int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) {
+      int extendedVkey = keymap[i].vk + (keymap[i].extended ? 256 : 0);
+      if (keysymMap.find(extendedVkey) == keysymMap.end()) {
+        keysymMap[extendedVkey] = keymap[i].keysym;
+      }
+    }
+  }
+
+  // lookup() tries to find a match for vkey with the extended flag.  We check
+  // first for an exact match including the extended flag, then try without the
+  // extended flag.
+  rdr::U32 lookup(int extendedVkey) {
+    if (keysymMap.find(extendedVkey) != keysymMap.end())
+      return keysymMap[extendedVkey];
+    if (keysymMap.find(extendedVkey ^ 256) != keysymMap.end())
+      return keysymMap[extendedVkey ^ 256];
+    return 0;
+  }
+
+private:
+  std::map<int,rdr::U32> keysymMap;
+} ckeymapper;
+
+
+class ModifierKeyReleaser {
+public:
+  ModifierKeyReleaser(CMsgWriter* writer_, int vkCode, bool extended)
+    : writer(writer_), extendedVkey(vkCode + (extended ? 256 : 0)),
+      keysym(0)
+  {}
+  void release(std::map<int,rdr::U32>* downKeysym) {
+    if (downKeysym->find(extendedVkey) != downKeysym->end()) {
+      keysym = (*downKeysym)[extendedVkey];
+      vlog.debug("fake release extendedVkey 0x%x, keysym 0x%x",
+                 extendedVkey, keysym);
+      writer->writeKeyEvent(keysym, false);
+    }
+  }
+  ~ModifierKeyReleaser() {
+    if (keysym) {
+      vlog.debug("fake press extendedVkey 0x%x, keysym 0x%x",
+                 extendedVkey, keysym);
+      writer->writeKeyEvent(keysym, true);
+    }
+  }
+  CMsgWriter* writer;
+  int extendedVkey;
+  rdr::U32 keysym;
+};
+
+// IS_PRINTABLE_LATIN1 tests if a character is either a printable latin1
+// character, or 128, which is the Euro symbol on Windows.
+#define IS_PRINTABLE_LATIN1(c) (((c) >= 32 && (c) <= 126) || (c) == 128 || \
+                                ((c) >= 160 && (c) <= 255))
+
+void win32::CKeyboard::keyEvent(CMsgWriter* writer, rdr::U8 vkey,
+                                rdr::U32 flags, bool down)
+{
+  bool extended = (flags & 0x1000000);
+  int extendedVkey = vkey + (extended ? 256 : 0);
+
+  // If it's a release, just release whichever keysym corresponded to the same
+  // key being pressed, regardless of how it would be interpreted in the
+  // current keyboard state.
+  if (!down) {
+    releaseKey(writer, extendedVkey);
+    return;
+  }
+
+  // We should always pass every down event to ToAscii() otherwise it can get
+  // out of sync.
+
+  // XXX should we pass CapsLock, ScrollLock or NumLock to ToAscii - they
+  // actually alter the lock state on the keyboard?
+
+  BYTE keystate[256];
+  GetKeyboardState(keystate);
+  rdr::U8 chars[2];
+
+  int nchars = ToAscii(vkey, 0, keystate, (WORD*)&chars, 0);
+
+  // See if it's in the Windows VK code -> X keysym map.  We do this before
+  // looking at the result of ToAscii so that e.g. we recognise that it's
+  // XK_KP_Add rather than '+'.
+
+  rdr::U32 keysym = ckeymapper.lookup(extendedVkey);
+  if (keysym) {
+    vlog.debug("mapped key: extendedVkey 0x%x", extendedVkey);
+    pressKey(writer, extendedVkey, keysym);
+    return;
+  }
+
+  if (nchars < 0) {
+    // Dead key - the next call to ToAscii() will give us either the accented
+    // character or two characters.
+    vlog.debug("ToAscii dead key (1): extendedVkey 0x%x", extendedVkey);
+    return;
+  }
+
+  if (nchars > 0 && IS_PRINTABLE_LATIN1(chars[0])) {
+    // Got a printable latin1 character.  We must release Control and Alt
+    // (AltGr) if they were both pressed, so that the latin1 character is seen
+    // without them by the VNC server.
+    ModifierKeyReleaser lctrl(writer, VK_CONTROL, 0);
+    ModifierKeyReleaser rctrl(writer, VK_CONTROL, 1);
+    ModifierKeyReleaser lalt(writer, VK_MENU, 0);
+    ModifierKeyReleaser ralt(writer, VK_MENU, 1);
+
+    if ((keystate[VK_CONTROL] & 0x80) && (keystate[VK_MENU] & 0x80)) {
+      lctrl.release(&downKeysym);
+      rctrl.release(&downKeysym);
+      lalt.release(&downKeysym);
+      ralt.release(&downKeysym);
+    }
+
+    for (int i = 0; i < nchars; i++) {
+      vlog.debug("ToAscii key (1): extendedVkey 0x%x", extendedVkey);
+      if (chars[i] == 128) { // special hack for euro!
+        pressKey(writer, extendedVkey, XK_EuroSign);
+      } else {
+        pressKey(writer, extendedVkey, chars[i]);
+      }
+    }
+    return;
+  }
+
+  // Either no chars were generated, or something outside the printable
+  // character range.  Try ToAscii() without the Control and Alt keys down to
+  // see if that yields an ordinary character.
+
+  keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
+  keystate[VK_MENU] = keystate[VK_LMENU] = keystate[VK_RMENU] = 0;
+
+  nchars = ToAscii(vkey, 0, keystate, (WORD*)&chars, 0);
+
+  if (nchars < 0) {
+    // So it would be a dead key if neither control nor alt were pressed.
+    // However, we know that at least one of control and alt must be pressed.
+    // We can't leave it at this stage otherwise the next call to ToAscii()
+    // with a valid character will get wrongly interpreted in the context of
+    // this bogus dead key.  Working on the assumption that a dead key followed
+    // by space usually returns the dead character itself, try calling ToAscii
+    // with VK_SPACE.
+    vlog.debug("ToAscii dead key (2): extendedVkey 0x%x", extendedVkey);
+    nchars = ToAscii(VK_SPACE, 0, keystate, (WORD*)&chars, 0);
+    if (nchars < 0) {
+      vlog.debug("ToAscii dead key (3): extendedVkey 0x%x - giving up!",
+                 extendedVkey);
+      return;
+    }
+  }
+
+  if (nchars > 0 && IS_PRINTABLE_LATIN1(chars[0])) {
+    for (int i = 0; i < nchars; i++) {
+      vlog.debug("ToAscii key (2) (no ctrl/alt): extendedVkey 0x%x",
+                 extendedVkey);
+      if (chars[i] == 128) { // special hack for euro!
+        pressKey(writer, extendedVkey, XK_EuroSign);
+      } else {
+        pressKey(writer, extendedVkey, chars[i]);
+      }
+    }
+    return;
+  }
+
+  vlog.debug("no chars regardless of control and alt: extendedVkey 0x%x",
+             extendedVkey);
+}
+
+// releaseAllKeys() - write key release events to the server for all keys
+// that are currently regarded as being down.
+void win32::CKeyboard::releaseAllKeys(CMsgWriter* writer) {
+  std::map<int,rdr::U32>::iterator i, next_i;
+  for (i=downKeysym.begin(); i!=downKeysym.end(); i=next_i) {
+    next_i = i; next_i++;
+    writer->writeKeyEvent((*i).second, false);
+    downKeysym.erase(i);
+  }
+}
+
+// releaseKey() - write a key up event to the server, but only if we've
+// actually sent a key down event for the given key.  The key up event always
+// contains the same keysym we used in the key down event, regardless of what
+// it would look up as using the current keyboard state.
+void win32::CKeyboard::releaseKey(CMsgWriter* writer, int extendedVkey)
+{
+  if (downKeysym.find(extendedVkey) != downKeysym.end()) {
+    vlog.debug("release extendedVkey 0x%x, keysym 0x%x",
+               extendedVkey, downKeysym[extendedVkey]);
+    writer->writeKeyEvent(downKeysym[extendedVkey], false);
+    downKeysym.erase(extendedVkey);
+  }
+}
+
+// pressKey() - write a key down event to the server, and record which keysym
+// was sent as corresponding to the given extendedVkey.  The only tricky bit is
+// that if we are trying to press an extendedVkey which is already marked as
+// down but with a different keysym, then we need to release the old keysym
+// first.  This can happen in two cases: (a) when a single key press results in
+// more than one character, and (b) when shift is released while another key is
+// autorepeating.
+void win32::CKeyboard::pressKey(CMsgWriter* writer, int extendedVkey,
+                                rdr::U32 keysym)
+{
+  if (downKeysym.find(extendedVkey) != downKeysym.end()) {
+    if (downKeysym[extendedVkey] != keysym) {
+      vlog.debug("release extendedVkey 0x%x, keysym 0x%x",
+                 extendedVkey, downKeysym[extendedVkey]);
+      writer->writeKeyEvent(downKeysym[extendedVkey], false);
+    }
+  }
+  vlog.debug("press   extendedVkey 0x%x, keysym 0x%x",
+             extendedVkey, keysym);
+  writer->writeKeyEvent(keysym, true);
+  downKeysym[extendedVkey] = keysym;
+}
diff --git a/rfb_win32/CKeyboard.h b/rfb_win32/CKeyboard.h
new file mode 100644
index 0000000..10346ff
--- /dev/null
+++ b/rfb_win32/CKeyboard.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- CKeyboard.h
+//
+// Client-side keyboard handling for Win32
+
+#ifndef __RFB_WIN32_CKEYBOARD_H__
+#define __RFB_WIN32_CKEYBOARD_H__
+
+#include <rdr/types.h>
+#include <map>
+
+namespace rfb {
+
+  class CMsgWriter;
+
+  namespace win32 {
+
+    class CKeyboard {
+    public:
+      void keyEvent(CMsgWriter* writer, rdr::U8 vkey, rdr::U32 flags,
+                    bool down);
+      void releaseAllKeys(CMsgWriter* writer);
+      const std::map<int,rdr::U32>& pressedKeys() const {return downKeysym;};
+      bool keyPressed(int k) const {return downKeysym.find(k)!=downKeysym.end();}
+    private:
+      void win32::CKeyboard::releaseKey(CMsgWriter* writer, int extendedVkey);
+      void win32::CKeyboard::pressKey(CMsgWriter* writer, int extendedVkey,
+                                      rdr::U32 keysym);
+      std::map<int,rdr::U32> downKeysym;
+    };
+
+  }; // win32
+
+}; // rfb
+
+#endif // __RFB_WIN32_CKEYBOARD_H__
diff --git a/rfb_win32/CPointer.cxx b/rfb_win32/CPointer.cxx
new file mode 100644
index 0000000..1cab662
--- /dev/null
+++ b/rfb_win32/CPointer.cxx
@@ -0,0 +1,188 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb/LogWriter.h>
+#include <rfb_win32/CPointer.h>
+
+using namespace rfb;
+using namespace win32;
+
+static LogWriter vlog("CPointer");
+
+
+CPointer::CPointer() : currButtonMask(0), intervalQueued(false), threeEmulating(false) {
+}
+
+CPointer::~CPointer() {
+  intervalTimer.stop();
+  threeTimer.stop();
+}
+
+
+void CPointer::pointerEvent(CMsgWriter* writer, int x, int y, int buttonMask) {
+  //
+  // - Duplicate Event Filtering
+  //
+
+  bool maskChanged = buttonMask != currButtonMask;
+  bool posChanged = !Point(x, y).equals(currPos);
+  if (!(posChanged || maskChanged))
+    return;
+
+  // Pass on the event to the event-interval handler
+  threePointerEvent(writer, x, y, buttonMask);
+
+  // Save the position and mask
+  currPos = Point(x, y);
+  currButtonMask = buttonMask;
+}
+
+
+inline abs(int x) {return x>0 ? x : 0;}
+
+int emulate3Mask(int buttonMask) {
+  // - Release left & right and press middle
+  vlog.debug("emulate3: active");
+  buttonMask &= ~5;
+  buttonMask |= 2;
+  return buttonMask;
+}
+
+void CPointer::threePointerEvent(CMsgWriter* writer, int x, int y, int buttonMask) {
+  //
+  // - 3-Button Mouse Emulation
+  //
+
+  if (emulate3) {
+
+    bool leftChanged = (buttonMask & 1) != (currButtonMask & 1);
+    bool rightChanged = (buttonMask & 4) != (currButtonMask & 4);
+
+    if (leftChanged || rightChanged) {
+      // - One of left or right have changed
+
+      if ((buttonMask & 5) == 1 || (buttonMask & 5) == 4) {
+        // - One is up, one is down.  Start a timer, so that if it
+        //   expires then we know we should actually send this event
+        vlog.debug("emulate3: start timer");
+        threeTimer.start(100);
+        threePos = Point(x, y);
+        threeMask = buttonMask;
+        return;
+
+      } else if (threeTimer.isActive()) {
+        // - Both are up or both are down, and we were timing for an emulation event
+        //   Stop the timer and flush the stored event
+        vlog.debug("emulate3: stop timer (state)");
+        threeTimer.stop();
+        if (threeEmulating == ((buttonMask & 5) == 5))
+          intervalPointerEvent(writer, threePos.x, threePos.y, threeMask);
+        else
+          threeEmulating = ((buttonMask & 5) == 5);
+      }
+
+    } else {
+    
+      if (threeTimer.isActive()) {
+        // - We are timing for an emulation event
+
+        if (abs(threePos.x - x) <= 4 || abs(threePos.y - y) <= 4) {
+          //   If the mouse has moved too far since the button-change event then flush
+          vlog.debug("emulate3: stop timer (moved)");
+          threeTimer.stop();
+          intervalPointerEvent(writer, threePos.x, threePos.y, threeMask);
+
+        } else {
+          //   Otherwise, we ignore the new event
+          return;
+        }
+      }
+
+    }
+
+    // - If neither left nor right are down, stop emulating
+    if ((buttonMask & 5) == 0)
+      threeEmulating = false;
+
+    // - If emulating, release left & right and press middle
+    if (threeEmulating)
+      buttonMask = emulate3Mask(buttonMask);
+
+  }
+
+  // - Let the event pass through to the next stage of processing
+  intervalPointerEvent(writer, x, y, buttonMask);
+}
+
+void CPointer::intervalPointerEvent(CMsgWriter* writer, int x, int y, int buttonMask) {
+  //
+  // - Pointer Event Interval
+  //
+  vlog.write(101, "ptrEvent: %d,%d (%lx)", x, y, buttonMask);
+
+  // Send the event immediately if we haven't sent one for a while
+  bool sendNow = !intervalTimer.isActive();
+
+  if (intervalMask != buttonMask) {
+    // If the buttons have changed then flush queued events and send now
+    sendNow = true;
+    if (intervalQueued)
+      writer->writePointerEvent(intervalPos.x, intervalPos.y, intervalMask);
+    intervalQueued = false;
+  }
+
+  if (!sendNow) {
+    // If we're not sending now then just queue the event
+    intervalQueued = true;
+    intervalPos = Point(x, y);
+    intervalMask = buttonMask;
+  } else {
+    // Start the interval timer if required, and send the event
+    intervalQueued = false;
+    intervalMask = buttonMask;
+    if (pointerEventInterval)
+      intervalTimer.start(pointerEventInterval);
+    writer->writePointerEvent(x, y, buttonMask);
+  }
+}
+
+void CPointer::handleTimer(CMsgWriter* writer, int timerId) {
+  if (timerId == intervalTimer.getId()) {
+    // Pointer interval has expired - send any queued events
+    if (intervalQueued) {
+      writer->writePointerEvent(intervalPos.x, intervalPos.y, intervalMask);
+      intervalQueued = false;
+    } else {
+      intervalTimer.stop();
+    }
+
+  } else if (timerId = threeTimer.getId()) {
+    // 3-Button emulation timer has expired - send what we've got
+    vlog.debug("emulate3: timeout");
+    threeTimer.stop();
+
+    // If emulating, release left & right and press middle
+    if (threeEmulating)
+      threeMask = emulate3Mask(threeMask);
+
+    intervalPointerEvent(writer, threePos.x, threePos.y, threeMask);
+  }
+}
diff --git a/rfb_win32/CPointer.h b/rfb_win32/CPointer.h
new file mode 100644
index 0000000..f111de7
--- /dev/null
+++ b/rfb_win32/CPointer.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- CPointer.h
+//
+// Client-side pointer event handling for Win32
+
+#ifndef __RFB_WIN32_CPOINTER_H__
+#define __RFB_WIN32_CPOINTER_H__
+
+#include <rdr/Exception.h>
+#include <rfb/Configuration.h>
+#include <rfb/CMsgWriter.h>
+#include <rfb/Rect.h>
+#include <rfb_win32/IntervalTimer.h>
+
+namespace rfb {
+
+  class CMsgWriter;
+
+  namespace win32 {
+
+    class CPointer {
+    public:
+      CPointer();
+      ~CPointer();
+
+      void pointerEvent(CMsgWriter* writer, int x, int y, int buttonMask);
+      void handleTimer(CMsgWriter* writer, int timerId);
+
+      void setHWND(HWND w) {intervalTimer.setHWND(w); threeTimer.setHWND(w);}
+      void setIntervalTimerId(int id) {intervalTimer.setId(id);}
+      void set3ButtonTimerId(int id) {threeTimer.setId(id);}
+
+      void enableEmulate3(bool enable) {emulate3 = enable;}
+      void enableInterval(int millis) {pointerEventInterval = millis;}
+    private:
+      Point currPos;
+      int currButtonMask;
+
+      bool emulate3;
+      int pointerEventInterval;
+
+      void intervalPointerEvent(CMsgWriter* writer, int x, int y, int buttonMask);
+      IntervalTimer intervalTimer;
+      bool intervalQueued;
+      Point intervalPos;
+      int intervalMask;
+
+      void threePointerEvent(CMsgWriter* writer, int x, int y, int buttonMask);
+      IntervalTimer threeTimer;
+      Point threePos;
+      int threeMask;
+      bool threeEmulating;
+    };
+
+  }; // win32
+
+}; // rfb
+
+#endif // __RFB_WIN32_CPOINTER_H__
diff --git a/rfb_win32/CleanDesktop.cxx b/rfb_win32/CleanDesktop.cxx
new file mode 100644
index 0000000..9fb8347
--- /dev/null
+++ b/rfb_win32/CleanDesktop.cxx
@@ -0,0 +1,255 @@
+/* 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.
+ */
+
+// -=- CleanDesktop.cxx
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <wininet.h>
+#include <shlobj.h>
+
+#include <rfb_win32/CleanDesktop.h>
+#include <rfb_win32/CurrentUser.h>
+#include <rfb_win32/Registry.h>
+#include <rfb/LogWriter.h>
+#include <rdr/Exception.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("CleanDesktop");
+
+
+struct ActiveDesktop {
+  ActiveDesktop() : handle(0) {
+    // - Contact Active Desktop
+    HRESULT result = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
+                                      IID_IActiveDesktop, (PVOID*)&handle);
+    if (result != S_OK)
+      throw rdr::SystemException("failed to contact Active Desktop", result);
+  }
+  ~ActiveDesktop() {
+    if (handle)
+      handle->Release();
+  }
+  bool enable(bool enable_) {
+    // - Get the current Active Desktop options
+    COMPONENTSOPT adOptions;
+    memset(&adOptions, 0, sizeof(adOptions));
+    adOptions.dwSize = sizeof(adOptions);
+
+    HRESULT result = handle->GetDesktopItemOptions(&adOptions, 0);
+    if (result != S_OK) {
+      vlog.error("failed to get Active Desktop options: %d", result);
+      return false;
+    }
+
+    // - If Active Desktop is active, disable it
+    if ((adOptions.fActiveDesktop==0) != (enable_==0)) {
+      if (enable_)
+        vlog.debug("enabling Active Desktop");
+      else
+        vlog.debug("disabling Active Desktop");
+
+      adOptions.fActiveDesktop = enable_;
+      result = handle->SetDesktopItemOptions(&adOptions, 0);
+      if (result != S_OK) {
+        vlog.error("failed to disable ActiveDesktop: %d", result);
+        return false;
+      }
+      handle->ApplyChanges(AD_APPLY_REFRESH);
+      return true;
+    }
+    return false;
+  }
+  IActiveDesktop* handle;
+};
+
+
+DWORD SysParamsInfo(UINT action, UINT param, PVOID ptr, UINT ini) {
+  DWORD r = ERROR_SUCCESS;
+  if (!SystemParametersInfo(action, param, ptr, ini)) {
+    r = GetLastError();
+    vlog.info("SPI error: %d", r);
+  }
+  return r;
+}
+
+
+CleanDesktop::CleanDesktop() : restoreActiveDesktop(false), restoreWallpaper(false), restoreEffects(false) {
+  CoInitialize(0);
+}
+
+CleanDesktop::~CleanDesktop() {
+  enableEffects();
+  enablePattern();
+  enableWallpaper();
+  CoUninitialize();
+}
+
+void CleanDesktop::disableWallpaper() {
+  try {
+    ImpersonateCurrentUser icu;
+
+    vlog.debug("disable desktop wallpaper/Active Desktop");
+
+    // -=- First attempt to remove the wallpaper using Active Desktop
+    try {
+      ActiveDesktop ad;
+      if (ad.enable(false))
+        restoreActiveDesktop = true;
+    } catch (rdr::Exception& e) {
+      vlog.error(e.str());
+    }
+
+    // -=- Switch of normal wallpaper and notify apps
+    SysParamsInfo(SPI_SETDESKWALLPAPER, 0, "", SPIF_SENDCHANGE);
+    restoreWallpaper = true;
+
+  } catch (rdr::Exception& e) {
+    vlog.info(e.str());
+  }
+}
+
+void CleanDesktop::enableWallpaper() {
+  try {
+    ImpersonateCurrentUser icu;
+
+    if (restoreActiveDesktop) {
+      vlog.debug("restore Active Desktop");
+
+      // -=- First attempt to re-enable Active Desktop
+      try {
+        ActiveDesktop ad;
+        ad.enable(true);
+        restoreActiveDesktop = false;
+      } catch (rdr::Exception& e) {
+        vlog.error(e.str());
+      }
+    }
+
+    if (restoreWallpaper) {
+      vlog.debug("restore desktop wallpaper");
+
+      // -=- Then restore the standard wallpaper if required
+	    SysParamsInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
+      restoreWallpaper = false;
+    }
+
+  } catch (rdr::Exception& e) {
+    vlog.info(e.str());
+  }
+}
+
+
+void CleanDesktop::disablePattern() {
+  try {
+    ImpersonateCurrentUser icu;
+
+    vlog.debug("disable desktop pattern");
+    SysParamsInfo(SPI_SETDESKPATTERN, 0, "", SPIF_SENDCHANGE);
+    restorePattern = true;
+
+  } catch (rdr::Exception& e) {
+    vlog.info(e.str());
+  }
+}
+
+void CleanDesktop::enablePattern() {
+  try {
+    if (restorePattern) {
+      ImpersonateCurrentUser icu;
+
+      vlog.debug("restoring pattern...");
+
+      TCharArray pattern;
+      if (osVersion.isPlatformWindows) {
+        RegKey cfgKey;
+        cfgKey.openKey(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"));
+        pattern.buf = cfgKey.getString(_T("Pattern"));
+      }
+      SysParamsInfo(SPI_SETDESKPATTERN, 0, pattern.buf, SPIF_SENDCHANGE);
+      restorePattern = false;
+    }
+
+  } catch (rdr::Exception& e) {
+    vlog.info(e.str());
+  }
+}
+
+
+void CleanDesktop::disableEffects() {
+#if (WINVER >= 0x500)
+  try {
+    ImpersonateCurrentUser icu;
+
+    vlog.debug("disable desktop effects");
+
+    SysParamsInfo(SPI_SETFONTSMOOTHING, FALSE, 0, SPIF_SENDCHANGE);
+    if (SysParamsInfo(SPI_GETUIEFFECTS, 0, &uiEffects, 0) == ERROR_CALL_NOT_IMPLEMENTED) {
+      SysParamsInfo(SPI_GETCOMBOBOXANIMATION, 0, &comboBoxAnim, 0);
+      SysParamsInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradientCaptions, 0);
+      SysParamsInfo(SPI_GETHOTTRACKING, 0, &hotTracking, 0);
+      SysParamsInfo(SPI_GETLISTBOXSMOOTHSCROLLING, 0, &listBoxSmoothScroll, 0);
+      SysParamsInfo(SPI_GETMENUANIMATION, 0, &menuAnim, 0);
+      SysParamsInfo(SPI_SETCOMBOBOXANIMATION, 0, FALSE, SPIF_SENDCHANGE);
+      SysParamsInfo(SPI_SETGRADIENTCAPTIONS, 0, FALSE, SPIF_SENDCHANGE);
+      SysParamsInfo(SPI_SETHOTTRACKING, 0, FALSE, SPIF_SENDCHANGE);
+      SysParamsInfo(SPI_SETLISTBOXSMOOTHSCROLLING, 0, FALSE, SPIF_SENDCHANGE);
+      SysParamsInfo(SPI_SETMENUANIMATION, 0, FALSE, SPIF_SENDCHANGE);
+    } else {
+      SysParamsInfo(SPI_SETUIEFFECTS, 0, FALSE, SPIF_SENDCHANGE);
+    }
+    restoreEffects = true;
+
+  } catch (rdr::Exception& e) {
+    vlog.info(e.str());
+  }
+#else
+      vlog.info("disableffects not implemented");
+#endif
+}
+
+void CleanDesktop::enableEffects() {
+  try {
+    if (restoreEffects) {
+#if (WINVER >= 0x500)
+      ImpersonateCurrentUser icu;
+
+      vlog.debug("restore desktop effects");
+
+      RegKey desktopCfg;
+      desktopCfg.openKey(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"));
+      SysParamsInfo(SPI_SETFONTSMOOTHING, desktopCfg.getInt(_T("FontSmoothing"), 0) != 0, 0, SPIF_SENDCHANGE);
+      if (SysParamsInfo(SPI_SETUIEFFECTS, 0, (void*)uiEffects, SPIF_SENDCHANGE) == ERROR_CALL_NOT_IMPLEMENTED) {
+        SysParamsInfo(SPI_SETCOMBOBOXANIMATION, 0, (void*)comboBoxAnim, SPIF_SENDCHANGE);
+        SysParamsInfo(SPI_SETGRADIENTCAPTIONS, 0, (void*)gradientCaptions, SPIF_SENDCHANGE);
+        SysParamsInfo(SPI_SETHOTTRACKING, 0, (void*)hotTracking, SPIF_SENDCHANGE);
+        SysParamsInfo(SPI_SETLISTBOXSMOOTHSCROLLING, 0, (void*)listBoxSmoothScroll, SPIF_SENDCHANGE);
+        SysParamsInfo(SPI_SETMENUANIMATION, 0, (void*)menuAnim, SPIF_SENDCHANGE);
+      }
+      restoreEffects = false;
+#else
+      vlog.info("enableEffects not implemented");
+#endif
+    }
+
+  } catch (rdr::Exception& e) {
+    vlog.info(e.str());
+  }
+}
diff --git a/rfb_win32/CleanDesktop.h b/rfb_win32/CleanDesktop.h
new file mode 100644
index 0000000..73f4153
--- /dev/null
+++ b/rfb_win32/CleanDesktop.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- CleanDesktop.h
+
+#ifndef __RFB_WIN32_CLEANDESKTOP_H__
+#define __RFB_WIN32_CLEANDESKTOP_H__
+
+#include <rfb_win32/TCharArray.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class CleanDesktop {
+    public:
+      CleanDesktop();
+      ~CleanDesktop();
+
+      void disableWallpaper();
+      void enableWallpaper();
+
+      void disablePattern();
+      void enablePattern();
+
+      void disableEffects();
+      void enableEffects();
+
+    private:
+      bool restoreActiveDesktop;
+      bool restoreWallpaper;
+      bool restorePattern;
+      bool restoreEffects;
+      BOOL uiEffects;
+      BOOL comboBoxAnim, gradientCaptions, hotTracking, listBoxSmoothScroll, menuAnim;
+    };
+
+  }; // win32
+
+}; // rfb
+
+#endif // __RFB_WIN32_CLEANDESKTOP_H__
diff --git a/rfb_win32/Clipboard.cxx b/rfb_win32/Clipboard.cxx
new file mode 100644
index 0000000..96d1e94
--- /dev/null
+++ b/rfb_win32/Clipboard.cxx
@@ -0,0 +1,199 @@
+/* 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.
+ */
+
+// -=- Clipboard.cxx
+
+#include <rfb_win32/Clipboard.h>
+#include <rfb_win32/WMShatter.h>
+#include <rfb/util.h>
+
+#include <rfb/LogWriter.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("Clipboard");
+
+
+//
+// -=- CR/LF handlers
+//
+
+char*
+dos2unix(const char* text) {
+  int len = strlen(text)+1;
+  char* unix = new char[strlen(text)+1];
+  int i, j=0;
+  for (i=0; i<len; i++) {
+    if (text[i] != '\x0d')
+      unix[j++] = text[i];
+  }
+  return unix;
+}
+
+char*
+unix2dos(const char* text) {
+  int len = strlen(text)+1;
+  char* dos = new char[strlen(text)*2+1];
+  int i, j=0;
+  for (i=0; i<len; i++) {
+    if (text[i] == '\x0a')
+      dos[j++] = '\x0d';
+    dos[j++] = text[i];
+  }
+  return dos;
+}
+
+
+//
+// -=- ASCII filter (in-place)
+//
+
+void
+removeNonAsciiChars(char* text) {
+  int len = strlen(text);
+  int i=0, j=0;
+  for (; i<len; i++) {
+    if ((text[i] >= 1) && (text[i] <= 127))
+      text[j++] = text[i];
+  }
+  text[j] = 0;
+}
+
+//
+// -=- Clipboard object
+//
+
+Clipboard::Clipboard()
+  : MsgWindow(_T("Clipboard")), notifier(0), next_window(0) {
+  next_window = SetClipboardViewer(getHandle());
+  vlog.debug("registered clipboard handler");
+}
+
+Clipboard::~Clipboard() {
+  vlog.debug("removing %x from chain (next is %x)", getHandle(), next_window);
+  ChangeClipboardChain(getHandle(), next_window);
+}
+
+LRESULT
+Clipboard::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  switch (msg) {
+
+  case WM_CHANGECBCHAIN:
+    vlog.debug("change clipboard chain (%x, %x)", wParam, lParam);
+    if ((HWND) wParam == next_window)
+      next_window = (HWND) lParam;
+    else if (next_window != 0)
+      SendMessage(next_window, msg, wParam, lParam);
+    else
+      vlog.error("bad clipboard chain change!");
+    break;
+
+  case WM_DRAWCLIPBOARD:
+    {
+      HWND owner = GetClipboardOwner();
+      if (owner == getHandle()) {
+        vlog.debug("local clipboard changed by me");
+      } else {
+        vlog.debug("local clipboard changed by %x", owner);
+
+			  // Open the clipboard
+			  if (OpenClipboard(getHandle())) {
+				  // Get the clipboard data
+				  HGLOBAL cliphandle = GetClipboardData(CF_TEXT);
+				  if (cliphandle) {
+					  char* clipdata = (char*) GlobalLock(cliphandle);
+
+            // Notify clients
+            if (notifier) {
+              if (!clipdata) {
+                notifier->notifyClipboardChanged(0, 0);
+              } else {
+                CharArray unix_text;
+                unix_text.buf = dos2unix(clipdata);
+                removeNonAsciiChars(unix_text.buf);
+                notifier->notifyClipboardChanged(unix_text.buf, strlen(unix_text.buf));
+              }
+            } else {
+              vlog.debug("no clipboard notifier registered");
+            }
+
+					  // Release the buffer and close the clipboard
+					  GlobalUnlock(cliphandle);
+				  }
+
+				  CloseClipboard();
+        }
+			}
+    }
+    if (next_window)
+		  SendMessage(next_window, msg, wParam, lParam);
+    return 0;
+
+  };
+  return MsgWindow::processMessage(msg, wParam, lParam);
+};
+
+void
+Clipboard::setClipText(const char* text) {
+  HANDLE clip_handle = 0;
+
+  try {
+
+    // - Firstly, we must open the clipboard
+    if (!OpenClipboard(getHandle()))
+      throw rdr::SystemException("unable to open Win32 clipboard", GetLastError());
+
+    // - Pre-process the supplied clipboard text into DOS format
+    CharArray dos_text;
+    dos_text.buf = unix2dos(text);
+    removeNonAsciiChars(dos_text.buf);
+    int dos_text_len = strlen(dos_text.buf);
+
+    // - Allocate global memory for the data
+    clip_handle = ::GlobalAlloc(GMEM_MOVEABLE, dos_text_len+1);
+
+    char* data = (char*) GlobalLock(clip_handle);
+    memcpy(data, dos_text.buf, dos_text_len+1);
+    data[dos_text_len] = 0;
+    GlobalUnlock(clip_handle);
+
+    // - Next, we must clear out any existing data
+    if (!EmptyClipboard())
+      throw rdr::SystemException("unable to empty Win32 clipboard", GetLastError());
+
+    // - Set the new clipboard data
+    if (!SetClipboardData(CF_TEXT, clip_handle))
+      throw rdr::SystemException("unable to set Win32 clipboard", GetLastError());
+    clip_handle = 0;
+
+    vlog.debug("set clipboard");
+  } catch (rdr::Exception& e) {
+    vlog.debug(e.str());
+  }
+
+  // - Close the clipboard
+  if (!CloseClipboard())
+    vlog.debug("unable to close Win32 clipboard: %u", GetLastError());
+  else
+    vlog.debug("closed clipboard");
+  if (clip_handle) {
+    vlog.debug("freeing clipboard handle");
+    GlobalFree(clip_handle);
+  }
+}
diff --git a/rfb_win32/Clipboard.h b/rfb_win32/Clipboard.h
new file mode 100644
index 0000000..57297e1
--- /dev/null
+++ b/rfb_win32/Clipboard.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- Clipboard.h
+//
+// The Clipboard is used to set the system clipboard, and to get callbacks
+// when the system clipboard has changed.
+
+#ifndef __RFB_WIN32_CLIPBOARD_H__
+#define __RFB_WIN32_CLIPBOARD_H__
+
+#include <rfb/SDesktop.h>
+#include <rfb/Threading.h>
+#include <rfb_win32/MsgWindow.h>
+#include <rfb_win32/DeviceFrameBuffer.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class Clipboard : MsgWindow {
+    public:
+
+      // -=- Abstract base class for callback recipients
+      class Notifier {
+      public:
+        virtual void notifyClipboardChanged(const char* text, int len) = 0;
+      };
+
+      Clipboard();
+      ~Clipboard();
+
+      // - Set the notifier to use
+      void setNotifier(Notifier* cbn) {notifier = cbn;}
+
+      // - Set the clipboard contents
+      void setClipText(const char* text);
+
+    protected:
+      // - Internal MsgWindow callback
+      virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+      Notifier* notifier;
+      HWND next_window;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_CLIPBOARD_H__
diff --git a/rfb_win32/CurrentUser.cxx b/rfb_win32/CurrentUser.cxx
new file mode 100644
index 0000000..1a24485
--- /dev/null
+++ b/rfb_win32/CurrentUser.cxx
@@ -0,0 +1,93 @@
+/* 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.
+ */
+
+// -=- Currentuser.cxx
+
+#include <windows.h>
+#include <lmcons.h>
+#include <rfb_win32/CurrentUser.h>
+#include <rfb_win32/Service.h>
+#include <rfb_win32/OSVersion.h>
+
+using namespace rfb;
+using namespace win32;
+
+
+CurrentUserToken::CurrentUserToken() : isValid_(false) {
+  // - If the OS doesn't support security, ignore it
+  if (!isServiceProcess()) {
+    // - Running in User-Mode - just get our current token
+    if (!OpenProcessToken(GetCurrentProcess(), GENERIC_ALL, &h)) {
+      DWORD err = GetLastError();
+      if (err != ERROR_CALL_NOT_IMPLEMENTED)
+       throw rdr::SystemException("OpenProcessToken failed", GetLastError());
+    }
+    isValid_ = true;
+  } else {
+    // - Under XP/2003 and above, we can just ask the operating system
+    typedef BOOL (WINAPI *WTSQueryUserToken_proto)(ULONG, PHANDLE);
+    DynamicFn<WTSQueryUserToken_proto> _WTSQueryUserToken(_T("wtsapi32.dll"), "WTSQueryUserToken");
+    if (_WTSQueryUserToken.isValid()) {
+      (*_WTSQueryUserToken)(-1, &h);
+      isValid_ = true;
+    } else {
+      // - Under NT/2K we have to resort to a nasty hack...
+      HWND tray = FindWindow(_T("Shell_TrayWnd"), 0);
+      if (!tray)
+        return;
+      DWORD processId = 0;
+      GetWindowThreadProcessId(tray, &processId);
+      if (!processId)
+        return;
+      Handle process = OpenProcess(MAXIMUM_ALLOWED, FALSE, processId);
+      if (!process.h)
+        return;
+      OpenProcessToken(process, MAXIMUM_ALLOWED, &h);
+      isValid_ = true;
+    }
+  }
+}
+
+
+ImpersonateCurrentUser::ImpersonateCurrentUser() {
+  RegCloseKey(HKEY_CURRENT_USER);
+  if (!isServiceProcess())
+    return;
+  if (!token.isValid())
+    throw rdr::Exception("CurrentUserToken is not valid");
+  if (!ImpersonateLoggedOnUser(token)) {
+    DWORD err = GetLastError();
+    if (err != ERROR_CALL_NOT_IMPLEMENTED)
+      throw rdr::SystemException("Failed to impersonate user", GetLastError());
+  }
+}
+
+ImpersonateCurrentUser::~ImpersonateCurrentUser() {
+  if (!RevertToSelf()) {
+    DWORD err = GetLastError();
+    if (err != ERROR_CALL_NOT_IMPLEMENTED)
+      exit(err);
+  }
+}
+
+
+UserName::UserName() : TCharArray(UNLEN+1) {
+  DWORD len = UNLEN+1;
+  if (!GetUserName(buf, &len))
+    throw rdr::SystemException("GetUserName failed", GetLastError());
+}
diff --git a/rfb_win32/CurrentUser.h b/rfb_win32/CurrentUser.h
new file mode 100644
index 0000000..469946b
--- /dev/null
+++ b/rfb_win32/CurrentUser.h
@@ -0,0 +1,78 @@
+/* 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.
+ */
+
+// CurrentUser.h
+
+// Helper class providing the session's logged on username, if
+// a user is logged on.  Also allows processes running under
+// XP/2K3 etc to masquerade as the logged on user for security
+// purposes
+
+#ifndef __RFB_WIN32_CURRENT_USER_H__
+#define __RFB_WIN32_CURRENT_USER_H__
+
+#include <rfb_win32/Service.h>
+#include <rfb_win32/OSVersion.h>
+#include <rfb_win32/Win32Util.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    // CurrentUserToken
+    //   h == 0
+    //     if platform is not NT *or* unable to get token
+    //     *or* if process is hosting service.
+    //   h != 0
+    //     if process is hosting service *and*
+    //     if platform is NT *and* able to get token.
+    //   isValid() == true
+    //     if platform is not NT *or* token is valid.
+
+    struct CurrentUserToken : public Handle {
+      CurrentUserToken();
+      bool isValid() const {return isValid_;};
+    private:
+      bool isValid_;
+    };
+
+    // ImpersonateCurrentUser
+    //   Throws an exception on failure.
+    //   Succeeds (trivially) if process is not running as service.
+    //   Fails if CurrentUserToken is not valid.
+    //   Fails if platform is NT AND cannot impersonate token.
+    //   Succeeds otherwise.
+
+    struct ImpersonateCurrentUser {
+      ImpersonateCurrentUser();
+      ~ImpersonateCurrentUser();
+      CurrentUserToken token;
+    };
+
+    // UserName
+    //   Returns the name of the user the thread is currently running as.
+
+    struct UserName : public TCharArray {
+      UserName();
+    };
+
+  }
+
+}
+
+#endif
diff --git a/rfb_win32/DIBSectionBuffer.cxx b/rfb_win32/DIBSectionBuffer.cxx
new file mode 100644
index 0000000..2174376
--- /dev/null
+++ b/rfb_win32/DIBSectionBuffer.cxx
@@ -0,0 +1,221 @@
+/* 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.
+ */
+#include <rfb/LogWriter.h>
+
+#include <rfb_win32/DIBSectionBuffer.h>
+#include <rfb_win32/Win32Util.h>
+
+
+using namespace rfb;
+using namespace win32;
+
+static LogWriter vlog("DIBSection");
+
+
+DIBSectionBuffer::DIBSectionBuffer(HWND window_)
+  : bitmap(0), device(0), window(window_) {
+  memset(&format, 0, sizeof(format));
+  memset(palette, 0, sizeof(palette));
+}
+
+DIBSectionBuffer::DIBSectionBuffer(HDC device_)
+  : bitmap(0), window(0), device(device_) {
+  memset(&format, 0, sizeof(format));
+  memset(palette, 0, sizeof(palette));
+}
+
+DIBSectionBuffer::~DIBSectionBuffer() {
+  if (bitmap)
+    DeleteObject(bitmap);
+}
+
+
+void DIBSectionBuffer::setPF(const PixelFormat& pf) {
+  if (memcmp(&getPF(), &pf, sizeof(pf)) == 0) {
+    vlog.debug("pixel format unchanged by setPF()");
+    return;
+  }
+  format = pf;
+  recreateBuffer();
+  if ((pf.bpp <= 8) && pf.trueColour) {
+    vlog.debug("creating %d-bit TrueColour palette", pf.depth);
+    for (int i=0; i < (1<<(pf.depth)); i++) {
+      palette[i].b = ((((i >> pf.blueShift) & pf.blueMax) * 65535) + pf.blueMax/2) / pf.blueMax;
+      palette[i].g = ((((i >> pf.greenShift) & pf.greenMax) * 65535) + pf.greenMax/2) / pf.greenMax;
+      palette[i].r = ((((i >> pf.redShift) & pf.redMax) * 65535) + pf.redMax/2) / pf.redMax;
+    }
+    refreshPalette();
+  }
+}
+
+void DIBSectionBuffer::setSize(int w, int h) {
+  if (width_ == w && height_ == h) {
+    vlog.debug("size unchanged by setSize()");
+    return;
+  }
+  width_ = w;
+  height_ = h;
+  recreateBuffer();
+}
+
+
+// * copyPaletteToDIB MUST NEVER be called on a truecolour DIB! *
+
+void copyPaletteToDIB(Colour palette[256], HDC wndDC, HBITMAP dib) {
+  BitmapDC dibDC(wndDC, dib);
+  RGBQUAD rgb[256];
+  for (unsigned int i=0;i<256;i++) {
+    rgb[i].rgbRed = palette[i].r >> 8;
+    rgb[i].rgbGreen = palette[i].g >> 8;
+    rgb[i].rgbBlue = palette[i].b >> 8;
+  }
+  if (!SetDIBColorTable(dibDC, 0, 256, (RGBQUAD*) rgb))
+    throw rdr::SystemException("unable to SetDIBColorTable", GetLastError());
+}
+
+inline void initMaxAndShift(DWORD mask, int* max, int* shift) {
+  for ((*shift) = 0; (mask & 1) == 0; (*shift)++) mask >>= 1;
+  (*max) = (rdr::U16)mask;
+}
+
+void DIBSectionBuffer::recreateBuffer() {
+  HBITMAP new_bitmap = 0;
+  rdr::U8* new_data = 0;
+
+  if (width_ && height_ && (format.depth != 0)) {
+    BitmapInfo bi;
+    memset(&bi, 0, sizeof(bi));
+    // *** wrong?
+    UINT iUsage = format.trueColour ? DIB_RGB_COLORS : DIB_PAL_COLORS;
+    // ***
+    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bi.bmiHeader.biBitCount = format.bpp;
+    bi.bmiHeader.biSizeImage = (format.bpp / 8) * width_ * height_;
+    bi.bmiHeader.biPlanes = 1;
+    bi.bmiHeader.biWidth = width_;
+    bi.bmiHeader.biHeight = -height_;
+    bi.bmiHeader.biCompression = (format.bpp > 8) ? BI_BITFIELDS : BI_RGB;
+    bi.mask.red = format.redMax << format.redShift;
+    bi.mask.green = format.greenMax << format.greenShift;
+    bi.mask.blue = format.blueMax << format.blueShift;
+
+    vlog.debug("area=%d, bpp=%d", width_ * height_, format.bpp);
+
+    // Create a DIBSection to draw into
+    if (device)
+      new_bitmap = ::CreateDIBSection(device, (BITMAPINFO*)&bi.bmiHeader, iUsage,
+                                      (void**)&new_data, NULL, 0);
+    else
+      new_bitmap = ::CreateDIBSection(WindowDC(window), (BITMAPINFO*)&bi.bmiHeader, iUsage,
+                                      (void**)&new_data, NULL, 0);
+
+    if (!new_bitmap) {
+      int err = GetLastError();
+      throw rdr::SystemException("unable to create DIB section", err);
+    }
+
+    vlog.debug("recreateBuffer()");
+  } else {
+    vlog.debug("one of area or format not set");
+  }
+
+  if (new_bitmap && bitmap) {
+    vlog.debug("preserving bitmap contents");
+
+    // Copy the contents across
+    if (device) {
+      if (format.bpp <= 8)
+        copyPaletteToDIB(palette, device, new_bitmap);
+      BitmapDC src_dev(device, bitmap);
+      BitmapDC dest_dev(device, new_bitmap);
+      BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY);
+    } else {
+      WindowDC wndDC(window);
+      if (format.bpp <= 8)
+        copyPaletteToDIB(palette, wndDC, new_bitmap);
+      BitmapDC src_dev(wndDC, bitmap);
+      BitmapDC dest_dev(wndDC, new_bitmap);
+      BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY);
+    }
+  }
+  
+  if (bitmap) {
+    // Delete the old bitmap
+    DeleteObject(bitmap);
+    bitmap = 0;
+    data = 0;
+  }
+
+  if (new_bitmap) {
+    // Set up the new bitmap
+    bitmap = new_bitmap;
+    data = new_data;
+
+    // Determine the *actual* DIBSection format
+    DIBSECTION ds;
+    if (!GetObject(bitmap, sizeof(ds), &ds))
+      throw rdr::SystemException("GetObject", GetLastError());
+
+    // Correct the "stride" of the DIB
+    // *** This code DWORD aligns each row - is that right???
+    stride = width_;
+    int bytesPerRow = stride * format.bpp/8;
+    if (bytesPerRow % 4) {
+      bytesPerRow += 4 - (bytesPerRow % 4);
+      stride = (bytesPerRow * 8) / format.bpp;
+      vlog.info("adjusting DIB stride: %d to %d", width_, stride);
+    }
+
+    // Calculate the PixelFormat for the DIB
+    format.bigEndian = 0;
+    format.bpp = format.depth = ds.dsBm.bmBitsPixel;
+    format.trueColour = format.trueColour || format.bpp > 8;
+    if (format.bpp > 8) {
+
+      // Get the truecolour format used by the DIBSection
+      initMaxAndShift(ds.dsBitfields[0], &format.redMax, &format.redShift);
+      initMaxAndShift(ds.dsBitfields[1], &format.greenMax, &format.greenShift);
+      initMaxAndShift(ds.dsBitfields[2], &format.blueMax, &format.blueShift);
+
+      // Calculate the effective depth
+      format.depth = 0;
+      Pixel bits = ds.dsBitfields[0] | ds.dsBitfields[1] | ds.dsBitfields[2];
+      while (bits) {
+        format.depth++;
+        bits = bits >> 1;
+      }
+    } else {
+      // Set the DIBSection's palette
+      refreshPalette();
+    }
+  }
+}
+
+void DIBSectionBuffer::refreshPalette() {
+  if (format.bpp > 8) {
+    vlog.error("refresh palette called for truecolour DIB");
+    return;
+  }
+  vlog.debug("refreshing palette");
+  if (device)
+    copyPaletteToDIB(palette, device, bitmap);
+  else
+    copyPaletteToDIB(palette, WindowDC(window), bitmap);
+}
+
+
diff --git a/rfb_win32/DIBSectionBuffer.h b/rfb_win32/DIBSectionBuffer.h
new file mode 100644
index 0000000..51e2da3
--- /dev/null
+++ b/rfb_win32/DIBSectionBuffer.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- DIBSectionBuffer.h
+
+// A DIBSectionBuffer acts much like a standard PixelBuffer, but is associated
+// with a particular window on-screen and can be drawn into that window if
+// required, using the standard Win32 drawing operations.
+
+#ifndef __RFB_WIN32_DIB_SECTION_BUFFER_H__
+#define __RFB_WIN32_DIB_SECTION_BUFFER_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb/PixelBuffer.h>
+#include <rfb/Region.h>
+#include <rfb/ColourMap.h>
+#include <rfb/Exception.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    //
+    // -=- DIBSectionBuffer
+    //
+
+    class DIBSectionBuffer : public FullFramePixelBuffer, ColourMap {
+    public:
+      DIBSectionBuffer(HWND window);
+      DIBSectionBuffer(HDC device);
+      virtual ~DIBSectionBuffer();
+
+      virtual void setPF(const PixelFormat &pf);
+      virtual void setSize(int w, int h);
+
+      virtual int getStride() const {return stride;}
+
+      virtual ColourMap* getColourMap() const {return (ColourMap*)this;}
+
+      // - ColourMap interface
+      virtual void lookup(int index, int* r, int *g, int* b) {
+        *r = palette[index].r;
+        *g = palette[index].g;
+        *b = palette[index].b;
+      }
+  
+      // Custom colourmap interface
+      void setColour(int index, int r, int g, int b) {
+        palette[index].r = r;
+        palette[index].g = g;
+        palette[index].b = b;
+      }
+      void refreshPalette();
+
+      // *** virtual void copyRect(const Rect &dest, const Point &move_by_delta);
+    public:
+      HBITMAP bitmap;
+    protected:
+      void recreateBuffer();
+      Colour palette[256];
+      int stride;
+      HWND window;
+      HDC device;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_DIB_SECTION_BUFFER_H__
diff --git a/rfb_win32/DeviceFrameBuffer.cxx b/rfb_win32/DeviceFrameBuffer.cxx
new file mode 100644
index 0000000..a4d1021
--- /dev/null
+++ b/rfb_win32/DeviceFrameBuffer.cxx
@@ -0,0 +1,298 @@
+/* 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.
+ */
+
+// -=- DeviceFrameBuffer.cxx
+//
+// The DeviceFrameBuffer class encapsulates the pixel data of the system
+// display.
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <assert.h>
+
+#include <vector>
+
+#include <rfb/LogWriter.h>
+#include <rfb/Exception.h>
+#include <rdr/types.h>
+#include <rfb/VNCServer.h>
+#include <rfb_win32/DeviceFrameBuffer.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/OSVersion.h>
+
+namespace rfb {
+
+namespace win32 {
+
+static LogWriter vlog("FrameBuffer");
+
+
+// -=- DeviceFrameBuffer class
+
+DeviceFrameBuffer::DeviceFrameBuffer(HDC deviceContext, const Rect& wRect)
+  : DIBSectionBuffer(deviceContext), device(deviceContext), cursorBm(deviceContext),
+    ignoreGrabErrors(false)
+{
+
+  // -=- Firstly, let's check that the device has suitable capabilities
+
+  int capabilities = GetDeviceCaps(device, RASTERCAPS);
+  if (!(capabilities & RC_BITBLT)) {
+    throw Exception("device does not support BitBlt");
+  }
+  if (!(capabilities & RC_DI_BITMAP)) {
+    throw Exception("device does not support GetDIBits");
+  }
+  /*
+  if (GetDeviceCaps(device, PLANES) != 1) {
+    throw Exception("device does not support planar displays");
+  }
+  */
+
+  // -=- Get the display dimensions and pixel format
+
+  // Get the display dimensions
+  RECT cr;
+  if (!GetClipBox(device, &cr))
+    throw rdr::SystemException("GetClipBox", GetLastError());
+  deviceCoords = Rect(cr.left, cr.top, cr.right, cr.bottom);
+  if (!wRect.is_empty())
+    deviceCoords = wRect.translate(deviceCoords.tl);
+  int w = deviceCoords.width();
+  int h = deviceCoords.height();
+
+  // We can't handle uneven widths :(
+  if (w % 2) w--;
+
+  // Configure the underlying DIB to match the device
+  DIBSectionBuffer::setPF(DeviceContext::getPF(device));
+  DIBSectionBuffer::setSize(w, h);
+
+  // Configure the cursor buffer
+  cursorBm.setPF(format);
+
+  // Set up a palette if required
+  if (!format.trueColour)
+    updateColourMap();
+}
+
+DeviceFrameBuffer::~DeviceFrameBuffer() {
+}
+
+
+void
+DeviceFrameBuffer::setPF(const PixelFormat &pf) {
+  throw Exception("setPF not supported");
+}
+
+void
+DeviceFrameBuffer::setSize(int w, int h) {
+  throw Exception("setSize not supported");
+}
+
+
+#ifndef CAPTUREBLT
+#define CAPTUREBLT 0x40000000
+#endif
+
+void
+DeviceFrameBuffer::grabRect(const Rect &rect) {
+  BitmapDC tmpDC(device, bitmap);
+
+  // Map the rectangle coords from VNC Desktop-relative to device relative - usually (0,0)
+  Point src = desktopToDevice(rect.tl);
+
+  // Note: Microsoft's documentation lies directly about CAPTUREBLT and claims it works on 98/ME
+  //       If you try CAPTUREBLT on 98 then you get blank output...
+  if (!::BitBlt(tmpDC, rect.tl.x, rect.tl.y, rect.width(), rect.height(), device, src.x, src.y,
+    osVersion.isPlatformNT ? CAPTUREBLT | SRCCOPY : SRCCOPY)) {
+    if (ignoreGrabErrors)
+      vlog.error("BitBlt failed:%ld", GetLastError());
+    else
+      throw rdr::SystemException("BitBlt failed", GetLastError());
+  }
+}
+
+void
+DeviceFrameBuffer::grabRegion(const Region &rgn) {
+  std::vector<Rect> rects;
+  std::vector<Rect>::const_iterator i;
+  rgn.get_rects(&rects);
+  for(i=rects.begin(); i!=rects.end(); i++) {
+    grabRect(*i);
+  }
+  ::GdiFlush();
+}
+
+
+void copyDevicePaletteToDIB(HDC dc, DIBSectionBuffer* dib) {
+  // - Fetch the system palette for the framebuffer
+  PALETTEENTRY syspalette[256];
+  UINT entries = ::GetSystemPaletteEntries(dc, 0, 256, syspalette);
+
+  if (entries == 0) {
+    vlog.info("resorting to standard 16 colour palette");
+    for (unsigned int i=0;i<256;i++) {
+      int v = (i%16) >= 8 ? 127 : 255;
+      syspalette[i].peRed = i & 1 ? v : 0;
+      syspalette[i].peGreen = i & 2 ? v : 0;
+      syspalette[i].peBlue = i & 4 ? v : 0;
+    }
+  } else {
+    vlog.info("framebuffer has %u palette entries", entries);
+  }
+
+  // - Update the bitmap's stored copy of the palette
+  for (unsigned int i=0;i<256;i++) {
+    int r, g, b;
+    r = (syspalette[i].peRed << 8) + 0x80;
+    g = (syspalette[i].peGreen << 8) + 0x80;
+    b = (syspalette[i].peBlue << 8) + 0x80;
+    dib->setColour(i, r, g, b);
+  }
+
+  // - Update the DIB section to use the palette
+  dib->refreshPalette();
+}
+
+
+void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)
+{
+  // - If hCursor is null then there is no cursor - clear the old one
+
+  if (hCursor == 0) {
+    server->setCursor(0, 0, 0, 0, 0, 0);
+    return;
+  }
+
+  try {
+
+    // - Get the size and other details about the cursor.
+
+    IconInfo iconInfo((HICON)hCursor);
+
+    BITMAP maskInfo;
+    if (!GetObject(iconInfo.hbmMask, sizeof(BITMAP), &maskInfo))
+      throw rdr::SystemException("GetObject() failed", GetLastError());
+
+    assert(maskInfo.bmPlanes == 1 && maskInfo.bmBitsPixel == 1);
+
+    // - Create the cursor pixel buffer and mask storage
+    //   NB: The cursor pixel buffer is NOT used here.  Instead, we
+    //   pass the cursorBm.data pointer directly, to save overhead.
+
+    cursor.setSize(maskInfo.bmWidth, maskInfo.bmHeight);
+    cursor.setPF(format);
+    cursor.hotspot = Point(iconInfo.xHotspot, iconInfo.yHotspot);
+
+    // - Get the AND and XOR masks.  There is only an XOR mask if this is not a
+    // colour cursor.
+
+    if (!iconInfo.hbmColor)
+      cursor.setSize(cursor.width(), cursor.height() / 2);
+    rdr::U8Array mask(maskInfo.bmWidthBytes * maskInfo.bmHeight);
+    rdr::U8* xorMask = mask.buf + cursor.height() * maskInfo.bmWidthBytes;
+
+    if (!GetBitmapBits(iconInfo.hbmMask,
+                       maskInfo.bmWidthBytes * maskInfo.bmHeight, mask.buf))
+      throw rdr::SystemException("GetBitmapBits failed", GetLastError());
+
+    // Configure the cursor bitmap
+    cursorBm.setSize(cursor.width(), cursor.height());
+
+    // Copy the palette into it if required
+    if (format.bpp <= 8)
+      copyDevicePaletteToDIB(device, &cursorBm);
+
+    // Draw the cursor into the bitmap
+    BitmapDC dc(device, cursorBm.bitmap);
+    if (!DrawIconEx(dc, 0, 0, hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT))
+      throw rdr::SystemException("unable to render cursor", GetLastError());
+
+    // Replace any XORed pixels with xorColour, because RFB doesn't support
+    // XORing of cursors.  XORing is used for the I-beam cursor, which is most
+    // often used over a white background, but also sometimes over a black
+    // background.  We set the XOR'd pixels to black, then draw a white outline
+    // around the whole cursor.
+
+    // *** should we replace any pixels not set in mask to zero, to ensure
+    // that irrelevant data doesn't screw compression?
+
+    bool doOutline = false;
+    if (!iconInfo.hbmColor) {
+      Pixel xorColour = format.pixelFromRGB(0, 0, 0, cursorBm.getColourMap());
+      for (int y = 0; y < cursor.height(); y++) {
+        bool first = true;
+        for (int x = 0; x < cursor.width(); x++) {
+          int byte = y * maskInfo.bmWidthBytes + x / 8;
+          int bit = 7 - x % 8;
+          if ((mask.buf[byte] & (1 << bit)) && (xorMask[byte] & (1 << bit)))
+          {
+            mask.buf[byte] &= ~(1 << bit);
+
+            switch (format.bpp) {
+            case 8:
+              ((rdr::U8*)cursorBm.data)[y * cursor.width() + x] = xorColour;  break;
+            case 16:
+              ((rdr::U16*)cursorBm.data)[y * cursor.width() + x] = xorColour; break;
+            case 32:
+              ((rdr::U32*)cursorBm.data)[y * cursor.width() + x] = xorColour; break;
+            }
+
+            doOutline = true;
+          }
+        }
+      }
+    }
+
+    // Finally invert the AND mask so it's suitable for RFB and pack it into
+    // the minimum number of bytes per row.
+
+    int maskBytesPerRow = (cursor.width() + 7) / 8;
+
+    for (int j = 0; j < cursor.height(); j++) {
+      for (int i = 0; i < maskBytesPerRow; i++)
+        cursor.mask.buf[j * maskBytesPerRow + i]
+          = ~mask.buf[j * maskInfo.bmWidthBytes + i];
+    }
+
+    if (doOutline) {
+      vlog.debug("drawing cursor outline!");
+      memcpy(cursor.data, cursorBm.data, cursor.dataLen());
+      cursor.drawOutline(format.pixelFromRGB(0xffff, 0xffff, 0xffff, cursorBm.getColourMap()));
+      memcpy(cursorBm.data, cursor.data, cursor.dataLen());
+    }
+
+    server->setCursor(cursor.width(), cursor.height(),
+                      cursor.hotspot.x, cursor.hotspot.y,
+                      cursorBm.data, cursor.mask.buf);
+  } catch (rdr::Exception& e) {
+    vlog.error(e.str());
+  }
+}
+
+
+void
+DeviceFrameBuffer::updateColourMap() {
+  if (!format.trueColour)
+    copyDevicePaletteToDIB(device, this);
+}
+
+}; // namespace win32
+
+}; // namespace rfb
diff --git a/rfb_win32/DeviceFrameBuffer.h b/rfb_win32/DeviceFrameBuffer.h
new file mode 100644
index 0000000..5e97b22
--- /dev/null
+++ b/rfb_win32/DeviceFrameBuffer.h
@@ -0,0 +1,121 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- DeviceFrameBuffer.h
+//
+// The DeviceFrameBuffer class encapsulates the pixel data of a supplied
+// Device Context Handle (HDC)
+
+// *** THIS INTERFACE NEEDS TIDYING TO SEPARATE COORDINATE SYSTEMS BETTER ***
+
+#ifndef __RFB_WIN32_DEVICE_FRAME_BUFFER_H__
+#define __RFB_WIN32_DEVICE_FRAME_BUFFER_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb_win32/DIBSectionBuffer.h>
+#include <rfb/Cursor.h>
+#include <rfb/Region.h>
+#include <rfb/Exception.h>
+
+namespace rfb {
+
+  class VNCServer;
+
+  namespace win32 {
+
+    // -=- DeviceFrameBuffer interface
+
+    // DeviceFrameBuffer is passed an HDC referring to a window or to
+    // the entire display.  It may also be passed a rectangle specifying
+    // the Device-relative coordinates of the actual rectangle to treat
+    // as the desktop.
+
+    // Coordinate systems start getting really annoying here.  There are
+    // three different "origins" to which coordinates might be relative:
+    //
+    // Desktop - VNC coordinates, top-left always (0,0)
+    // Device - DC coordinates.  Top-left *usually (0,0) but could be other.
+    // Window - coordinates relative to the specified sub-rectangle within
+    //          the supplied DC.
+    // Screen - Coordinates relative to the entire Windows virtual screen.
+    //          The virtual screen includes all monitors that are part of
+    //          the Windows desktop.
+
+    // The data member is made to point to an internal mirror of the
+    // current display data.  Individual rectangles or regions of the
+    // buffer can be brought up to date by calling the grab functions.
+
+    class DeviceFrameBuffer : public DIBSectionBuffer {
+    public:
+      DeviceFrameBuffer(HDC deviceContext, const Rect& area_=Rect());
+      virtual ~DeviceFrameBuffer();
+
+      // - FrameBuffer overrides
+
+      virtual void grabRect(const Rect &rect);
+      virtual void grabRegion(const Region &region);
+
+      // - DIBSectionBuffer overrides
+      
+      virtual void setPF(const PixelFormat& pf);
+      virtual void setSize(int w, int h);
+      
+      // - DeviceFrameBuffer specific methods
+
+      void setCursor(HCURSOR c, VNCServer* server);
+      void updateColourMap();
+
+      // Set whether grabRect should ignore errors or throw exceptions
+      // Only set this if you are sure you'll capture the errors some other way!
+      void setIgnoreGrabErrors(bool ie) {ignoreGrabErrors=ie;}
+
+    protected:
+      // Translate supplied Desktop coordinates into Device-relative coordinates
+      // This translation may have been affected at start-time by the supplied sub-rect.
+      Point desktopToDevice(const Point p) const {return p.translate(deviceCoords.tl);}
+
+      HDC device;
+      DIBSectionBuffer cursorBm;
+      Cursor cursor;
+      Rect deviceCoords;
+      bool ignoreGrabErrors;
+    };
+
+    // -=- createDisplayDeviceFrameBuffer
+    // createDisplayDeviceFrameBuffer must be passed the name of a display device,
+    // and will return a new FrameBuffer object attached to that display
+    // device.
+    // If the device name is not specified then the default display is
+    // returned.
+
+    DeviceFrameBuffer *createDisplayDeviceFrameBuffer(const char *device=0);
+
+    // -=- createDisplayFrameBuffers
+    // Creates a set of framebuffers, one for each available display
+    // device.
+
+    typedef std::vector<DeviceFrameBuffer *> DeviceFrameBuffers;
+    void createDisplayDeviceFrameBuffers(DeviceFrameBuffers *fbs);
+
+  };
+
+};
+
+#endif // __RFB_WIN32_DEVICE_FRAME_BUFFER_H__
diff --git a/rfb_win32/Dialog.cxx b/rfb_win32/Dialog.cxx
new file mode 100644
index 0000000..157cf5f
--- /dev/null
+++ b/rfb_win32/Dialog.cxx
@@ -0,0 +1,353 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- Dialog.cxx
+
+// Base-class for any Dialog classes we might require
+
+#include <rfb_win32/Dialog.h>
+#include <rfb_win32/TCharArray.h>
+#include <rfb/LogWriter.h>
+#include <rdr/Exception.h>
+#include <rfb_win32/Win32Util.h>
+#ifdef _DIALOG_CAPTURE
+#include <rfb_win32/DeviceFrameBuffer.h>
+#include <extra/LoadBMP.cxx>
+#endif
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter dlog("Dialog");
+static LogWriter plog("PropSheet");
+
+
+Dialog::Dialog(HINSTANCE inst_)
+: inst(inst_), alreadyShowing(false), handle(0)
+{
+}
+
+Dialog::~Dialog()
+{
+}
+
+
+bool Dialog::showDialog(const TCHAR* resource, HWND owner)
+{
+  if (alreadyShowing) return false;
+  handle = 0;
+  alreadyShowing = true;
+  INT_PTR result = DialogBoxParam(inst, resource, owner,
+                                  staticDialogProc, (LPARAM)this);
+  if (result<0)
+    throw rdr::SystemException("DialogBoxParam failed", GetLastError());
+  alreadyShowing = false;
+  return (result == 1);
+}
+
+
+bool Dialog::isItemChecked(int id) {
+  return SendMessage(GetDlgItem(handle, id), BM_GETCHECK, 0, 0) == BST_CHECKED;
+}
+int Dialog::getItemInt(int id) {
+  BOOL trans;
+  int result = GetDlgItemInt(handle, id, &trans, TRUE);
+  if (!trans)
+    throw rdr::Exception("unable to read dialog Int");
+  return result;
+}
+TCHAR* Dialog::getItemString(int id) {
+  TCharArray tmp(256);
+  if (!GetDlgItemText(handle, id, tmp.buf, 256))
+    tmp.buf[0] = 0;
+  return tmp.takeBuf();
+}
+
+void Dialog::setItemChecked(int id, bool state) {
+  dlog.debug("bool[%d]=%d", id, (int)state);
+  SendMessage(GetDlgItem(handle, id), BM_SETCHECK, state ? BST_CHECKED : BST_UNCHECKED, 0);
+}
+void Dialog::setItemInt(int id, int value) {
+  dlog.debug("int[%d]=%d", id, value);
+  SetDlgItemInt(handle, id, value, TRUE);
+}
+void Dialog::setItemString(int id, const TCHAR* s) {
+  dlog.debug("string[%d]=%s", id, (const char*)CStr(s));
+  SetDlgItemText(handle, id, s);
+}
+
+
+void Dialog::enableItem(int id, bool state) {
+  dlog.debug("enable[%d]=%d", id, (int)state);
+  EnableWindow(GetDlgItem(handle, id), state);
+}
+
+
+
+
+BOOL CALLBACK Dialog::staticDialogProc(HWND hwnd, UINT msg,
+				       WPARAM wParam, LPARAM lParam)
+{
+  if (msg == WM_INITDIALOG)
+    SetWindowLong(hwnd, GWL_USERDATA, (LONG)lParam);
+
+  LONG self = GetWindowLong(hwnd, GWL_USERDATA);
+  if (!self) return FALSE;
+
+  return ((Dialog*)self)->dialogProc(hwnd, msg, wParam, lParam);
+}
+
+BOOL Dialog::dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  switch (msg) {
+
+  case WM_INITDIALOG:
+    handle = hwnd;
+    initDialog();
+    return TRUE;
+
+  case WM_COMMAND:
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      if (onOk()) {
+        EndDialog(hwnd, 1);
+        return TRUE;
+      }
+      return FALSE;
+    case IDCANCEL:
+      EndDialog(hwnd, 0);
+      return TRUE;
+    default:
+      return onCommand(LOWORD(wParam), HIWORD(wParam));
+    };
+
+  case WM_HELP:
+    return onHelp(((HELPINFO*)lParam)->iCtrlId);
+
+  }
+
+  return FALSE;
+}
+
+
+PropSheetPage::PropSheetPage(HINSTANCE inst, const TCHAR* id) : Dialog(inst), propSheet(0) {
+  page.dwSize = sizeof(page);
+  page.dwFlags = 0; // PSP_USECALLBACK;
+  page.hInstance = inst;
+  page.pszTemplate = id;
+  page.pfnDlgProc = staticPageProc;
+  page.lParam = (LPARAM)this;
+  page.pfnCallback = 0; // staticPageProc;
+}
+
+PropSheetPage::~PropSheetPage() {
+}
+
+
+BOOL CALLBACK PropSheetPage::staticPageProc(HWND hwnd, UINT msg,
+				       WPARAM wParam, LPARAM lParam)
+{
+  if (msg == WM_INITDIALOG)
+    SetWindowLong(hwnd, GWL_USERDATA, ((PROPSHEETPAGE*)lParam)->lParam);
+
+  LONG self = GetWindowLong(hwnd, GWL_USERDATA);
+  if (!self) return FALSE;
+
+  return ((PropSheetPage*)self)->dialogProc(hwnd, msg, wParam, lParam);
+}
+
+BOOL PropSheetPage::dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  switch (msg) {
+
+  case WM_INITDIALOG:
+    handle = hwnd;
+    initDialog();
+    return TRUE;
+
+  case WM_NOTIFY:
+    switch (((NMHDR*)lParam)->code) {
+    case PSN_APPLY:
+      onOk();
+      return FALSE;
+    };
+    return FALSE;
+
+  case WM_COMMAND:
+    return onCommand(LOWORD(wParam), HIWORD(wParam));
+
+  case WM_HELP:
+    return onHelp(((HELPINFO*)lParam)->iCtrlId);
+
+  }
+
+  return FALSE;
+}
+
+
+PropSheet::PropSheet(HINSTANCE inst_, const TCHAR* title_, std::list<PropSheetPage*> pages_, HICON icon_)
+: title(tstrDup(title_)), inst(inst_), pages(pages_), alreadyShowing(0), handle(0), icon(icon_) {
+}
+
+PropSheet::~PropSheet() {
+}
+
+
+bool PropSheet::showPropSheet(HWND owner, bool showApply, bool showCtxtHelp, bool capture) {
+  if (alreadyShowing) return false;
+  alreadyShowing = true;
+  int count = pages.size();
+
+  HPROPSHEETPAGE* hpages = new HPROPSHEETPAGE[count];
+  try {
+    // Create the PropertSheet page GDI objects.
+    std::list<PropSheetPage*>::iterator pspi;
+    int i = 0;
+    for (pspi=pages.begin(); pspi!=pages.end(); pspi++) {
+      hpages[i] = CreatePropertySheetPage(&((*pspi)->page));
+      (*pspi)->setPropSheet(this);
+      i++;
+    }
+ 
+    // Initialise and create the PropertySheet itself
+    PROPSHEETHEADER header;
+    header.dwSize = PROPSHEETHEADER_V1_SIZE;
+    header.dwFlags = PSH_MODELESS | (showApply ? 0 : PSH_NOAPPLYNOW) /*| (showCtxtHelp ? 0 : PSH_NOCONTEXTHELP)*/;
+    header.hwndParent = owner;
+    header.hInstance = inst;
+    header.pszCaption = title.buf;
+    header.nPages = count;
+    header.nStartPage = 0;
+    header.phpage = hpages;
+    if (icon) {
+      header.hIcon = icon;
+      header.dwFlags |= PSH_USEHICON;
+    }
+
+    handle = (HWND)PropertySheet(&header);
+    if ((handle == 0) || (handle == (HWND)-1))
+      throw rdr::SystemException("PropertySheet failed", GetLastError());
+    centerWindow(handle, owner);
+    plog.info("created %lx", handle);
+
+#if (WINVER >= 0x0500)
+#ifdef _DIALOG_CAPTURE
+    // *** NOT TESTED
+    if (capture) {
+      plog.info("capturing \"%s\"", (const char*)CStr(title.buf));
+      char* tmpdir = getenv("TEMP");
+      HDC dc = GetWindowDC(handle);
+      DeviceFrameBuffer fb(dc);
+      int i=0;
+      while (true) {
+        int id = PropSheet_IndexToId(handle, i);
+        if (!id) break;
+        PropSheet_SetCurSelByID(handle, id);
+        MSG msg;
+        while (PeekMessage(&msg, handle, 0, 0, PM_REMOVE)) {
+          if (!PropSheet_IsDialogMessage(handle, &msg))
+            DispatchMessage(&msg);
+        }
+        fb.grabRect(fb.getRect());
+        char filename[256];
+        sprintf(filename, "%s\\capture%d.bmp", tmpdir, i);
+        saveBMP(filename, &fb);
+        i++;
+      }
+      ReleaseDC(handle, dc);
+    } else {
+#endif
+#endif
+      try {
+        if (owner)
+          EnableWindow(owner, FALSE);
+        // Run the PropertySheet
+        MSG msg;
+        while (GetMessage(&msg, 0, 0, 0)) {
+          if (!PropSheet_IsDialogMessage(handle, &msg))
+            DispatchMessage(&msg);
+          if (!PropSheet_GetCurrentPageHwnd(handle))
+            break;
+        }
+        if (owner)
+          EnableWindow(owner, TRUE);
+      } catch (...) {
+        if (owner)
+          EnableWindow(owner, TRUE);
+        throw;
+      }
+#if (WINVER >= 0x0500)
+#ifdef _DIALOG_CAPTURE
+    }
+#endif
+#endif
+
+    plog.info("finished %lx", handle);
+
+    DestroyWindow(handle);
+    handle = 0;
+    alreadyShowing = false;
+
+    // Clear up the pages' GDI objects
+    for (pspi=pages.begin(); pspi!=pages.end(); pspi++)
+      (*pspi)->setPropSheet(0);
+    delete [] hpages; hpages = 0;
+
+    return true;
+  } catch (rdr::Exception) {
+    alreadyShowing = false;
+
+    std::list<PropSheetPage*>::iterator pspi;
+    for (pspi=pages.begin(); pspi!=pages.end(); pspi++)
+      (*pspi)->setPropSheet(0);
+    delete [] hpages; hpages = 0;
+
+    throw;
+  }
+}
+
+void PropSheet::reInitPages() {
+  plog.debug("reInitPages %lx", handle);
+  std::list<PropSheetPage*>::iterator pspi;
+  for (pspi=pages.begin(); pspi!=pages.end(); pspi++) {
+    if ((*pspi)->handle)
+      (*pspi)->initDialog();
+  }
+}
+
+bool PropSheet::commitPages() {
+  plog.debug("commitPages %lx", handle);
+  bool result = true;
+  std::list<PropSheetPage*>::iterator pspi;
+  for (pspi=pages.begin(); pspi!=pages.end(); pspi++) {
+    if ((*pspi)->handle)
+      result = result && (*pspi)->onOk();
+  }
+  return result;
+}
+
+
+void PropSheetPage::setChanged(bool changed) {
+  if (propSheet) {
+    plog.debug("setChanged[%lx(%lx)]=%d", handle, propSheet->handle, (int)changed);
+    if (changed)
+      PropSheet_Changed(propSheet->handle, handle);
+    else
+      PropSheet_UnChanged(propSheet->handle, handle);
+  }
+}
diff --git a/rfb_win32/Dialog.h b/rfb_win32/Dialog.h
new file mode 100644
index 0000000..d46133a
--- /dev/null
+++ b/rfb_win32/Dialog.h
@@ -0,0 +1,159 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- RegConfig.h
+
+// Class which monitors the registry and reads in the registry settings
+// whenever they change, or are added or removed.
+
+#ifndef __RFB_WIN32_DIALOG_H__
+#define __RFB_WIN32_DIALOG_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <prsht.h>
+#include <list>
+#include <rfb_win32/TCharArray.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    // Dialog - A simple Win32 Dialog box.  A derived class of Dialog overrides the
+    // initDialog(), command() and ok() methods to take appropriate action.  A
+    // simple dialog box can be displayed by creating a Dialog object and calling
+    // show().
+
+    class Dialog {
+    public:
+
+      Dialog(HINSTANCE inst);
+      virtual ~Dialog();
+
+      // showDialog() displays the dialog box.  It returns when it has been dismissed,
+      // returning true if "OK" was pressed, false otherwise.  The resource
+      // argument identifies the dialog resource (often a MAKEINTRESOURCE macro
+      // expansion), and owner is an optional window handle - the corresponding
+      // window is disabled while the dialog box is displayed.
+
+      bool showDialog(const TCHAR* resource, HWND owner=0);
+
+      // initDialog() is called upon receipt of the WM_INITDIALOG message.
+
+      virtual void initDialog() {}
+
+      // onCommand() is called upon receipt of a WM_COMMAND message item other than IDOK
+      // or IDCANCEL.  It should return true if the command has been handled.
+
+      virtual bool onCommand(int item, int cmd) { return false; }
+
+      // onHelp() is called upon receipt of a WM_MENU message.  This indicates that
+      // context-specific help should be displayed, for a dialog control, for example.
+      // It should return true if the command has been handled.
+
+      virtual bool onHelp(int item) { return false; }
+
+      // onOk() is called when the OK button is pressed.  The hwnd argument is the
+      // dialog box's window handle.
+
+      virtual bool onOk() { return true; }
+
+      // Read the states of items
+      bool isItemChecked(int id);
+      int getItemInt(int id);
+      TCHAR* getItemString(int id); // Recipient owns string storage
+      
+      // Set the states of items
+      void setItemChecked(int id, bool state);
+      void setItemInt(int id, int value);
+      void setItemString(int id, const TCHAR* s);
+
+      // enableItem is used to grey out an item, making it inaccessible, or to
+      // re-enable it.
+      void enableItem(int id, bool state);
+
+    protected:
+      static BOOL CALLBACK staticDialogProc(HWND hwnd, UINT msg,
+			      WPARAM wParam, LPARAM lParam);
+      virtual BOOL dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+      HINSTANCE inst;
+      HWND handle;
+      bool alreadyShowing;
+    };
+
+    // PropertySheetPage 
+    // Class used to define property pages within a PropertySheet.
+    // Each page is associated with a particular dialog resource, indicated by
+    // the "id" parameter supplied to the constructor.
+
+    class PropSheetPage;
+
+    class PropSheet {
+    public:
+      PropSheet(HINSTANCE inst, const TCHAR* title, std::list<PropSheetPage*> pages, HICON icon=0);
+      virtual ~PropSheet();
+
+      // Display the PropertySheet
+      bool showPropSheet(HWND owner, bool showApply = false, bool showCtxtHelp = false, bool capture=false);
+      
+      // Calls initDialog again for each page that has already had it called.
+      // Note: If a page hasn't been seen yet, it won't have been called.
+      // Note: This must only be called while the property sheet is visible.
+      void reInitPages();
+
+      // Calls onOk for each page that has had initDialog called, and returns
+      // false if any one of them returns false, or true otherwise.  ALL the
+      // onOk() methods will be called, even if one of them fails.
+      // Note: If a page hasn't been seen yet, it won't have been called.
+      // Note: This must only be called while the property sheet is visible.
+      bool commitPages();
+
+      friend class PropSheetPage;
+
+    protected:
+      HWND owner;
+      HICON icon;
+      std::list<PropSheetPage*> pages;
+      HINSTANCE inst;
+      TCharArray title;
+      HWND handle;
+      bool alreadyShowing;
+    };
+
+    class PropSheetPage : public Dialog {
+    public:
+      PropSheetPage(HINSTANCE inst, const TCHAR* id);
+      virtual ~PropSheetPage();
+
+      void setChanged(bool changed);
+
+      friend class PropSheet;
+
+    protected:
+      void setPropSheet(PropSheet* ps) {propSheet = ps;};
+      static BOOL CALLBACK staticPageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+      virtual BOOL dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+      PROPSHEETPAGE page;
+      PropSheet* propSheet;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_DIALOG_H__
diff --git a/rfb_win32/IntervalTimer.h b/rfb_win32/IntervalTimer.h
new file mode 100644
index 0000000..645d0ee
--- /dev/null
+++ b/rfb_win32/IntervalTimer.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- IntervalTimer.h
+//
+// Simple wrapper for standard Win32 timers
+
+#ifndef __RFB_WIN32_INTERVAL_TIMER_H__
+#define __RFB_WIN32_INTERVAL_TIMER_H__
+
+namespace rfb {
+
+  namespace win32 {
+
+    struct IntervalTimer {
+      IntervalTimer(HWND hwnd_, int id_)
+        : active(false), hwnd(hwnd_), id(id_) {
+      }
+      IntervalTimer() : active(false), hwnd(0), id(0) {
+      }
+      ~IntervalTimer() {
+        stop();
+      }
+
+      void start(int interval_) {
+        if (!active || interval_ != interval) {
+          interval = interval_;
+          if (!SetTimer(hwnd, id, interval, 0))
+            throw rdr::SystemException("SetTimer", GetLastError());
+          active = true;
+        }
+      }
+      void stop() {
+        if (active)
+          KillTimer(hwnd, id);
+        active = false;
+      }
+
+      void setHWND(HWND hwnd_) {hwnd=hwnd_;}
+      void setId(int id_) {id = id_;}
+      int getId() const {return id;}
+      bool isActive() const {return active;}
+
+    private:
+      HWND hwnd;
+      int id;
+      bool active;
+      int interval;
+    };
+
+  }; // win32
+
+}; // rfb
+
+#endif // __RFB_WIN32_INTERVAL_TIMER_H__
diff --git a/rfb_win32/LaunchProcess.cxx b/rfb_win32/LaunchProcess.cxx
new file mode 100644
index 0000000..0a48d60
--- /dev/null
+++ b/rfb_win32/LaunchProcess.cxx
@@ -0,0 +1,92 @@
+/* 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.
+ */
+
+// -=- LaunchProcess.cxx
+
+#include <rfb_win32/LaunchProcess.h>
+#include <rfb_win32/Win32Util.h>
+
+#include <rfb/util.h>
+
+using namespace rfb;
+using namespace win32;
+
+
+LaunchProcess::LaunchProcess(const TCHAR* exeName_, const TCHAR* params_)
+: exeName(tstrDup(exeName_)), params(tstrDup(params_)) {
+  memset(&procInfo, 0, sizeof(procInfo));
+}
+
+LaunchProcess::~LaunchProcess() {
+  await();
+}
+
+
+void LaunchProcess::start(HANDLE userToken) {
+  if (procInfo.hProcess && (WaitForSingleObject(procInfo.hProcess, 0) != WAIT_OBJECT_0))
+    return;
+  await();
+
+  // - Create storage for the process startup information
+  STARTUPINFO sinfo;
+  memset(&sinfo, 0, sizeof(sinfo));
+  sinfo.cb = sizeof(sinfo);
+
+  // - Concoct a suitable command-line
+  TCharArray exePath;
+  if (!tstrContains(exeName.buf, _T('\\'))) {
+    ModuleFileName filename;
+    TCharArray path; splitPath(filename.buf, &path.buf, 0);
+    exePath.buf = new TCHAR[_tcslen(path.buf) + _tcslen(exeName.buf) + 2];
+    _stprintf(exePath.buf, _T("%s\\%s"), path.buf, exeName.buf);
+  } else {
+    exePath.buf = tstrDup(exeName.buf);
+  }
+
+  // - Start the VNC server
+  // Note: We specify the exe's precise path in the ApplicationName parameter,
+  //       AND include the name as the first part of the CommandLine parameter,
+  //       because CreateProcess doesn't make ApplicationName argv[0] in C programs.
+  TCharArray cmdLine(_tcslen(exeName.buf) + 3 + _tcslen(params.buf) + 1);
+  _stprintf(cmdLine.buf, _T("\"%s\" %s"), exeName.buf, params.buf);
+#ifdef _DEBUG
+  DWORD flags = CREATE_NEW_CONSOLE;
+#else
+  DWORD flags = CREATE_NO_WINDOW;
+#endif
+  BOOL success;
+  if (userToken)
+    success = CreateProcessAsUser(userToken, exePath.buf, cmdLine.buf, 0, 0, FALSE, flags, 0, 0, &sinfo, &procInfo);
+  else
+    success = CreateProcess(exePath.buf, cmdLine.buf, 0, 0, FALSE, flags, 0, 0, &sinfo, &procInfo);
+  if (!success)
+    throw rdr::SystemException("unable to launch process", GetLastError());
+
+  // Wait for it to finish initialising
+  WaitForInputIdle(procInfo.hProcess, 15000);
+}
+
+void LaunchProcess::await() {
+  if (!procInfo.hProcess)
+    return;
+  WaitForSingleObject(procInfo.hProcess, INFINITE);
+  CloseHandle(procInfo.hProcess);
+  CloseHandle(procInfo.hThread);
+  memset(&procInfo, 0, sizeof(procInfo));
+}
+
diff --git a/rfb_win32/LaunchProcess.h b/rfb_win32/LaunchProcess.h
new file mode 100644
index 0000000..6fd34e9
--- /dev/null
+++ b/rfb_win32/LaunchProcess.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- LaunchProcess.h
+
+// Helper class to launch a names process from the same directory as
+// the current process executable resides in.
+
+#ifndef __RFB_WIN32_LAUNCHPROCESS_H__
+#define __RFB_WIN32_LAUNCHPROCESS_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb_win32/TCharArray.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class LaunchProcess {
+    public:
+      LaunchProcess(const TCHAR* exeName_, const TCHAR* params);
+      ~LaunchProcess();
+
+      // If userToken is 0 then starts as current user, otherwise
+      // starts as the specified user.  userToken must be a primary token.
+      void start(HANDLE userToken);
+
+      // Wait for the process to quit, and close the handles to it.
+      void await();
+
+      PROCESS_INFORMATION procInfo;
+    protected:
+      TCharArray exeName;
+      TCharArray params;
+    };
+
+
+  };
+
+};
+
+#endif
diff --git a/rfb_win32/MsgWindow.cxx b/rfb_win32/MsgWindow.cxx
new file mode 100644
index 0000000..519d6ab
--- /dev/null
+++ b/rfb_win32/MsgWindow.cxx
@@ -0,0 +1,116 @@
+/* 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.
+ */
+
+// -=- MsgWindow.cxx
+
+#include <rfb_win32/MsgWindow.h>
+#include <rfb_win32/WMShatter.h>
+#include <rfb/LogWriter.h>
+#include <rdr/Exception.h>
+#include <malloc.h>
+#include <tchar.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("MsgWindow");
+
+//
+// -=- MsgWindowClass
+//
+
+class MsgWindowClass {
+public:
+  MsgWindowClass();
+  ~MsgWindowClass();
+  ATOM classAtom;
+  HINSTANCE instance;
+};
+
+LRESULT CALLBACK MsgWindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+  LRESULT result;
+
+  if (msg == WM_CREATE)
+    SetWindowLong(wnd, GWL_USERDATA, (long)((CREATESTRUCT*)lParam)->lpCreateParams);
+  else if (msg == WM_DESTROY)
+    SetWindowLong(wnd, GWL_USERDATA, 0);
+  MsgWindow* _this = (MsgWindow*) GetWindowLong(wnd, GWL_USERDATA);
+  if (!_this) {
+    vlog.info("null _this in %x, message %x", wnd, msg);
+    return SafeDefWindowProc(wnd, msg, wParam, lParam);
+  }
+
+  try {
+    result = _this->processMessage(msg, wParam, lParam);
+  } catch (rdr::Exception& e) {
+    vlog.error("untrapped: %s", e.str());
+  }
+
+  return result;
+};
+
+MsgWindowClass::MsgWindowClass() : classAtom(0) {
+  WNDCLASS wndClass;
+  wndClass.style = 0;
+  wndClass.lpfnWndProc = MsgWindowProc;
+  wndClass.cbClsExtra = 0;
+  wndClass.cbWndExtra = 0;
+  wndClass.hInstance = instance = GetModuleHandle(0);
+  wndClass.hIcon = 0;
+  wndClass.hCursor = 0;
+  wndClass.hbrBackground = 0;
+  wndClass.lpszMenuName = 0;
+  wndClass.lpszClassName = _T("rfb::win32::MsgWindowClass");
+  classAtom = RegisterClass(&wndClass);
+  if (!classAtom) {
+    throw rdr::SystemException("unable to register MsgWindow window class", GetLastError());
+  }
+}
+
+MsgWindowClass::~MsgWindowClass() {
+  if (classAtom) {
+    UnregisterClass((const TCHAR*)classAtom, instance);
+  }
+}
+
+MsgWindowClass baseClass;
+
+//
+// -=- MsgWindow
+//
+
+MsgWindow::MsgWindow(const TCHAR* name_) : name(tstrDup(name_)), handle(0) {
+  vlog.debug("creating window \"%s\"", (const char*)CStr(name.buf));
+  handle = CreateWindow((const TCHAR*)baseClass.classAtom, name.buf, WS_OVERLAPPED,
+    0, 0, 10, 10, 0, 0, baseClass.instance, this);
+  if (!handle) {
+    throw rdr::SystemException("unable to create WMNotifier window instance", GetLastError());
+  }
+  vlog.debug("created window \"%s\" (%x)", (const char*)CStr(name.buf), handle);
+}
+
+MsgWindow::~MsgWindow() {
+  if (handle)
+    DestroyWindow(handle);
+  vlog.debug("destroyed window \"%s\" (%x)", (const char*)CStr(name.buf), handle); 
+}
+
+LRESULT
+MsgWindow::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  return SafeDefWindowProc(getHandle(), msg, wParam, lParam);
+}
\ No newline at end of file
diff --git a/rfb_win32/MsgWindow.h b/rfb_win32/MsgWindow.h
new file mode 100644
index 0000000..94baca3
--- /dev/null
+++ b/rfb_win32/MsgWindow.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- MsgWindow.h
+
+// Base-class for any hidden message-handling windows used in the rfb::win32
+// implementation.
+
+#ifndef __RFB_WIN32_MSG_WINDOW_H__
+#define __RFB_WIN32_MSG_WINDOW_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb_win32/TCharArray.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class MsgWindow {
+    public:
+      MsgWindow(const TCHAR* _name);
+      virtual ~MsgWindow();
+
+      const TCHAR* getName() {return name.buf;}
+      HWND getHandle() const {return handle;}
+
+      virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+    protected:
+      TCharArray name;
+      HWND handle;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_MSG_WINDOW_H__
diff --git a/rfb_win32/OSVersion.cxx b/rfb_win32/OSVersion.cxx
new file mode 100644
index 0000000..1976098
--- /dev/null
+++ b/rfb_win32/OSVersion.cxx
@@ -0,0 +1,47 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- OSVersion.cxx
+
+#include <rfb_win32/OSVersion.h>
+#include <rdr/Exception.h>
+#include <tchar.h>
+
+using namespace rfb;
+using namespace win32;
+
+
+OSVersionInfo::OSVersionInfo() {
+  // Get OS Version Info
+  ZeroMemory(static_cast<OSVERSIONINFO*>(this), sizeof(this));
+  dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  if (!GetVersionEx(this))
+    throw rdr::SystemException("unable to get system version info", GetLastError());
+
+  // Set the special extra flags
+  isPlatformNT = dwPlatformId == VER_PLATFORM_WIN32_NT;
+  isPlatformWindows = dwPlatformId == VER_PLATFORM_WIN32_WINDOWS;
+
+  cannotSwitchDesktop = isPlatformNT && (dwMajorVersion==4) &&
+    ((_tcscmp(szCSDVersion, _T("")) == 0) ||
+     (_tcscmp(szCSDVersion, _T("Service Pack 1")) == 0) ||
+     (_tcscmp(szCSDVersion, _T("Service Pack 2")) == 0));
+
+}
+
+OSVersionInfo rfb::win32::osVersion;
diff --git a/rfb_win32/OSVersion.h b/rfb_win32/OSVersion.h
new file mode 100644
index 0000000..1d52943
--- /dev/null
+++ b/rfb_win32/OSVersion.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- OSVersion.h
+
+// Operating system version info.
+// GetVersionInfo is called once at process initialisation, and any
+// extra flags (such as isWinNT) are calculated and saved at that
+// point.  It is assumed that the OS Version seldom changes during a
+// program's execution...
+
+#ifndef __RFB_WIN32_OS_VERSION_H__
+#define __RFB_WIN32_OS_VERSION_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    extern struct OSVersionInfo : OSVERSIONINFO {
+      OSVersionInfo();
+
+      // Is the OS one of the NT family (NT 3.51, NT4.0, 2K, XP, etc.)?
+      bool isPlatformNT;
+      // Is one of the Windows family?
+      bool isPlatformWindows;
+
+      // Is this OS one of those that blue-screens when grabbing another desktop (NT4 pre SP3)?
+      bool cannotSwitchDesktop;
+
+    } osVersion;
+
+  };
+
+};
+
+#endif // __RFB_WIN32_OS_VERSION_H__
diff --git a/rfb_win32/RegConfig.cxx b/rfb_win32/RegConfig.cxx
new file mode 100644
index 0000000..fcb309b
--- /dev/null
+++ b/rfb_win32/RegConfig.cxx
@@ -0,0 +1,151 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- RegConfig.cxx
+
+#include <malloc.h>
+
+#include <rfb_win32/RegConfig.h>
+#include <rfb/LogWriter.h>
+#include <rfb/util.h>
+#include <rdr/HexOutStream.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+
+static LogWriter vlog("RegConfig");
+
+
+class rfb::win32::RegReaderThread : public Thread {
+public:
+  RegReaderThread(RegistryReader& reader, const HKEY key);
+  ~RegReaderThread();
+  virtual void run();
+  virtual Thread* join();
+protected:
+  RegistryReader& reader;
+  RegKey key;
+  HANDLE event;
+};
+
+RegReaderThread::RegReaderThread(RegistryReader& reader_, const HKEY key_) : Thread("RegConfig"), reader(reader_), key(key_) {
+}
+
+RegReaderThread::~RegReaderThread() {
+}
+
+void
+RegReaderThread::run() {
+  vlog.debug("RegReaderThread started");
+  while (key) {
+    // - Wait for changes
+    vlog.debug("waiting for changes");
+    key.awaitChange(true, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET);
+
+    // - Load settings
+    RegistryReader::loadRegistryConfig(key);
+
+    // - Notify specified thread of changes
+    if (reader.notifyThread)
+      PostThreadMessage(reader.notifyThread->getThreadId(),
+        reader.notifyMsg.message, 
+        reader.notifyMsg.wParam, 
+        reader.notifyMsg.lParam);
+    else if (reader.notifyWindow)
+      PostMessage(reader.notifyWindow,
+        reader.notifyMsg.message, 
+        reader.notifyMsg.wParam, 
+        reader.notifyMsg.lParam);
+  }
+}
+
+Thread*
+RegReaderThread::join() {
+  RegKey old_key = key;
+  key.close();
+  if ((HKEY)old_key) {
+    // *** Closing the key doesn't always seem to work
+    //     Writing to it always will, instead...
+    vlog.debug("closing key");
+    old_key.setString(_T("dummy"), _T(""));
+  }
+  return Thread::join();
+}
+
+
+RegistryReader::RegistryReader() : thread(0), notifyThread(0) {
+  memset(&notifyMsg, 0, sizeof(notifyMsg));
+}
+
+RegistryReader::~RegistryReader() {
+  if (thread) delete thread->join();
+}
+
+bool RegistryReader::setKey(const HKEY rootkey, const TCHAR* keyname) {
+  if (thread) delete thread->join();
+  thread = 0;
+  
+  RegKey key;
+  try {
+    key.createKey(rootkey, keyname);
+    loadRegistryConfig(key);
+  } catch (rdr::Exception& e) {
+    vlog.debug(e.str());
+    return false;
+  }
+  thread = new RegReaderThread(*this, key);
+  if (thread) thread->start();
+  return true;
+}
+
+void
+RegistryReader::loadRegistryConfig(RegKey& key) {
+  DWORD i = 0;
+  try {
+    while (1) {
+      TCharArray name = tstrDup(key.getValueName(i++));
+      if (!name.buf) break;
+      TCharArray value = key.getRepresentation(name.buf);
+      if (!value.buf || !Configuration::setParam(CStr(name.buf), CStr(value.buf)))
+        vlog.info("unable to process %s", CStr(name.buf));
+    }
+  } catch (rdr::SystemException& e) {
+    if (e.err != 6)
+      vlog.error(e.str());
+  }
+}
+
+bool RegistryReader::setNotifyThread(Thread* thread, UINT winMsg, WPARAM wParam, LPARAM lParam) {
+  notifyMsg.message = winMsg;
+  notifyMsg.wParam = wParam;
+  notifyMsg.lParam = lParam;
+  notifyThread = thread;
+  notifyWindow = 0;
+  return true;
+}
+
+bool RegistryReader::setNotifyWindow(HWND window, UINT winMsg, WPARAM wParam, LPARAM lParam) {
+  notifyMsg.message = winMsg;
+  notifyMsg.wParam = wParam;
+  notifyMsg.lParam = lParam;
+  notifyWindow = window;
+  notifyThread = 0;
+  return true;
+}
+
diff --git a/rfb_win32/RegConfig.h b/rfb_win32/RegConfig.h
new file mode 100644
index 0000000..3fced85
--- /dev/null
+++ b/rfb_win32/RegConfig.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- RegConfig.h
+
+// Class which monitors the registry and reads in the registry settings
+// whenever they change, or are added or removed.
+
+#ifndef __RFB_WIN32_REG_CONFIG_H__
+#define __RFB_WIN32_REG_CONFIG_H__
+
+#include <rfb/Threading.h>
+#include <rfb/Configuration.h>
+
+#include <rfb_win32/Registry.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class RegistryReader {
+    public:
+      RegistryReader();
+      ~RegistryReader();
+      bool setKey(const HKEY rootkey, const TCHAR* keyname);
+      bool setNotifyThread(Thread* thread, UINT winMsg, WPARAM wParam=0, LPARAM lParam=0);
+      bool setNotifyWindow(HWND window, UINT winMsg, WPARAM wParam=0, LPARAM lParam=0);
+      static void loadRegistryConfig(RegKey& key);
+    protected:
+      friend class RegReaderThread;
+      Thread* thread;
+      Thread* notifyThread;
+      HWND notifyWindow;
+      MSG notifyMsg;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_REG_CONFIG_H__
diff --git a/rfb_win32/Registry.cxx b/rfb_win32/Registry.cxx
new file mode 100644
index 0000000..de9238f
--- /dev/null
+++ b/rfb_win32/Registry.cxx
@@ -0,0 +1,272 @@
+/* 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.
+ */
+
+// -=- Registry.cxx
+
+#include <rfb/LogWriter.h>
+#include <rfb_win32/Registry.h>
+#include <rdr/MemOutStream.h>
+#include <rdr/HexOutstream.h>
+#include <rdr/HexInStream.h>
+#include <rfb_win32/Security.h>
+
+#include <stdlib.h>
+
+// These flags are required to control access control inheritance,
+// but are not defined by VC6's headers.  These definitions comes
+// from the Microsoft Platform SDK.
+#ifndef PROTECTED_DACL_SECURITY_INFORMATION
+#define PROTECTED_DACL_SECURITY_INFORMATION     (0x80000000L)
+#endif
+#ifndef UNPROTECTED_DACL_SECURITY_INFORMATION
+#define UNPROTECTED_DACL_SECURITY_INFORMATION     (0x20000000L)
+#endif
+
+
+using namespace rfb;
+using namespace rfb::win32;
+
+
+static LogWriter vlog("Registry");
+
+
+RegKey::RegKey() : key(0), freeKey(false), valueNameBufLen(0) {}
+
+RegKey::RegKey(const HKEY k) : key(0), freeKey(false), valueNameBufLen(0) {
+  LONG result = RegOpenKeyEx(k, 0, 0, KEY_ALL_ACCESS, &key);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegOpenKeyEx(HKEY)", result);
+  vlog.debug("duplicated %x to %x", k, key);
+  freeKey = true;
+}
+
+RegKey::RegKey(const RegKey& k) : key(0), freeKey(false), valueNameBufLen(0) {
+  LONG result = RegOpenKeyEx(k.key, 0, 0, KEY_ALL_ACCESS, &key);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegOpenKeyEx(RegKey&)", result);
+  vlog.debug("duplicated %x to %x", k.key, key);
+  freeKey = true;
+}
+
+RegKey::~RegKey() {
+  close();
+}
+
+
+void RegKey::setHKEY(HKEY k, bool fK) {
+  close();
+  freeKey = fK;
+  key = k;
+}
+
+
+bool RegKey::createKey(const RegKey& root, const TCHAR* name) {
+  close();
+  LONG result = RegCreateKey(root.key, name, &key);
+  if (result != ERROR_SUCCESS) {
+    vlog.error("RegCreateKey(%x, %s): %x", root.key, name, result);
+    throw rdr::SystemException("RegCreateKeyEx", result);
+  }
+  freeKey = true;
+  return true;
+}
+
+void RegKey::openKey(const RegKey& root, const TCHAR* name, bool readOnly) {
+  close();
+  LONG result = RegOpenKeyEx(root.key, name, 0, readOnly ? KEY_READ : KEY_ALL_ACCESS, &key);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegOpenKeyEx (open)", result);
+  freeKey = true;
+}
+
+void RegKey::setDACL(const PACL acl, bool inherit) {
+  DWORD result;
+  typedef DWORD (WINAPI *_SetSecurityInfo_proto) (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID, PSID, PACL, PACL);
+  DynamicFn<_SetSecurityInfo_proto> _SetSecurityInfo(_T("advapi32.dll"), "SetSecurityInfo");
+  if (!_SetSecurityInfo.isValid())
+    throw rdr::SystemException("RegKey::setDACL failed", ERROR_CALL_NOT_IMPLEMENTED);
+  if ((result = (*_SetSecurityInfo)(key, SE_REGISTRY_KEY,
+    DACL_SECURITY_INFORMATION |
+    (inherit ? UNPROTECTED_DACL_SECURITY_INFORMATION : PROTECTED_DACL_SECURITY_INFORMATION),
+    0, 0, acl, 0)) != ERROR_SUCCESS)
+    throw rdr::SystemException("RegKey::setDACL failed", result);
+}
+
+void RegKey::close() {
+  if (freeKey) {
+    RegCloseKey(key);
+    key = 0;
+  }
+}
+
+void RegKey::deleteKey(const TCHAR* name) const {
+  LONG result = RegDeleteKey(key, name);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegDeleteKey", result);
+}
+
+void RegKey::deleteValue(const TCHAR* name) const {
+  LONG result = RegDeleteValue(key, name);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegDeleteValue", result);
+}
+
+void RegKey::awaitChange(bool watchSubTree, DWORD filter) const {
+  LONG result = RegNotifyChangeKeyValue(key, watchSubTree, filter, 0, FALSE);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegNotifyChangeKeyValue", result);
+}
+
+
+RegKey::operator HKEY() const {return key;}
+
+
+void RegKey::setExpandString(const TCHAR* valname, const TCHAR* value) const {
+  LONG result = RegSetValueEx(key, valname, 0, REG_EXPAND_SZ, (const BYTE*)value, (_tcslen(value)+1)*sizeof(TCHAR));
+  if (result != ERROR_SUCCESS) throw rdr::SystemException("setExpandString", result);
+}
+
+void RegKey::setString(const TCHAR* valname, const TCHAR* value) const {
+  LONG result = RegSetValueEx(key, valname, 0, REG_SZ, (const BYTE*)value, (_tcslen(value)+1)*sizeof(TCHAR));
+  if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result);
+}
+
+void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const {
+  LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length);
+  if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result);
+}
+
+void RegKey::setInt(const TCHAR* valname, int value) const {
+  LONG result = RegSetValueEx(key, valname, 0, REG_DWORD, (const BYTE*)&value, sizeof(value));
+  if (result != ERROR_SUCCESS) throw rdr::SystemException("setInt", result);
+}
+
+void RegKey::setBool(const TCHAR* valname, bool value) const {
+  setInt(valname, value ? 1 : 0);
+}
+
+TCHAR* RegKey::getString(const TCHAR* valname) const {return getRepresentation(valname);}
+TCHAR* RegKey::getString(const TCHAR* valname, const TCHAR* def) const {
+  try {
+    return getString(valname);
+  } catch(rdr::Exception) {
+    return tstrDup(def);
+  }
+}
+
+void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const {
+  TCharArray hex = getRepresentation(valname);
+  if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length))
+    throw rdr::Exception("getBinary failed");
+}
+void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const {
+  try {
+    getBinary(valname, data, length);
+  } catch(rdr::Exception) {
+    if (deflen) {
+      *data = new char[deflen];
+      memcpy(*data, def, deflen);
+    } else
+      *data = 0;
+    *length = deflen;
+  }
+}
+
+int RegKey::getInt(const TCHAR* valname) const {
+  TCharArray tmp = getRepresentation(valname);
+  return _ttoi(tmp.buf);
+}
+int RegKey::getInt(const TCHAR* valname, int def) const {
+  try {
+    return getInt(valname);
+  } catch(rdr::Exception) {
+    return def;
+  }
+}
+
+bool RegKey::getBool(const TCHAR* valname) const {
+  return getInt(valname) > 0;
+}
+bool RegKey::getBool(const TCHAR* valname, bool def) const {
+  return getInt(valname, def ? 1 : 0) > 0;
+}
+
+TCHAR* RegKey::getRepresentation(const TCHAR* valname) const {
+  DWORD type, length;
+  LONG result = RegQueryValueEx(key, valname, 0, &type, 0, &length);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("get registry value length", result);
+  CharArray data(length);
+  result = RegQueryValueEx(key, valname, 0, &type, (BYTE*)data.buf, &length);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("get registry value", result);
+
+  switch (type) {
+  case REG_BINARY:
+    {
+      TCharArray hex = rdr::HexOutStream::binToHexStr(data.buf, length);
+      return hex.takeBuf();
+    }
+  case REG_SZ:
+    if (length) {
+      // We must terminate the string, just to be sure.  Stupid Win32...
+      int len = length/sizeof(TCHAR);
+      TCharArray str(len+1);
+      memcpy(str.buf, data.buf, length);
+      str.buf[len] = 0;
+      return str.takeBuf();
+    } else {
+      return tstrDup(_T(""));
+    }
+  case REG_DWORD:
+    {
+      TCharArray tmp(16);
+      _stprintf(tmp.buf, _T("%u"), *((DWORD*)data.buf));
+      return tmp.takeBuf();
+    }
+  default:
+    throw rdr::Exception("unsupported registry type");
+  }
+}
+
+bool RegKey::isValue(const TCHAR* valname) const {
+  try {
+    TCharArray tmp = getRepresentation(valname);
+    return true;
+  } catch(rdr::Exception) {
+    return false;
+  }
+}
+
+const TCHAR* RegKey::getValueName(int i) {
+  DWORD maxValueNameLen;
+  LONG result = RegQueryInfoKey(key, 0, 0, 0, 0, 0, 0, 0, &maxValueNameLen, 0, 0, 0);
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegQueryInfoKey", result);
+  if (valueNameBufLen < maxValueNameLen + 1) {
+    valueNameBufLen = maxValueNameLen + 1;
+    delete [] valueName.buf;
+    valueName.buf = new TCHAR[valueNameBufLen];
+  }
+  DWORD length = valueNameBufLen;
+  result = RegEnumValue(key, i, valueName.buf, &length, NULL, 0, 0, 0);
+  if (result == ERROR_NO_MORE_ITEMS) return 0;
+  if (result != ERROR_SUCCESS)
+    throw rdr::SystemException("RegEnumValue", result);
+  return valueName.buf;
+}
diff --git a/rfb_win32/Registry.h b/rfb_win32/Registry.h
new file mode 100644
index 0000000..1998c49
--- /dev/null
+++ b/rfb_win32/Registry.h
@@ -0,0 +1,111 @@
+/* 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.
+ */
+// -=- Registry.h
+
+// C++ wrappers around the Win32 Registry APIs
+
+#ifndef __RFB_WIN32_REGISTRY_H__
+#define __RFB_WIN32_REGISTRY_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb_win32/Security.h>
+#include <rfb/util.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class RegKey {
+    public:
+      // No key open
+      RegKey();
+
+      // Duplicate the specified existing key
+      RegKey(const HKEY k);
+      RegKey(const RegKey& k);
+
+      // Calls close() internally
+      ~RegKey();
+
+      void setHKEY(HKEY key, bool freeKey);
+    protected:
+      HKEY operator=(const RegKey& k);
+      HKEY operator=(HKEY k);
+    public:
+
+      // Returns true if key was created, false if already existed
+      bool createKey(const RegKey& root, const TCHAR* name);
+
+      // Opens key if it exists, or raises an exception if not
+      void openKey(const RegKey& root, const TCHAR* name, bool readOnly=false);
+
+      // Set the (discretionary) access control list for the key
+      void setDACL(const PACL acl, bool inheritFromParent=true);
+
+      // Closes current key, if required
+      void close();
+
+      // Delete a subkey/value
+      void deleteKey(const TCHAR* name) const;
+      void deleteValue(const TCHAR* name) const;
+
+
+      void awaitChange(bool watchSubTree, DWORD filter) const;
+
+      void setExpandString(const TCHAR* valname, const TCHAR* s) const;
+      void setString(const TCHAR* valname, const TCHAR* s) const;
+      void setBinary(const TCHAR* valname, const void* data, int length) const;
+      void setInt(const TCHAR* valname, int i) const;
+      void setBool(const TCHAR* valname, bool b) const;
+
+      TCHAR* getString(const TCHAR* valname) const;
+      TCHAR* getString(const TCHAR* valname, const TCHAR* def) const;
+
+      void getBinary(const TCHAR* valname, void** data, int* length) const;
+      void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const;
+
+      int getInt(const TCHAR* valname) const;
+      int getInt(const TCHAR* valname, int def) const;
+
+      bool getBool(const TCHAR* valname) const;
+      bool getBool(const TCHAR* valname, bool def) const;
+
+      TCHAR* getRepresentation(const TCHAR* valname) const;
+
+      bool isValue(const TCHAR* valname) const;
+
+      // Get the name of value number "i"
+      // If there are fewer than "i" values then return 0
+      // NAME IS OWNED BY RegKey OBJECT!
+      const TCHAR* getValueName(int i);
+
+      operator HKEY() const;
+    protected:
+      HKEY key;
+      bool freeKey;
+      TCharArray valueName;
+      DWORD valueNameBufLen;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_REG_CONFIG_H__
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);
+}
diff --git a/rfb_win32/SDisplay.h b/rfb_win32/SDisplay.h
new file mode 100644
index 0000000..c4c08bf
--- /dev/null
+++ b/rfb_win32/SDisplay.h
@@ -0,0 +1,149 @@
+/* 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.h
+//
+// The SDisplay class encapsulates a system display.
+
+// *** THIS INTERFACE NEEDS TIDYING TO SEPARATE COORDINATE SYSTEMS BETTER ***
+
+#ifndef __RFB_SDISPLAY_H__
+#define __RFB_SDISPLAY_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <rfb/SDesktop.h>
+#include <rfb/UpdateTracker.h>
+#include <rfb/Configuration.h>
+#include <rfb/util.h>
+
+#include <winsock2.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/SocketManager.h>
+#include <rfb_win32/DeviceFrameBuffer.h>
+#include <rfb_win32/SInput.h>
+#include <rfb_win32/Clipboard.h>
+#include <rfb_win32/MsgWindow.h>
+#include <rfb_win32/WMCursor.h>
+#include <rfb_win32/WMHooks.h>
+#include <rfb_win32/WMNotifier.h>
+#include <rfb_win32/WMWindowCopyRect.h>
+#include <rfb_win32/WMPoller.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    //
+    // -=- SDisplay
+    //
+
+    class SDisplayCore;
+
+    class SDisplay : public SDesktop,
+      WMMonitor::Notifier,
+      Clipboard::Notifier,
+      UpdateTracker,
+      public SocketManager::EventHandler
+    {
+    public:
+      SDisplay(const TCHAR* device=0);
+      virtual ~SDisplay();
+
+      // -=- SDesktop interface
+
+      virtual void start(VNCServer* vs);
+      virtual void stop();
+      virtual void pointerEvent(const Point& pos, rdr::U8 buttonmask);
+      virtual void keyEvent(rdr::U32 key, bool down);
+      virtual void clientCutText(const char* str, int len);
+      virtual void framebufferUpdateRequest();
+      virtual Point getFbSize();
+
+      // -=- UpdateTracker
+
+      virtual void add_changed(const Region& rgn);
+      virtual void add_copied(const Region& dest, const Point& delta);
+
+      // -=- Clipboard
+      
+      virtual void notifyClipboardChanged(const char* text, int len);
+
+      // -=- Display events
+      
+      virtual void notifyDisplayEvent(WMMonitor::Notifier::DisplayEventType evt);
+
+      // -=- EventHandler interface
+
+      HANDLE getUpdateEvent() {return updateEvent;}
+      virtual bool processEvent(HANDLE event);
+
+      // -=- Notification of whether or not SDisplay is started
+
+      void setStatusLocation(bool* status) {statusLocation = status;}
+
+      friend class SDisplayCore;
+
+      static BoolParameter use_hooks;
+      static BoolParameter disableLocalInputs;
+      static StringParameter disconnectAction;
+      static BoolParameter removeWallpaper;
+      static BoolParameter removePattern;
+      static BoolParameter disableEffects;
+
+    protected:
+      void restart();
+      void recreatePixelBuffer();
+      bool flushChangeTracker();  // true if flushed, false if empty
+
+      void triggerUpdate();
+
+      VNCServer* server;
+
+      // -=- Display pixel buffer
+      DeviceFrameBuffer* pb;
+      TCharArray deviceName;
+      HDC device;
+      bool releaseDevice;
+
+      // -=- The coordinates of Window's entire virtual Screen
+      Rect screenRect;
+
+      // -=- All changes are collected in Display coords and merged
+      SimpleUpdateTracker change_tracker;
+
+      // -=- Internal SDisplay implementation
+      SDisplayCore* core;
+
+      // -=- Cursor
+      WMCursor::Info old_cursor;
+      Region old_cursor_region;
+      Point cursor_renderpos;
+
+      // -=- Event signalled to trigger an update to be flushed
+      Handle updateEvent;
+
+      // -=- Where to write the active/inactive indicator to
+      bool* statusLocation;
+    };
+
+  }
+}
+
+#endif // __RFB_SDISPLAY_H__
diff --git a/rfb_win32/SInput.cxx b/rfb_win32/SInput.cxx
new file mode 100644
index 0000000..457a861
--- /dev/null
+++ b/rfb_win32/SInput.cxx
@@ -0,0 +1,459 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- SInput.cxx
+//
+// A number of routines that accept VNC input event data and perform
+// the appropriate actions under Win32
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_CURRENCY
+#include <rfb/keysymdef.h>
+
+// * Force the windows headers to include all the SendInput stuff
+#define _WIN32_WINNT 0x401
+
+#include <rfb_win32/SInput.h>
+#include <rfb_win32/Service.h>
+#include <rfb/LogWriter.h>
+#include <rfb_win32/OSVersion.h>
+#include <rfb_win32/Win32Util.h>
+#include "keymap.h"
+
+using namespace rfb;
+
+static LogWriter vlog("SInput");
+
+
+typedef UINT (WINAPI *_SendInput_proto)(UINT, LPINPUT, int);
+static win32::DynamicFn<_SendInput_proto> _SendInput(_T("user32.dll"), "SendInput");
+
+//
+// -=- Pointer implementation for Win32
+//
+
+static DWORD buttonDownMapping[8] = {
+  MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN,
+  MOUSEEVENTF_WHEEL, MOUSEEVENTF_WHEEL, 0, 0, 0
+};
+
+static DWORD buttonUpMapping[8] = {
+  MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTUP,
+  MOUSEEVENTF_WHEEL, MOUSEEVENTF_WHEEL, 0, 0, 0
+};
+
+static DWORD buttonDataMapping[8] = {
+  0, 0, 0, 120, -120, 0, 0, 0
+};
+
+win32::SPointer::SPointer()
+  : last_buttonmask(0)
+{
+}
+
+void
+win32::SPointer::pointerEvent(const Point& pos, rdr::U8 buttonmask)
+{
+  // - We are specifying absolute coordinates
+  DWORD flags = MOUSEEVENTF_ABSOLUTE;
+
+  // - Has the pointer moved since the last event?
+  if (!last_position.equals(pos))
+    flags |= MOUSEEVENTF_MOVE;
+
+  // - If the system swaps left and right mouse buttons then we must
+  //   swap them here to negate the effect, so that we do the actual
+  //   action we mean to do
+  if (::GetSystemMetrics(SM_SWAPBUTTON)) {
+    bool leftDown = buttonmask & 1;
+    bool rightDown = buttonmask & 4;
+    buttonmask = (buttonmask & ~(1 | 4));
+    if (leftDown) buttonmask |= 4;
+    if (rightDown) buttonmask |= 1;
+  }
+
+  DWORD data = 0;
+  for (int i = 0; i < 8; i++) {
+    if ((buttonmask & (1<<i)) != (last_buttonmask & (1<<i))) {
+      if (buttonmask & (1<<i)) {
+        flags |= buttonDownMapping[i];
+        if (buttonDataMapping[i]) {
+          if (data) vlog.info("warning - two buttons set mouse_event data field");
+          data = buttonDataMapping[i];
+        }
+      } else {
+        flags |= buttonUpMapping[i];
+      }
+    }
+  }
+
+  last_position = pos;
+  last_buttonmask = buttonmask;
+
+  Rect primaryDisplay(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
+  if (primaryDisplay.contains(pos)) {
+    // mouse_event wants coordinates specified as a proportion of the
+    // primary display's size, scaled to the range 0 to 65535
+    Point scaled;
+    scaled.x = (pos.x * 65535) / (primaryDisplay.width()-1);
+    scaled.y = (pos.y * 65535) / (primaryDisplay.height()-1);
+    ::mouse_event(flags, scaled.x, scaled.y, data, 0);
+  } else {
+    // The event lies outside the primary monitor.  Under Win2K, we can just use
+    // SendInput, which allows us to provide coordinates scaled to the virtual desktop.
+    // SendInput is available on all multi-monitor-aware platforms.
+#ifdef SM_CXVIRTUALSCREEN
+    if (osVersion.isPlatformNT) {
+      if (!_SendInput.isValid())
+        throw rdr::Exception("SendInput not available");
+      INPUT evt;
+      evt.type = INPUT_MOUSE;
+      Point vPos(pos.x-GetSystemMetrics(SM_XVIRTUALSCREEN),
+                 pos.y-GetSystemMetrics(SM_YVIRTUALSCREEN));
+      evt.mi.dx = (vPos.x * 65535) / (GetSystemMetrics(SM_CXVIRTUALSCREEN)-1);
+      evt.mi.dy = (vPos.y * 65535) / (GetSystemMetrics(SM_CYVIRTUALSCREEN)-1);
+      evt.mi.dwFlags = flags | MOUSEEVENTF_VIRTUALDESK;
+      evt.mi.dwExtraInfo = 0;
+      evt.mi.mouseData = data;
+      evt.mi.time = 0;
+      if ((*_SendInput)(1, &evt, sizeof(evt)) != 1)
+        throw rdr::SystemException("SendInput", GetLastError());
+    } else {
+      // Under Win9x, this is not addressable by either mouse_event or SendInput
+      // *** STUPID KLUDGY HACK ***
+      POINT cursorPos; GetCursorPos(&cursorPos);
+      ULONG oldSpeed, newSpeed = 10;
+      ULONG mouseInfo[3];
+      if (flags & MOUSEEVENTF_MOVE) {
+        flags &= ~MOUSEEVENTF_ABSOLUTE;
+        SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0);
+        SystemParametersInfo(SPI_GETMOUSESPEED, 0, &oldSpeed, 0);
+        vlog.debug("SPI_GETMOUSE %d, %d, %d, speed %d", mouseInfo[0], mouseInfo[1], mouseInfo[2], oldSpeed);
+        ULONG idealMouseInfo[] = {10, 0, 0};
+        SystemParametersInfo(SPI_SETMOUSESPEED, 0, &newSpeed, 0);
+        SystemParametersInfo(SPI_SETMOUSE, 0, &idealMouseInfo, 0);
+      }
+      ::mouse_event(flags, pos.x-cursorPos.x, pos.y-cursorPos.y, data, 0);
+      if (flags & MOUSEEVENTF_MOVE) {
+        SystemParametersInfo(SPI_SETMOUSE, 0, &mouseInfo, 0);
+        SystemParametersInfo(SPI_SETMOUSESPEED, 0, &oldSpeed, 0);
+      }
+    }
+#endif
+  }
+}
+
+//
+// -=- Keyboard implementation
+//
+
+BoolParameter rfb::win32::SKeyboard::deadKeyAware("DeadKeyAware",
+  "Whether to assume the viewer has already interpreted dead key sequences "
+  "into latin-1 characters", true);
+
+static bool oneShift;
+
+// The keysymToAscii table transforms a couple of awkward keysyms into their
+// ASCII equivalents.
+struct  keysymToAscii_t {
+  rdr::U32 keysym;
+  rdr::U8 ascii;
+};
+
+keysymToAscii_t keysymToAscii[] = {
+  { XK_KP_Space, ' ' },
+  { XK_KP_Equal, '=' },
+};
+
+rdr::U8 latin1DeadChars[] = {
+  XK_grave, XK_acute, XK_asciicircum, XK_diaeresis, XK_degree, XK_cedilla,
+  XK_asciitilde
+};
+
+struct latin1ToDeadChars_t {
+  rdr::U8 latin1Char;
+  rdr::U8 deadChar;
+  rdr::U8 baseChar;
+};
+
+latin1ToDeadChars_t latin1ToDeadChars[] = {
+
+  { XK_Agrave, XK_grave, XK_A },
+  { XK_Egrave, XK_grave, XK_E },
+  { XK_Igrave, XK_grave, XK_I },
+  { XK_Ograve, XK_grave, XK_O },
+  { XK_Ugrave, XK_grave, XK_U },
+  { XK_agrave, XK_grave, XK_a },
+  { XK_egrave, XK_grave, XK_e },
+  { XK_igrave, XK_grave, XK_i },
+  { XK_ograve, XK_grave, XK_o},
+  { XK_ugrave, XK_grave, XK_u },
+
+  { XK_Aacute, XK_acute, XK_A },
+  { XK_Eacute, XK_acute, XK_E },
+  { XK_Iacute, XK_acute, XK_I },
+  { XK_Oacute, XK_acute, XK_O },
+  { XK_Uacute, XK_acute, XK_U },
+  { XK_Yacute, XK_acute, XK_Y },
+  { XK_aacute, XK_acute, XK_a },
+  { XK_eacute, XK_acute, XK_e },
+  { XK_iacute, XK_acute, XK_i },
+  { XK_oacute, XK_acute, XK_o},
+  { XK_uacute, XK_acute, XK_u },
+  { XK_yacute, XK_acute, XK_y },
+
+  { XK_Acircumflex, XK_asciicircum, XK_A },
+  { XK_Ecircumflex, XK_asciicircum, XK_E },
+  { XK_Icircumflex, XK_asciicircum, XK_I },
+  { XK_Ocircumflex, XK_asciicircum, XK_O },
+  { XK_Ucircumflex, XK_asciicircum, XK_U },
+  { XK_acircumflex, XK_asciicircum, XK_a },
+  { XK_ecircumflex, XK_asciicircum, XK_e },
+  { XK_icircumflex, XK_asciicircum, XK_i },
+  { XK_ocircumflex, XK_asciicircum, XK_o},
+  { XK_ucircumflex, XK_asciicircum, XK_u },
+
+  { XK_Adiaeresis, XK_diaeresis, XK_A },
+  { XK_Ediaeresis, XK_diaeresis, XK_E },
+  { XK_Idiaeresis, XK_diaeresis, XK_I },
+  { XK_Odiaeresis, XK_diaeresis, XK_O },
+  { XK_Udiaeresis, XK_diaeresis, XK_U },
+  { XK_adiaeresis, XK_diaeresis, XK_a },
+  { XK_ediaeresis, XK_diaeresis, XK_e },
+  { XK_idiaeresis, XK_diaeresis, XK_i },
+  { XK_odiaeresis, XK_diaeresis, XK_o},
+  { XK_udiaeresis, XK_diaeresis, XK_u },
+  { XK_ydiaeresis, XK_diaeresis, XK_y },
+
+  { XK_Aring, XK_degree, XK_A },
+  { XK_aring, XK_degree, XK_a },
+
+  { XK_Ccedilla, XK_cedilla, XK_C },
+  { XK_ccedilla, XK_cedilla, XK_c },
+
+  { XK_Atilde, XK_asciitilde, XK_A },
+  { XK_Ntilde, XK_asciitilde, XK_N },
+  { XK_Otilde, XK_asciitilde, XK_O },
+  { XK_atilde, XK_asciitilde, XK_a },
+  { XK_ntilde, XK_asciitilde, XK_n },
+  { XK_otilde, XK_asciitilde, XK_o },
+};
+
+// doKeyboardEvent wraps the system keybd_event function and attempts to find
+// the appropriate scancode corresponding to the supplied virtual keycode.
+
+inline void doKeyboardEvent(BYTE vkCode, DWORD flags) {
+  vlog.debug("vkCode 0x%x flags 0x%x", vkCode, flags);
+  keybd_event(vkCode, MapVirtualKey(vkCode, 0), flags, 0);
+}
+
+// KeyStateModifier is a class which helps simplify generating a "fake" press
+// or release of shift, ctrl, alt, etc.  An instance of the class is created
+// for every key which may need to be pressed or released.  Then either press()
+// or release() may be called to make sure that the corresponding key is in the
+// right state.  The destructor of the class automatically reverts to the
+// previous state.
+
+class KeyStateModifier {
+public:
+  KeyStateModifier(int vkCode_, int flags_=0)
+    : vkCode(vkCode_), flags(flags_), pressed(false), released(false)
+  {}
+  void press() {
+    if (!(GetAsyncKeyState(vkCode) & 0x8000)) {
+      doKeyboardEvent(vkCode, flags);
+      pressed = true;
+    }
+  }
+  void release() {
+    if (GetAsyncKeyState(vkCode) & 0x8000) {
+      doKeyboardEvent(vkCode, flags | KEYEVENTF_KEYUP);
+      released = true;
+    }
+  }
+  ~KeyStateModifier() {
+    if (pressed) {
+      doKeyboardEvent(vkCode, flags | KEYEVENTF_KEYUP);
+    } else if (released) {
+      doKeyboardEvent(vkCode, flags);
+    }
+  }
+  int vkCode;
+  int flags;
+  bool pressed;
+  bool released;
+};
+
+
+// doKeyEventWithModifiers() generates a key event having first "pressed" or
+// "released" the shift, ctrl or alt modifiers if necessary.
+
+void doKeyEventWithModifiers(BYTE vkCode, BYTE modifierState, bool down)
+{
+  KeyStateModifier ctrl(VK_CONTROL);
+  KeyStateModifier alt(VK_MENU);
+  KeyStateModifier shift(VK_SHIFT);
+
+  if (down) {
+    if (modifierState & 2) ctrl.press();
+    if (modifierState & 4) alt.press();
+    if (modifierState & 1) {
+      shift.press(); 
+    } else {
+      shift.release();
+    }
+  }
+  doKeyboardEvent(vkCode, down ? 0 : KEYEVENTF_KEYUP);
+}
+
+
+win32::SKeyboard::SKeyboard()
+{
+  oneShift = rfb::win32::osVersion.isPlatformWindows;
+  for (int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) {
+    vkMap[keymap[i].keysym] = keymap[i].vk;
+    extendedMap[keymap[i].keysym] = keymap[i].extended;
+  }
+
+  // Find dead characters for the current keyboard layout
+  // XXX how could we handle the keyboard layout changing?
+  BYTE keystate[256];
+  memset(keystate, 0, 256);
+  for (int j = 0; j < sizeof(latin1DeadChars); j++) {
+    SHORT s = VkKeyScan(latin1DeadChars[j]);
+    if (s != -1) {
+      BYTE vkCode = LOBYTE(s);
+      BYTE modifierState = HIBYTE(s);
+      keystate[VK_SHIFT] = (modifierState & 1) ? 0x80 : 0;
+      keystate[VK_CONTROL] = (modifierState & 2) ? 0x80 : 0;
+      keystate[VK_MENU] = (modifierState & 4) ? 0x80 : 0;
+      rdr::U8 chars[2];
+      int nchars = ToAscii(vkCode, 0, keystate, (WORD*)&chars, 0);
+      if (nchars < 0) {
+        vlog.debug("Found dead key 0x%x '%c'",
+                   latin1DeadChars[j], latin1DeadChars[j]);
+        deadChars.push_back(latin1DeadChars[j]);
+        ToAscii(vkCode, 0, keystate, (WORD*)&chars, 0);
+      }
+    }
+  }
+}
+
+
+void win32::SKeyboard::keyEvent(rdr::U32 keysym, bool down)
+{
+  for (int i = 0; i < sizeof(keysymToAscii) / sizeof(keysymToAscii_t); i++) {
+    if (keysymToAscii[i].keysym == keysym) {
+      keysym = keysymToAscii[i].ascii;
+      break;
+    }
+  }
+
+  if ((keysym >= 32 && keysym <= 126) ||
+      (keysym >= 160 && keysym <= 255))
+  {
+    // ordinary Latin-1 character
+
+    if (deadKeyAware) {
+      // Detect dead chars and generate the dead char followed by space so
+      // that we'll end up with the original char.
+      for (int i = 0; i < deadChars.size(); i++) {
+        if (keysym == deadChars[i]) {
+          SHORT dc = VkKeyScan(keysym);
+          if (dc != -1) {
+            if (down) {
+              vlog.info("latin-1 dead key: 0x%x vkCode 0x%x mod 0x%x "
+                        "followed by space", keysym, LOBYTE(dc), HIBYTE(dc));
+              doKeyEventWithModifiers(LOBYTE(dc), HIBYTE(dc), true);
+              doKeyEventWithModifiers(LOBYTE(dc), HIBYTE(dc), false);
+              doKeyEventWithModifiers(VK_SPACE, 0, true);
+              doKeyEventWithModifiers(VK_SPACE, 0, false);
+            }
+            return;
+          }
+        }
+      }
+    }
+
+    SHORT s = VkKeyScan(keysym);
+    if (s == -1) {
+      if (down) {
+        // not a single keypress - try synthesizing dead chars.
+        for (int j = 0;
+             j < sizeof(latin1ToDeadChars) / sizeof(latin1ToDeadChars_t);
+             j++) {
+          if (keysym == latin1ToDeadChars[j].latin1Char) {
+            for (int i = 0; i < deadChars.size(); i++) {
+              if (deadChars[i] == latin1ToDeadChars[j].deadChar) {
+                SHORT dc = VkKeyScan(latin1ToDeadChars[j].deadChar);
+                SHORT bc = VkKeyScan(latin1ToDeadChars[j].baseChar);
+                if (dc != -1 && bc != -1) {
+                  vlog.info("latin-1 key: 0x%x dead key vkCode 0x%x mod 0x%x "
+                            "followed by vkCode 0x%x mod 0x%x",
+                            keysym, LOBYTE(dc), HIBYTE(dc),
+                            LOBYTE(bc), HIBYTE(bc));
+                  doKeyEventWithModifiers(LOBYTE(dc), HIBYTE(dc), true);
+                  doKeyEventWithModifiers(LOBYTE(dc), HIBYTE(dc), false);
+                  doKeyEventWithModifiers(LOBYTE(bc), HIBYTE(bc), true);
+                  doKeyEventWithModifiers(LOBYTE(bc), HIBYTE(bc), false);
+                  return;
+                }
+                break;
+              }
+            }
+            break;
+          }
+        }
+        vlog.info("ignoring unrecognised Latin-1 keysym 0x%x",keysym);
+      }
+      return;
+    }
+
+    BYTE vkCode = LOBYTE(s);
+    BYTE modifierState = HIBYTE(s);
+    vlog.debug("latin-1 key: 0x%x vkCode 0x%x mod 0x%x down %d",
+               keysym, vkCode, modifierState, down);
+    doKeyEventWithModifiers(vkCode, modifierState, down);
+
+  } else {
+
+    // see if it's a recognised keyboard key, otherwise ignore it
+
+    if (vkMap.find(keysym) == vkMap.end()) {
+      vlog.info("ignoring unknown keysym 0x%x",keysym);
+      return;
+    }
+    BYTE vkCode = vkMap[keysym];
+    DWORD flags = 0;
+    if (extendedMap[keysym]) flags |= KEYEVENTF_EXTENDEDKEY;
+    if (!down) flags |= KEYEVENTF_KEYUP;
+
+    vlog.debug("keyboard key: keysym 0x%x vkCode 0x%x ext %d down %d",
+               keysym, vkCode, extendedMap[keysym], down);
+    if (down && (vkCode == VK_DELETE) &&
+        ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) &&
+        ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0))
+    {
+      rfb::win32::emulateCtrlAltDel();
+      return;
+    }
+
+    doKeyboardEvent(vkCode, flags);
+  }
+}
diff --git a/rfb_win32/SInput.h b/rfb_win32/SInput.h
new file mode 100644
index 0000000..dcd779e
--- /dev/null
+++ b/rfb_win32/SInput.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- Input.h
+//
+// A number of routines that accept VNC-style input event data and perform
+// the appropriate actions under Win32
+
+#ifndef __RFB_WIN32_INPUT_H__
+#define __RFB_WIN32_INPUT_H__
+
+#include <rfb/Rect.h>
+#include <rfb/Configuration.h>
+#include <rdr/types.h>
+#include <map>
+#include <vector>
+
+namespace rfb {
+
+  class CMsgWriter;
+
+  namespace win32 {
+
+    // -=- Pointer event handling
+
+    class SPointer {
+    public:
+      SPointer();
+      // - Create a pointer event at a the given coordinates, with the
+      //   specified button state.  The event must be specified using
+      //   Screen coordinates.
+      void pointerEvent(const Point& pos, rdr::U8 buttonmask);
+    protected:
+      Point last_position;
+      rdr::U8 last_buttonmask;
+    };
+
+    // -=- Keyboard event handling
+
+    class SKeyboard {
+    public:
+      SKeyboard();
+      void keyEvent(rdr::U32 key, bool down);
+      static BoolParameter deadKeyAware;
+    private:
+      std::map<rdr::U32,rdr::U8> vkMap;
+      std::map<rdr::U32,bool> extendedMap;
+      std::vector<rdr::U8> deadChars;
+    };
+
+  }; // win32
+
+}; // rfb
+
+#endif // __RFB_WIN32_INPUT_H__
diff --git a/rfb_win32/Security.h b/rfb_win32/Security.h
new file mode 100644
index 0000000..d92e314
--- /dev/null
+++ b/rfb_win32/Security.h
@@ -0,0 +1,198 @@
+/* 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.
+ */
+
+// Security.h
+
+// Wrapper classes for a few Windows NT security structures/functions
+// that are used by VNC
+
+#ifndef __RFB_WIN32_SECURITY_H__
+#define __RFB_WIN32_SECURITY_H__
+
+#include <rdr/types.h>
+#include <rdr/Exception.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/TCharArray.h>
+
+#include <lmcons.h>
+#include <Accctrl.h>
+#include <aclapi.h>
+
+#include <list>
+
+namespace rfb {
+
+  namespace win32 {
+
+    struct Trustee : public TRUSTEE {
+      Trustee(const TCHAR* name,
+              TRUSTEE_FORM form=TRUSTEE_IS_NAME,
+              TRUSTEE_TYPE type=TRUSTEE_IS_UNKNOWN)
+      {
+        pMultipleTrustee = 0;
+        MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+        TrusteeForm = form;
+        TrusteeType = type;
+        ptstrName = (TCHAR*)name;
+      }
+    };
+
+    struct ExplicitAccess : public EXPLICIT_ACCESS {
+      ExplicitAccess(const TCHAR* name,
+                     TRUSTEE_FORM type,
+                     DWORD perms,
+                     ACCESS_MODE mode,
+                     DWORD inherit=0)
+      {
+        Trustee = rfb::win32::Trustee(name, type);
+        grfAccessPermissions = perms;
+        grfAccessMode = mode;
+        grfInheritance = inherit;
+      }
+    };
+
+    // Helper class for building access control lists
+    struct AccessEntries {
+      AccessEntries() : entries(0), entry_count(0) {}
+      ~AccessEntries() {delete [] entries;}
+      void allocMinEntries(int count) {
+        if (count > entry_count) {
+          EXPLICIT_ACCESS* new_entries = new EXPLICIT_ACCESS[entry_count+1];
+          if (entries) {
+            memcpy(new_entries, entries, sizeof(EXPLICIT_ACCESS) * entry_count);
+            delete entries;
+          }
+          entries = new_entries;
+        }
+      }
+      void addEntry(const TCHAR* trusteeName,
+                    DWORD permissions,
+                    ACCESS_MODE mode)
+      {
+        allocMinEntries(entry_count+1);
+        ZeroMemory(&entries[entry_count], sizeof(EXPLICIT_ACCESS));
+        entries[entry_count] = ExplicitAccess(trusteeName, TRUSTEE_IS_NAME, permissions, mode);
+        entry_count++;
+      }
+      void addEntry(const PSID sid, DWORD permissions, ACCESS_MODE mode) {
+        allocMinEntries(entry_count+1);
+        ZeroMemory(&entries[entry_count], sizeof(EXPLICIT_ACCESS));
+        entries[entry_count] = ExplicitAccess((TCHAR*)sid, TRUSTEE_IS_SID, permissions, mode);
+        entry_count++;
+      }
+
+      EXPLICIT_ACCESS* entries;
+      int entry_count;
+    };
+
+    // Helper class for handling SIDs
+    struct Sid {
+      Sid() : sid(0) {}
+      Sid(PSID sid_) : sid(sid_) {}
+      ~Sid() {
+        if (sid) FreeSid(sid);
+      }
+      operator PSID() const {return sid;}
+      PSID operator=(const PSID sid_) {
+        if (sid) FreeSid(sid);
+        sid = sid_;
+      }
+
+      static PSID Administrators() {
+        PSID sid = 0;
+        SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY;
+        if (!AllocateAndInitializeSid(&ntAuth, 2,
+          SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
+          0, 0, 0, 0, 0, 0,
+          &sid)) 
+          throw rdr::SystemException("Sid::Administrators", GetLastError());
+        return sid;
+      }
+      static PSID SYSTEM() {
+        PSID sid = 0;
+        SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY;
+        if (!AllocateAndInitializeSid(&ntAuth, 1,
+          SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
+          &sid))
+          throw rdr::SystemException("Sid::SYSTEM", GetLastError());
+        return sid;
+      }
+
+    protected:
+      PSID sid;
+    };
+      
+    // Helper class for handling & freeing ACLs
+    struct AccessControlList : public LocalMem {
+      AccessControlList(int size) : LocalMem(size) {}
+      AccessControlList(PACL acl_=0) : LocalMem(acl_) {}
+      operator PACL() {return (PACL)ptr;}
+    };
+
+    // Create a new ACL based on supplied entries and, if supplied, existing ACL 
+    static PACL CreateACL(const AccessEntries& ae, PACL existing_acl=0) {
+      typedef DWORD (WINAPI *_SetEntriesInAcl_proto) (ULONG, PEXPLICIT_ACCESS, PACL, PACL*);
+#ifdef UNICODE
+      const char* fnName = "SetEntriesInAclW";
+#else
+      const char* fnName = "SetEntriesInAclA";
+#endif
+      DynamicFn<_SetEntriesInAcl_proto> _SetEntriesInAcl(_T("advapi32.dll"), fnName);
+      if (!_SetEntriesInAcl.isValid())
+        throw rdr::SystemException("CreateACL failed; no SetEntriesInAcl", ERROR_CALL_NOT_IMPLEMENTED);
+      PACL new_dacl;
+      DWORD result;
+      if ((result = (*_SetEntriesInAcl)(ae.entry_count, ae.entries, existing_acl, &new_dacl)) != ERROR_SUCCESS)
+        throw rdr::SystemException("SetEntriesInAcl", result);
+      return new_dacl;
+    }
+
+    // Helper class for memory-management of self-relative SecurityDescriptors
+    struct SecurityDescriptorPtr : LocalMem {
+      SecurityDescriptorPtr(int size) : LocalMem(size) {}
+      SecurityDescriptorPtr(PSECURITY_DESCRIPTOR sd_=0) : LocalMem(sd_) {}
+      PSECURITY_DESCRIPTOR takeSD() {return takePtr();}
+    };
+
+    // Create a new self-relative Security Descriptor, owned by SYSTEM/Administrators,
+    //   with the supplied DACL and no SACL.  The returned value can be assigned
+    //   to a SecurityDescriptorPtr to be managed.
+    static PSECURITY_DESCRIPTOR CreateSdWithDacl(const PACL dacl) {
+      SECURITY_DESCRIPTOR absSD;
+      if (!InitializeSecurityDescriptor(&absSD, SECURITY_DESCRIPTOR_REVISION))
+        throw rdr::SystemException("InitializeSecurityDescriptor", GetLastError());
+      Sid owner(Sid::SYSTEM());
+      if (!SetSecurityDescriptorOwner(&absSD, owner, FALSE))
+        throw rdr::SystemException("SetSecurityDescriptorOwner", GetLastError());
+      Sid group(Sid::Administrators());
+      if (!SetSecurityDescriptorGroup(&absSD, group, FALSE))
+        throw rdr::SystemException("SetSecurityDescriptorGroupp", GetLastError());
+      if (!SetSecurityDescriptorDacl(&absSD, TRUE, dacl, FALSE))
+        throw rdr::SystemException("SetSecurityDescriptorDacl", GetLastError());
+      DWORD sdSize = GetSecurityDescriptorLength(&absSD);
+      SecurityDescriptorPtr sd(sdSize);
+      if (!MakeSelfRelativeSD(&absSD, sd, &sdSize))
+        throw rdr::SystemException("MakeSelfRelativeSD", GetLastError());
+      return sd.takeSD();
+    }
+
+  }
+
+}
+
+#endif
diff --git a/rfb_win32/Service.cxx b/rfb_win32/Service.cxx
new file mode 100644
index 0000000..b00c290
--- /dev/null
+++ b/rfb_win32/Service.cxx
@@ -0,0 +1,638 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- Service.cxx
+
+#include <rfb_win32/Service.h>
+#include <rfb_win32/MsgWindow.h>
+#include <rfb_win32/Registry.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/OSVersion.h>
+#include <rfb/Threading.h>
+#include <rfb/LogWriter.h>
+#include <rfb/util.h>
+#include <rdr/Exception.h>
+
+#include <logmessages/messages.h>
+
+using namespace rdr;
+using namespace rfb;
+using namespace win32;
+
+static LogWriter vlog("Service");
+
+
+// - Internal service implementation functions
+
+Service* service = 0;
+
+VOID WINAPI serviceHandler(DWORD control) {
+  vlog.debug("service control %u", control);
+  switch (control) {
+  case SERVICE_CONTROL_INTERROGATE:
+    service->setStatus();
+    break;
+  case SERVICE_CONTROL_PARAMCHANGE:
+    service->readParams();
+    break;
+  case SERVICE_CONTROL_SHUTDOWN:
+    service->osShuttingDown();
+    break;
+  case SERVICE_CONTROL_STOP:
+    service->setStatus(SERVICE_STOP_PENDING);
+    service->stop();
+    break;
+  }
+}
+
+
+// -=- Message window derived class used under Win9x to implement stopService
+
+#define WM_SMSG_SERVICE_STOP WM_USER
+
+class ServiceMsgWindow : public MsgWindow {
+public:
+  ServiceMsgWindow(const TCHAR* name) : MsgWindow(name) {}
+  LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+    switch (msg) {
+    case WM_SMSG_SERVICE_STOP:
+      service->stop();
+      return TRUE;
+    }
+    return MsgWindow::processMessage(msg, wParam, lParam);
+  }
+
+  static const TCHAR* baseName;
+};
+
+const TCHAR* ServiceMsgWindow::baseName = _T("ServiceWindow:");
+
+
+// -=- Service main procedure, used under WinNT/2K/XP by the SCM
+
+VOID WINAPI serviceProc(DWORD dwArgc, LPTSTR* lpszArgv) {
+  vlog.debug("entering %s serviceProc", service->getName());
+  service->status_handle = RegisterServiceCtrlHandler(service->getName(), serviceHandler);
+  if (!service->status_handle) {
+    vlog.error("unable to register service control handler");
+    return;
+  }
+  service->setStatus(SERVICE_START_PENDING);
+  vlog.debug("entering %s serviceMain", service->getName());
+  service->status.dwWin32ExitCode = service->serviceMain(dwArgc, lpszArgv);
+  vlog.debug("leaving %s serviceMain", service->getName());
+  service->setStatus(SERVICE_STOPPED);
+}
+
+
+// -=- Service
+
+Service::Service(const TCHAR* name_) : name(name_) {
+  vlog.debug("Service");
+  status_handle = 0;
+  status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
+  status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
+  status.dwWin32ExitCode = NO_ERROR;
+  status.dwServiceSpecificExitCode = 0;
+  status.dwCheckPoint = 0;
+  status.dwWaitHint = 30000;
+  status.dwCurrentState = SERVICE_STOPPED;
+}
+
+void
+Service::start() {
+  if (osVersion.isPlatformNT) {
+    SERVICE_TABLE_ENTRY entry[2];
+    entry[0].lpServiceName = (TCHAR*)name;
+    entry[0].lpServiceProc = serviceProc;
+    entry[1].lpServiceName = NULL;
+    entry[1].lpServiceProc = NULL;
+    vlog.debug("entering dispatcher");
+    if (!SetProcessShutdownParameters(0x100, 0))
+      vlog.error("unable to set shutdown parameters: %d", GetLastError());
+    service = this;
+    if (!StartServiceCtrlDispatcher(entry))
+      throw SystemException("unable to start service", GetLastError());
+  } else {
+
+    // - Create the service window, so the service can be stopped
+    TCharArray wndName(_tcslen(getName()) + _tcslen(ServiceMsgWindow::baseName) + 1);
+    _tcscpy(wndName.buf, ServiceMsgWindow::baseName);
+    _tcscat(wndName.buf, getName());
+    ServiceMsgWindow service_window(wndName.buf);
+
+    // - Locate the RegisterServiceProcess function
+	  typedef DWORD (WINAPI * _RegisterServiceProcess_proto)(DWORD, DWORD);
+    DynamicFn<_RegisterServiceProcess_proto> _RegisterServiceProcess(_T("kernel32.dll"), "RegisterServiceProcess");
+    if (!_RegisterServiceProcess.isValid())
+      throw Exception("unable to find RegisterServiceProcess");
+
+    // - Run the service
+    (*_RegisterServiceProcess)(NULL, 1);
+    service = this;
+    serviceMain(0, 0);
+	  (*_RegisterServiceProcess)(NULL, 0);
+  }
+}
+
+void
+Service::setStatus() {
+  setStatus(status.dwCurrentState);
+}
+
+void
+Service::setStatus(DWORD state) {
+  if (!osVersion.isPlatformNT)
+    return;
+  if (status_handle == 0) {
+    vlog.debug("warning - cannot setStatus");
+    return;
+  }
+  status.dwCurrentState = state;
+  status.dwCheckPoint++;
+  if (!SetServiceStatus(status_handle, &status)) {
+    status.dwWin32ExitCode = GetLastError();
+    vlog.error("unable to set service status:%u", status.dwWin32ExitCode);
+    stop();
+  }
+  vlog.debug("set status to %u(%u)", state, status.dwCheckPoint);
+}
+
+Service::~Service() {
+  vlog.debug("~Service");
+  service = 0;
+}
+
+
+// Find out whether this process is running as the WinVNC service
+bool thisIsService() {
+  return service && (service->status.dwCurrentState != SERVICE_STOPPED);
+}
+
+
+// -=- Desktop handling code
+
+// Switch the current thread to the specified desktop
+static bool
+switchToDesktop(HDESK desktop) {
+  HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId());
+  if (!SetThreadDesktop(desktop)) {
+    vlog.debug("switchToDesktop failed:%u", GetLastError());
+    return false;
+  }
+  if (!CloseDesktop(old_desktop))
+    vlog.debug("unable to close old desktop:%u", GetLastError());
+  return true;
+}
+
+// Determine whether the thread's current desktop is the input one
+static bool
+inputDesktopSelected() {
+  HDESK current = GetThreadDesktop(GetCurrentThreadId());
+	HDESK input = OpenInputDesktop(0, FALSE,
+  	DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
+		DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
+		DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
+		DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
+  if (!input) {
+    vlog.debug("unable to OpenInputDesktop(1):%u", GetLastError());
+    return false;
+  }
+
+  DWORD size;
+  char currentname[256];
+  char inputname[256];
+
+  if (!GetUserObjectInformation(current, UOI_NAME, currentname, 256, &size)) {
+    vlog.debug("unable to GetUserObjectInformation(1):%u", GetLastError());
+    CloseDesktop(input);
+    return false;
+  }
+  if (!GetUserObjectInformation(input, UOI_NAME, inputname, 256, &size)) {
+    vlog.debug("unable to GetUserObjectInformation(2):%u", GetLastError());
+    CloseDesktop(input);
+    return false;
+  }
+  if (!CloseDesktop(input))
+    vlog.debug("unable to close input desktop:%u", GetLastError());
+
+  // *** vlog.debug("current=%s, input=%s", currentname, inputname);
+  bool result = strcmp(currentname, inputname) == 0;
+  return result;
+}
+
+// Switch the current thread into the input desktop
+static bool
+selectInputDesktop() {
+  // - Open the input desktop
+  HDESK desktop = OpenInputDesktop(0, FALSE,
+		DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
+		DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
+		DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
+		DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
+  if (!desktop) {
+    vlog.debug("unable to OpenInputDesktop(2):%u", GetLastError());
+    return false;
+  }
+
+  // - Switch into it
+  if (!switchToDesktop(desktop)) {
+    CloseDesktop(desktop);
+    return false;
+  }
+
+  // ***
+  DWORD size = 256;
+  char currentname[256];
+  if (GetUserObjectInformation(desktop, UOI_NAME, currentname, 256, &size)) {
+    vlog.debug("switched to %s", currentname);
+  }
+  // ***
+
+  vlog.debug("switched to input desktop");
+
+  return true;
+}
+
+
+// -=- Access points to desktop-switching routines
+
+bool
+rfb::win32::desktopChangeRequired() {
+  if (!osVersion.isPlatformNT)
+    return false;
+
+  return !inputDesktopSelected();
+}
+
+bool
+rfb::win32::changeDesktop() {
+  if (!osVersion.isPlatformNT)
+    return true;
+  if (osVersion.cannotSwitchDesktop)
+    return false;
+
+  return selectInputDesktop();
+}
+
+
+// -=- Ctrl-Alt-Del emulation
+
+class CADThread : public Thread {
+public:
+  CADThread() : Thread("CtrlAltDel Emulator"), result(false) {}
+  virtual void run() {
+	  HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId());
+
+    if (switchToDesktop(OpenDesktop(_T("Winlogon"), 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
+		  DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
+		  DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
+      DESKTOP_SWITCHDESKTOP | GENERIC_WRITE))) {
+	    PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
+      switchToDesktop(old_desktop);
+      result = true;
+    }
+  }
+  bool result;
+};
+
+bool
+rfb::win32::emulateCtrlAltDel() {
+  if (!osVersion.isPlatformNT)
+    return false;
+
+  CADThread* cad_thread = new CADThread();
+  vlog.debug("emulate Ctrl-Alt-Del");
+  if (cad_thread) {
+    cad_thread->start();
+    cad_thread->join();
+    bool result = cad_thread->result;
+    delete cad_thread;
+    return result;
+  }
+  return false;
+}
+
+
+// -=- Application Event Log target Logger class
+
+class Logger_EventLog : public Logger {
+public:
+  Logger_EventLog(const TCHAR* srcname) : Logger("EventLog") {
+    eventlog = RegisterEventSource(NULL, srcname);
+    if (!eventlog)
+      printf("Unable to open event log:%ld\n", GetLastError());
+  }
+  ~Logger_EventLog() {
+    if (eventlog)
+      DeregisterEventSource(eventlog);
+  }
+
+  virtual void write(int level, const char *logname, const char *message) {
+    if (!eventlog) return;
+    TStr log(logname), msg(message);
+    const TCHAR* strings[] = {log, msg};
+    WORD type = EVENTLOG_INFORMATION_TYPE;
+    if (level == 0) type = EVENTLOG_ERROR_TYPE;
+    if (!ReportEvent(eventlog, type, 0, VNC4LogMessage, NULL, 2, 0, strings, NULL)) {
+      // *** It's not at all clear what is the correct behaviour if this fails...
+      printf("ReportEvent failed:%ld\n", GetLastError());
+    }
+  }
+
+protected:
+  HANDLE eventlog;
+};
+
+static Logger_EventLog* logger = 0;
+
+bool rfb::win32::initEventLogLogger(const TCHAR* srcname) {
+  if (logger)
+    return false;
+  if (osVersion.isPlatformNT) {
+    logger = new Logger_EventLog(srcname);
+    logger->registerLogger();
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+// -=- Registering and unregistering the service
+
+bool rfb::win32::registerService(const TCHAR* name, const TCHAR* desc,
+                                 int argc, const char* argv[]) {
+
+  // - Initialise the default service parameters
+  const TCHAR* defaultcmdline;
+  if (osVersion.isPlatformNT)
+    defaultcmdline = _T("-service");
+  else
+    defaultcmdline = _T("-noconsole -service");
+
+  // - Get the full pathname of our executable
+  ModuleFileName buffer;
+
+  // - Calculate the command-line length
+  int cmdline_len = _tcslen(buffer.buf) + 4;
+  int i;
+  for (i=0; i<argc; i++) {
+    cmdline_len += strlen(argv[i]) + 3;
+  }
+
+  // - Add the supplied extra parameters to the command line
+  TCharArray cmdline(cmdline_len+_tcslen(defaultcmdline));
+  _stprintf(cmdline.buf, _T("\"%s\" %s"), buffer.buf, defaultcmdline);
+  for (i=0; i<argc; i++) {
+    _tcscat(cmdline.buf, _T(" \""));
+    _tcscat(cmdline.buf, TStr(argv[i]));
+    _tcscat(cmdline.buf, _T("\""));
+  }
+    
+  // - Register the service
+
+  if (osVersion.isPlatformNT) {
+
+    // - Open the SCM
+    ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+    if (!scm)
+      throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+
+    ServiceHandle service = CreateService(scm,
+      name, desc, SC_MANAGER_ALL_ACCESS,
+      SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
+      SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
+      cmdline.buf, NULL, NULL, NULL, NULL, NULL);
+    if (!service)
+      throw rdr::SystemException("unable to create service", GetLastError());
+
+    // - Register the event log source
+    RegKey hk, hk2;
+
+    hk2.createKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application"));
+    hk.createKey(hk2, name);
+
+    for (i=_tcslen(buffer.buf); i>0; i--) {
+      if (buffer.buf[i] == _T('\\')) {
+        buffer.buf[i+1] = 0;
+        break;
+      }
+    }
+
+    const TCHAR* dllFilename = _T("logmessages.dll");
+    TCharArray dllPath(_tcslen(buffer.buf) + _tcslen(dllFilename) + 1);
+    _tcscpy(dllPath.buf, buffer.buf);
+    _tcscat(dllPath.buf, dllFilename);
+ 
+    hk.setExpandString(_T("EventMessageFile"), dllPath.buf);
+    hk.setInt(_T("TypesSupported"), EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE);
+
+  } else {
+
+    RegKey services;
+    services.createKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"));
+    services.setString(name, cmdline.buf);
+
+  }
+
+  Sleep(500);
+
+  return true;
+}
+
+bool rfb::win32::unregisterService(const TCHAR* name) {
+  if (osVersion.isPlatformNT) {
+
+    // - Open the SCM
+    ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+    if (!scm)
+      throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+    // - Create the service
+    ServiceHandle service = OpenService(scm, name, SC_MANAGER_ALL_ACCESS);
+    if (!service)
+      throw rdr::SystemException("unable to locate the service", GetLastError());
+    if (!DeleteService(service))
+      throw rdr::SystemException("unable to remove the service", GetLastError());
+
+    // - Register the event log source
+    RegKey hk;
+    hk.openKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application"));
+    hk.deleteKey(name);
+
+  } else {
+
+		RegKey services;
+    services.openKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"));
+    services.deleteValue(name);
+
+  }
+
+  Sleep(500);
+
+  return true;
+}
+
+
+// -=- Starting and stopping the service
+
+HWND findServiceWindow(const TCHAR* name) {
+  TCharArray wndName(_tcslen(ServiceMsgWindow::baseName)+_tcslen(name)+1);
+  _tcscpy(wndName.buf, ServiceMsgWindow::baseName);
+  _tcscat(wndName.buf, name);
+  vlog.debug("searching for %s window", CStr(wndName.buf));
+  return FindWindow(0, wndName.buf);
+}
+
+bool rfb::win32::startService(const TCHAR* name) {
+
+  if (osVersion.isPlatformNT) {
+    // - Open the SCM
+    ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+    if (!scm)
+      throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+    // - Locate the service
+    ServiceHandle service = OpenService(scm, name, SERVICE_START);
+    if (!service)
+      throw rdr::SystemException("unable to open the service", GetLastError());
+
+    // - Start the service
+    if (!StartService(service, 0, NULL))
+      throw rdr::SystemException("unable to start the service", GetLastError());
+  } else {
+    // - Check there is no service window
+    if (findServiceWindow(name))
+      throw rdr::Exception("the service is already running");
+
+    // - Find the RunServices registry key
+		RegKey services;
+		services.openKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"));
+
+    // - Read the command-line from it
+    TCharArray cmdLine = services.getString(name);
+
+    // - Start the service
+    PROCESS_INFORMATION proc_info;
+    STARTUPINFO startup_info;
+    ZeroMemory(&startup_info, sizeof(startup_info));
+    startup_info.cb = sizeof(startup_info);
+    if (!CreateProcess(0, cmdLine.buf, 0, 0, FALSE, CREATE_NEW_CONSOLE, 0, 0, &startup_info, &proc_info)) {
+      throw SystemException("unable to start service", GetLastError());
+    }
+  }
+
+  Sleep(500);
+
+  return true;
+}
+
+bool rfb::win32::stopService(const TCHAR* name) {
+  if (osVersion.isPlatformNT) {
+    // - Open the SCM
+    ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+    if (!scm)
+      throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+    // - Locate the service
+    ServiceHandle service = OpenService(scm, name, SERVICE_STOP);
+    if (!service)
+      throw rdr::SystemException("unable to open the service", GetLastError());
+
+    // - Start the service
+    SERVICE_STATUS status;
+    if (!ControlService(service, SERVICE_CONTROL_STOP, &status))
+      throw rdr::SystemException("unable to stop the service", GetLastError());
+
+  } else {
+    // - Find the service window
+    HWND service_window = findServiceWindow(name);
+    if (!service_window)
+      throw Exception("unable to locate running service");
+
+    // Tell it to quit
+    vlog.debug("sending service stop request");
+    if (!SendMessage(service_window, WM_SMSG_SERVICE_STOP, 0, 0))
+      throw Exception("unable to stop service");
+
+    // Check it's quitting...
+    DWORD process_id = 0;
+    HANDLE process = 0;
+    if (!GetWindowThreadProcessId(service_window, &process_id))
+      throw SystemException("unable to verify service has quit", GetLastError());
+    process = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, process_id);
+    if (!process)
+      throw SystemException("unable to obtain service handle", GetLastError());
+    int retries = 5;
+    vlog.debug("checking status");
+    while (retries-- && (WaitForSingleObject(process, 1000) != WAIT_OBJECT_0)) {}
+    if (!retries) {
+      vlog.debug("failed to quit - terminating");
+      // May not have quit because of silly Win9x registry watching bug..
+      if (!TerminateProcess(process, 1))
+        throw SystemException("unable to terminate process!", GetLastError());
+      throw Exception("service failed to quit - called TerminateProcess");
+    }
+  }
+
+  Sleep(500);
+
+  return true;
+}
+
+void rfb::win32::printServiceStatus(const TCHAR* name) {
+  if (osVersion.isPlatformNT) {
+    // - Open the SCM
+    ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+    if (!scm)
+      throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+    // - Locate the service
+    ServiceHandle service = OpenService(scm, name, SERVICE_INTERROGATE);
+    if (!service)
+      throw rdr::SystemException("unable to open the service", GetLastError());
+
+    // - Get the service status
+    SERVICE_STATUS status;
+    if (!ControlService(service, SERVICE_CONTROL_INTERROGATE, (SERVICE_STATUS*)&status))
+      throw rdr::SystemException("unable to query the service", GetLastError());
+
+    printf("Service is in the ");
+    switch (status.dwCurrentState) {
+    case SERVICE_RUNNING: printf("running"); break;
+    case SERVICE_STOPPED: printf("stopped"); break;
+    case SERVICE_STOP_PENDING: printf("stop pending"); break;
+    default: printf("unknown (%lu)", status.dwCurrentState); break;
+    };
+    printf(" state.\n");
+
+  } else {
+    HWND service_window = findServiceWindow(name);
+    printf("Service is in the ");
+    if (!service_window) printf("stopped");
+    else printf("running");
+    printf(" state.\n");
+  }
+}
+
+
+bool rfb::win32::isServiceProcess() {
+  return service != 0;
+}
\ No newline at end of file
diff --git a/rfb_win32/Service.h b/rfb_win32/Service.h
new file mode 100644
index 0000000..164381a
--- /dev/null
+++ b/rfb_win32/Service.h
@@ -0,0 +1,123 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- Service.h
+//
+// Win32 service-mode code.
+// Derive your service from this code and let it handle the annoying Win32
+// service API.
+// The underlying implementation takes care of the differences between
+// Windows NT and Windows 95 based systems
+
+#ifndef __RFB_WIN32_SERVICE_H__
+#define __RFB_WIN32_SERVICE_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    //
+    // -=- Service
+    //
+
+    // Application base-class for services.
+
+    class Service {
+    public:
+
+      Service(const TCHAR* name_);
+      virtual ~Service();
+
+      const TCHAR* getName() {return name;}
+      SERVICE_STATUS& getStatus() {return status;}
+
+      void setStatus(DWORD status);
+      void setStatus();
+
+      // - Start the service, having initialised it
+      void start();
+
+      // - Service main procedure - override to implement a service
+      virtual DWORD serviceMain(int argc, TCHAR* argv[]) = 0;
+
+      // - Service control notifications
+
+      // To get notified when the OS is shutting down
+      virtual void osShuttingDown() = 0;
+
+      // To get notified when the service parameters change
+      virtual void readParams() = 0;
+
+      // To cause the serviceMain() routine to return
+      virtual void stop() = 0;
+
+    public:
+      SERVICE_STATUS_HANDLE status_handle;
+      SERVICE_STATUS status;
+    protected:
+      const TCHAR* name;
+    };
+
+    class ServiceHandle {
+    public:
+      ServiceHandle(SC_HANDLE h) : handle(h) {}
+      ~ServiceHandle() {CloseServiceHandle(handle);}
+      operator SC_HANDLE() const {return handle;}
+    protected:
+      SC_HANDLE handle;
+    };
+
+    // -=- Routines used by desktop back-end code to manage desktops/window stations
+
+    //     Returns false under Win9x
+    bool desktopChangeRequired();
+
+    //     Returns true under Win9x
+    bool changeDesktop();
+
+    // -=- Routines used by the SInput Keyboard class to emulate Ctrl-Alt-Del
+    //     Returns false under Win9x
+    bool emulateCtrlAltDel();
+
+    // -=- Routines to initialise the Event Log target Logger
+    //     Returns false under Win9x
+    bool initEventLogLogger(const TCHAR* srcname);
+
+    // -=- Routines to register/unregister the service
+    //     These routines also take care of registering the required
+    //     event source information, etc.
+    // *** should really accept TCHAR argv
+
+    bool registerService(const TCHAR* name, const TCHAR* desc, int argc, const char* argv[]);
+    bool unregisterService(const TCHAR* name);
+
+    bool startService(const TCHAR* name);
+    bool stopService(const TCHAR* name);
+    void printServiceStatus(const TCHAR* name);
+
+    // -=- Routine to determine whether the host process is running a service
+    bool isServiceProcess();
+
+  };
+
+};
+
+#endif // __RFB_WIN32_SERVICE_NT_H__
diff --git a/rfb_win32/SocketManager.cxx b/rfb_win32/SocketManager.cxx
new file mode 100644
index 0000000..6ebd5c0
--- /dev/null
+++ b/rfb_win32/SocketManager.cxx
@@ -0,0 +1,246 @@
+/* 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.
+ */
+
+// -=- SocketManager.cxx
+
+#define WIN32_LEAN_AND_MEAN
+#include <winsock2.h>
+#include <assert.h>
+
+#include <rfb/LogWriter.h>
+#include <rfb_win32/SocketManager.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("SocketManager");
+
+
+// -=- SocketManager
+
+SocketManager::SocketManager() : sockets(0), events(0), nSockets(0), nAvail(0) {
+}
+
+SocketManager::~SocketManager() {
+  for (int i=0; i<nSockets; i++) {
+    if (!sockets[i].is_event)
+      WSACloseEvent(events[i]);
+  }
+  delete [] events;
+  delete [] sockets;
+}
+
+
+void SocketManager::addListener(network::SocketListener* sock_, network::SocketServer* srvr) {
+  WSAEVENT event = WSACreateEvent();
+  assert(event != WSA_INVALID_EVENT);
+  addListener(sock_, event, srvr);
+}
+
+void SocketManager::addSocket(network::Socket* sock_, network::SocketServer* srvr) {
+  WSAEVENT event = WSACreateEvent();
+  assert(event != WSA_INVALID_EVENT);
+  addSocket(sock_, event, srvr);
+}
+
+
+BOOL SocketManager::getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg) {
+  while (true) {
+    // First check for idle timeout
+
+    network::SocketServer* server = 0;
+    int timeout = 0;
+    for (int i=0; i<nSockets; i++) {
+      if (!sockets[i].is_event &&
+          sockets[i].server != server) {
+        server = sockets[i].server;
+        int t = server->checkTimeouts();
+        if (t > 0 && (timeout == 0 || t < timeout))
+          timeout = t;
+      }
+    }
+    if (timeout == 0)
+      timeout = INFINITE;
+
+    // - Network IO is less common than messages - process it first
+    DWORD result;
+    if (nSockets) {
+      result = WaitForMultipleObjects(nSockets, events, FALSE, 0);
+      if (result == WAIT_TIMEOUT) {
+        if (PeekMessage(msg, hwnd, minMsg, maxMsg, PM_REMOVE)) 
+          return msg->message != WM_QUIT;
+
+        result = MsgWaitForMultipleObjects(nSockets, events, FALSE, timeout,
+                                           QS_ALLINPUT);
+        if (result == WAIT_OBJECT_0 + nSockets) {
+          if (PeekMessage(msg, hwnd, minMsg, maxMsg, PM_REMOVE)) 
+            return msg->message != WM_QUIT;
+          continue;
+        }
+      }
+    } else
+      return GetMessage(msg, hwnd, minMsg, maxMsg);
+
+    if ((result >= WAIT_OBJECT_0) && (result < (WAIT_OBJECT_0 + nSockets))) {
+      int index = result - WAIT_OBJECT_0;
+
+      // - Process a socket event
+
+      if (sockets[index].is_event) {
+        // Process a general Win32 event
+        // NB: The handler must reset the event!
+
+        if (!sockets[index].handler->processEvent(events[index])) {
+          removeSocket(index);
+          continue;
+        }
+      } else if (sockets[index].is_conn) {
+        // Process data from an active connection
+
+        // Cancel event notification for this socket
+        if (WSAEventSelect(sockets[index].fd, events[index], 0) == SOCKET_ERROR)
+          vlog.info("unable to disable WSAEventSelect:%u", WSAGetLastError());
+
+        // Reset the event object
+        WSAResetEvent(events[index]);
+
+        // Call the socket server to process the event
+        if (!sockets[index].server->processSocketEvent(sockets[index].sock.conn)) {
+          removeSocket(index);
+          continue;
+        }
+
+        // Re-instate the required socket event
+        // If the read event is still valid, the event object gets set here
+        if (WSAEventSelect(sockets[index].fd, events[index], FD_READ | FD_CLOSE) == SOCKET_ERROR)
+          throw rdr::SystemException("unable to re-enable WSAEventSelect:%u", WSAGetLastError());
+
+      } else {
+        // Accept an incoming connection
+        vlog.debug("accepting incoming connection");
+
+        // What kind of event is this?
+        WSANETWORKEVENTS network_events;
+        WSAEnumNetworkEvents(sockets[index].fd, events[index], &network_events);
+        if (network_events.lNetworkEvents & FD_ACCEPT) {
+          network::Socket* new_sock = sockets[index].sock.listener->accept();
+          if (new_sock) {
+            sockets[index].server->addClient(new_sock);
+            addSocket(new_sock, sockets[index].server);
+          }
+        } else if (network_events.lNetworkEvents & FD_CLOSE) {
+          vlog.info("deleting listening socket");
+          network::SocketListener* s = sockets[index].sock.listener;
+          removeSocket(index);
+          delete s;
+        } else {
+          vlog.error("unknown network event for listener");
+        }
+
+      }
+    } else if (result == WAIT_FAILED) {
+      throw rdr::SystemException("unable to wait for events", GetLastError());
+    }
+  }
+}
+
+
+void SocketManager::resizeArrays(int numSockets) {
+  if (nAvail >= numSockets) return;
+  while (nAvail < numSockets)
+    nAvail = max(16, nAvail*2);
+
+  SocketInfo* newinfo = new SocketInfo[nAvail];
+  HANDLE* newevents = new HANDLE[nAvail];
+  for (int i=0; i<nSockets; i++) {
+    newinfo[i] = sockets[i];
+    newevents[i] = events[i];
+  }
+  delete [] sockets;
+  delete [] events;
+  sockets = newinfo;
+  events = newevents;
+}
+
+void SocketManager::addSocket(network::Socket* sock, HANDLE event, network::SocketServer* server) {
+  resizeArrays(nSockets+1);
+
+  sockets[nSockets].sock.conn = sock;
+  sockets[nSockets].fd = sock->getFd();
+  sockets[nSockets].server = server;
+  events[nSockets] = event;
+  sockets[nSockets].is_conn = true;
+  sockets[nSockets].is_event = false;
+
+  if (WSAEventSelect(sock->getFd(), event, FD_READ | FD_CLOSE) == SOCKET_ERROR)
+    throw rdr::SystemException("unable to select on socket", WSAGetLastError());
+  nSockets++;
+}
+
+void SocketManager::addListener(network::SocketListener* sock, HANDLE event, network::SocketServer* server) {
+  resizeArrays(nSockets+1);
+
+  sockets[nSockets].sock.listener = sock;
+  sockets[nSockets].fd = sock->getFd();
+  sockets[nSockets].server = server;
+  events[nSockets] = event;
+  sockets[nSockets].is_conn = false;
+  sockets[nSockets].is_event = false;
+
+  if (WSAEventSelect(sock->getFd(), event, FD_ACCEPT | FD_CLOSE) == SOCKET_ERROR)
+    throw rdr::SystemException("unable to select on listener", WSAGetLastError());
+  nSockets++;
+}
+
+void SocketManager::remListener(network::SocketListener* sock) {
+  for (int index=0; index<nSockets; index++) {
+    if (!sockets[index].is_conn &&
+        !sockets[index].is_event) {
+      vlog.debug("removing listening socket");
+      removeSocket(index);
+      delete sock;
+    }
+  }
+}
+
+void SocketManager::addEvent(HANDLE event, EventHandler* ecb) {
+  resizeArrays(nSockets+1);
+
+  sockets[nSockets].handler = ecb;
+  events[nSockets] = event;
+  sockets[nSockets].is_conn = false;
+  sockets[nSockets].is_event = true;
+
+  nSockets++;
+}
+
+void SocketManager::removeSocket(int index) {
+  if (index >= nSockets)
+    throw rdr::Exception("attempting to remove unregistered socket");
+
+  if (!sockets[index].is_event)
+    WSACloseEvent(events[index]);
+
+  for (int i=index; i<nSockets-1; i++) {
+    sockets[i] = sockets[i+1];
+    events[i] = events[i+1];
+  }
+
+  nSockets--;
+}
+
diff --git a/rfb_win32/SocketManager.h b/rfb_win32/SocketManager.h
new file mode 100644
index 0000000..791370f
--- /dev/null
+++ b/rfb_win32/SocketManager.h
@@ -0,0 +1,107 @@
+/* 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.
+ */
+
+// -=- SocketManager.h
+
+// Socket manager class for Win32.
+// Passed a network::SocketListener and a network::SocketServer when
+// constructed.  Uses WSAAsyncSelect to get notifications of network 
+// connection attempts.  When an incoming connection is received,
+// the manager will call network::SocketServer::addClient().  If
+// addClient returns true then the manager registers interest in
+// network events on that socket, and calls
+// network::SocketServer::processSocketEvent().
+
+#ifndef __RFB_WIN32_SOCKET_MGR_H__
+#define __RFB_WIN32_SOCKET_MGR_H__
+
+#include <list>
+
+#include <network/Socket.h>
+#include <rfb_win32/MsgWindow.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class SocketManager {
+    public:
+      SocketManager();
+      virtual ~SocketManager();
+
+      // Add a listening socket.  Incoming connections will be added to the supplied
+      // SocketServer.
+      void addListener(network::SocketListener* sock_, network::SocketServer* srvr);
+
+      // Remove and delete a listening socket.
+      void remListener(network::SocketListener* sock);
+
+      // Add an already-connected socket.  Socket events will cause the supplied
+      // SocketServer to be called.  The socket must ALREADY BE REGISTERED with
+      // the SocketServer.
+      void addSocket(network::Socket* sock_, network::SocketServer* srvr);
+
+      // Add a Win32 event & handler for it to the SocketManager
+      // This event will be blocked on along with the registered Sockets, and the
+      // handler called whenever it is discovered to be set.
+      // NB: SocketManager does NOT call ResetEvent on the event!
+      // NB: If processEvent returns false then the event is no longer registered,
+      //     and the event object is assumed to have been closed by processEvent()
+      struct EventHandler {
+        virtual ~EventHandler() {}
+        virtual bool processEvent(HANDLE event) = 0;
+      };
+      void addEvent(HANDLE event, EventHandler* ecb);
+
+      // getMessage
+      //
+      // Either return a message from the thread's message queue or process a socket
+      // event.
+      // Returns whenever a message needs processing.  Returns false if message is
+      // WM_QUIT, true for all other messages.
+      BOOL getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg);
+
+    protected:
+      void addListener(network::SocketListener* sock, HANDLE event, network::SocketServer* server);
+      void addSocket(network::Socket* sock, HANDLE event, network::SocketServer* server);
+      void resizeArrays(int numSockets);
+      void removeSocket(int index);
+      struct SocketInfo {
+        union {
+          network::Socket* conn;
+          network::SocketListener* listener;
+        } sock;
+        SOCKET fd;
+        bool is_conn;
+        bool is_event;
+        union {
+          network::SocketServer* server;
+          EventHandler* handler;
+        };
+      };
+      SocketInfo* sockets;
+      HANDLE* events;
+      int nSockets;
+      int nAvail;
+   };
+
+  }
+
+}
+
+#endif
diff --git a/rfb_win32/TCharArray.cxx b/rfb_win32/TCharArray.cxx
new file mode 100644
index 0000000..f8f03a6
--- /dev/null
+++ b/rfb_win32/TCharArray.cxx
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+#include <rfb_win32/TCharArray.h>
+
+namespace rfb {
+
+  WCHAR* wstrDup(const WCHAR* s) {
+    if (!s) return 0;
+    WCHAR* t = new WCHAR[wcslen(s)+1];
+    memcpy(t, s, sizeof(WCHAR)*(wcslen(s)+1));
+    return t;
+  }
+  void wstrFree(WCHAR* s) {delete [] s;}
+
+  char* strDup(const WCHAR* s) {
+    if (!s) return 0;
+    int len = wcslen(s);
+    char* t = new char[len+1];
+    t[WideCharToMultiByte(CP_ACP, 0, s, len, t, len, 0, 0)] = 0;
+    return t;
+  }
+
+  WCHAR* wstrDup(const char* s) {
+    if (!s) return 0;
+    int len = strlen(s);
+    WCHAR* t = new WCHAR[len+1];
+    t[MultiByteToWideChar(CP_ACP, 0, s, len, t, len)] = 0;
+    return t;
+  }
+
+
+  bool wstrSplit(const WCHAR* src, const WCHAR limiter, WCHAR** out1, WCHAR** out2, bool fromEnd) {
+    WCharArray out1old, out2old;
+    if (out1) out1old.buf = *out1;
+    if (out2) out2old.buf = *out2;
+    int len = wcslen(src);
+    int i=0, increment=1, limit=len;
+    if (fromEnd) {
+      i=len-1; increment = -1; limit = -1;
+    }
+    while (i!=limit) {
+      if (src[i] == limiter) {
+        if (out1) {
+          *out1 = new WCHAR[i+1];
+          if (i) memcpy(*out1, src, sizeof(WCHAR)*i);
+          (*out1)[i] = 0;
+        }
+        if (out2) {
+          *out2 = new WCHAR[len-i];
+          if (len-i-1) memcpy(*out2, &src[i+1], sizeof(WCHAR)*(len-i-1));
+          (*out2)[len-i-1] = 0;
+        }
+        return true;
+      }
+      i+=increment;
+    }
+    if (out1) *out1 = wstrDup(src);
+    if (out2) *out2 = 0;
+    return false;
+  }
+
+  bool wstrContains(const WCHAR* src, WCHAR c) {
+    int l=wcslen(src);
+    for (int i=0; i<l; i++)
+      if (src[i] == c) return true;
+    return false;
+  }
+
+};
diff --git a/rfb_win32/TCharArray.h b/rfb_win32/TCharArray.h
new file mode 100644
index 0000000..399e00a
--- /dev/null
+++ b/rfb_win32/TCharArray.h
@@ -0,0 +1,119 @@
+/* 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.
+ */
+
+// -=- TCharArray.h
+
+// This library contains the wide-character equivalent of CharArray, named
+// WCharArray.  In addition to providing wide-character equivalents of
+// the char* string manipulation functions (strDup, strFree, etc), special
+// versions of those functions are provided which attempt to convert from
+// one format to the other.
+//    e.g. char* t = "hello world"; WCHAR* w = wstrDup(t);
+//    Results in w containing the wide-character text "hello world".
+// For convenience, the WStr and CStr classes are also provided.  These
+// accept an existing (const) WCHAR* or char* null-terminated string and
+// create a read-only copy of that in the desired format.  The new copy
+// will actually be the original copy if the format has not changed, otherwise
+// it will be a new buffer owned by the WStr/CStr.
+
+// In addition to providing wide character functions, this header defines
+// TCHAR* handling classes & functions.  TCHAR is defined at compile time to
+// either char or WCHAR.  Programs can treat this as a third data type and
+// call TStr() whenever a TCHAR* is required but a char* or WCHAR* is supplied,
+// and TStr will do the right thing.
+
+#ifndef __RFB_WIN32_TCHARARRAY_H__
+#define __RFB_WIN32_TCHARARRAY_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <tchar.h>
+
+#include <rfb/util.h>
+
+namespace rfb {
+
+  // -=- String duplication and cleanup functions.
+  //     These routines also handle conversion between WCHAR* and char*
+
+  char* strDup(const WCHAR* s);
+  WCHAR* wstrDup(const WCHAR* s);
+  WCHAR* wstrDup(const char* s);
+  void wstrFree(WCHAR* s);
+
+  bool wstrSplit(const WCHAR* src, const WCHAR limiter, WCHAR** out1, WCHAR** out2, bool fromEnd=false);
+  bool wstrContains(const WCHAR* src, WCHAR c);
+
+  // -=- Temporary format conversion classes
+  //     CStr accepts WCHAR* or char* and behaves like a char*
+  //     WStr accepts WCHAR* or char* and behaves like a WCHAR*
+
+  struct WStr {
+    WStr(const char* s) : buf(wstrDup(s)), free_(true) {}
+    WStr(const WCHAR* s) : buf(s), free_(false) {}
+    ~WStr() {if (free_) wstrFree((WCHAR*)buf);}
+    operator const WCHAR*() {return buf;}
+    const WCHAR* buf;
+    bool free_;
+  };
+
+  struct CStr {
+    CStr(const char* s) : buf(s), free_(false) {}
+    CStr(const WCHAR* s) : buf(strDup(s)), free_(true) {}
+    ~CStr() {if (free_) strFree((char*)buf);}
+    operator const char*() {return buf;}
+    const char* buf;
+    bool free_;
+  };
+
+  // -=- Class to handle cleanup of arrays of native Win32 characters
+  class WCharArray {
+  public:
+    WCharArray() : buf(0) {}
+    WCharArray(char* str) : buf(wstrDup(str)) {strFree(str);} // note: assumes ownership
+    WCharArray(WCHAR* str) : buf(str) {}                      // note: assumes ownership
+    WCharArray(int len) {
+      buf = new WCHAR[len];
+    }
+    ~WCharArray() {
+      delete [] buf;
+    }
+    // Get the buffer pointer & clear it (i.e. caller takes ownership)
+    WCHAR* takeBuf() {WCHAR* tmp = buf; buf = 0; return tmp;}
+    void replaceBuf(WCHAR* str) {delete [] buf; buf = str;}
+    WCHAR* buf;
+  };
+
+#ifdef _UNICODE
+#define tstrDup wstrDup
+#define tstrFree wstrFree
+#define tstrSplit wstrSplit
+#define tstrContains wstrContains
+  typedef WCharArray TCharArray;
+  typedef WStr TStr;
+#else
+#define tstrDup strDup
+#define tstrFree strFree
+#define tstrSplit strSplit
+#define tstrContains strContains
+  typedef CharArray TCharArray;
+  typedef CStr TStr;
+#endif
+
+};
+
+#endif
\ No newline at end of file
diff --git a/rfb_win32/TrayIcon.h b/rfb_win32/TrayIcon.h
new file mode 100644
index 0000000..85680f3
--- /dev/null
+++ b/rfb_win32/TrayIcon.h
@@ -0,0 +1,90 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- CView.h
+
+// An instance of the CView class is created for each VNC Viewer connection.
+
+#ifndef __RFB_WIN32_TRAY_ICON_H__
+#define __RFB_WIN32_TRAY_ICON_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <shellapi.h>
+#include <rfb_win32/MsgWindow.h>
+#include <rdr/Exception.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class TrayIcon : public MsgWindow {
+    public:
+      TrayIcon() : MsgWindow(_T("VNCTray")) {
+#ifdef NOTIFYICONDATA_V1_SIZE
+        nid.cbSize = NOTIFYICONDATA_V1_SIZE;
+#else
+        nid.cbSize = sizeof(NOTIFYICONDATA);
+#endif
+
+        nid.hWnd = getHandle();
+        nid.uID = 0;
+        nid.hIcon = 0;
+        nid.uFlags = NIF_ICON | NIF_MESSAGE;
+        nid.uCallbackMessage = WM_USER;
+      }
+      virtual ~TrayIcon() {
+        remove();
+      }
+      bool setIcon(UINT icon) {
+        if (icon == 0) {
+          return remove();
+        } else {
+          nid.hIcon = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(icon),
+            IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+          return refresh();
+        }
+      }
+      bool setToolTip(const TCHAR* text) {
+        if (text == 0) {
+          nid.uFlags &= ~NIF_TIP;
+        } else {
+          const int tipLen = sizeof(nid.szTip)/sizeof(TCHAR);
+          _tcsncpy(nid.szTip, text, tipLen);
+          nid.szTip[tipLen-1] = 0;
+          nid.uFlags |= NIF_TIP;
+        }
+        return refresh();
+      }
+      bool remove() {
+        return Shell_NotifyIcon(NIM_DELETE, &nid) != 0;
+      }
+      bool refresh() {
+        return Shell_NotifyIcon(NIM_MODIFY, &nid) || Shell_NotifyIcon(NIM_ADD, &nid);
+      }
+    protected:
+      NOTIFYICONDATA nid;
+    };
+
+  };
+
+};
+
+#endif
+
+
diff --git a/rfb_win32/WMCursor.cxx b/rfb_win32/WMCursor.cxx
new file mode 100644
index 0000000..871d937
--- /dev/null
+++ b/rfb_win32/WMCursor.cxx
@@ -0,0 +1,98 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMCursor.cxx
+
+// *** DOESN'T SEEM TO WORK WITH GetCursorInfo POS CODE BUILT-IN UNDER NT4SP6
+// *** INSTEAD, WE LOOK FOR Win2000/Win98 OR ABOVE
+#define WINVER 0x0500
+
+#include <rfb_win32/WMCursor.h>
+#include <rfb_win32/OSVersion.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb/Exception.h>
+#include <rfb/LogWriter.h>
+
+using namespace rdr;
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("WMCursor");
+
+
+typedef BOOL (WINAPI *_GetCursorInfo_proto)(PCURSORINFO pci);
+DynamicFn<_GetCursorInfo_proto> _GetCursorInfo(_T("user32.dll"), "GetCursorInfo");
+
+
+WMCursor::WMCursor() : hooks(0), library(0), use_getCursorInfo(false), cursor(0) {
+#if (WINVER >= 0x0500)
+  // Check the OS version
+  bool is_win98 = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
+    (osVersion.dwMajorVersion > 4) || ((osVersion.dwMajorVersion == 4) && (osVersion.dwMinorVersion > 0));
+  bool is_win2K = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVersion.dwMajorVersion >= 5);
+
+  // Use GetCursorInfo if OS version is sufficient
+  use_getCursorInfo = (is_win98 || is_win2K) && _GetCursorInfo.isValid();
+#else
+#pragma message ("not building in GetCursorInfo support")
+#endif
+  if (!use_getCursorInfo) {
+    hooks = new WMCursorHooks();
+    if (hooks && hooks->start()) {
+      vlog.info("falling back to cursor hooking");
+    } else {
+      delete hooks;
+      hooks = 0;
+      vlog.error("unable to monitor cursor shape");
+    }
+  } else {
+    vlog.info("using GetCursorInfo");
+  }
+  cursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+}
+
+WMCursor::~WMCursor() {
+  if (hooks) delete hooks;
+  if (library) FreeLibrary(library);
+}
+  
+WMCursor::Info
+WMCursor::getCursorInfo() {
+  Info result;
+#if (WINVER >= 0x0500)
+  if (use_getCursorInfo) {
+    CURSORINFO info;
+    info.cbSize = sizeof(CURSORINFO);
+    if ((*_GetCursorInfo)(&info)) {
+      result.cursor = info.hCursor;
+      result.position = Point(info.ptScreenPos.x, info.ptScreenPos.y);
+      result.visible = info.flags & CURSOR_SHOWING;
+      return result;
+    }
+  }
+#endif
+  // Fall back to the old way of doing things
+  POINT pos;
+  if (hooks) cursor = hooks->getCursor();
+  result.cursor = cursor;
+  result.visible = cursor != 0;
+  GetCursorPos(&pos);
+  result.position.x = pos.x;
+  result.position.y = pos.y;
+  return result;
+}
diff --git a/rfb_win32/WMCursor.h b/rfb_win32/WMCursor.h
new file mode 100644
index 0000000..a96822a
--- /dev/null
+++ b/rfb_win32/WMCursor.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMCursor.h
+
+// WMCursor provides a single API through which the cursor state can be obtained
+// The underlying implementation will use either GetCursorInfo, or use the
+// wm_hooks library if GetCursorInfo is not available.
+
+#ifndef __RFB_WIN32_WM_CURSOR_H__
+#define __RFB_WIN32_WM_CURSOR_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <rfb_win32/WMHooks.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class WMCursor {
+    public:
+      WMCursor();
+      ~WMCursor();
+
+      struct Info {
+        HCURSOR cursor;
+        Point position;
+        bool visible;
+        Info() : cursor(0), visible(false) {}
+        bool operator!=(const Info& info) {
+          return ((cursor != info.cursor) ||
+            (!position.equals(info.position)) ||
+            (visible != info.visible));
+        }
+      };
+
+      Info getCursorInfo();
+    protected:
+      WMCursorHooks* hooks;
+      HMODULE library;
+      bool use_getCursorInfo;
+      HCURSOR cursor;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_WM_CURSOR_H__
diff --git a/rfb_win32/WMHooks.cxx b/rfb_win32/WMHooks.cxx
new file mode 100644
index 0000000..26a2363
--- /dev/null
+++ b/rfb_win32/WMHooks.cxx
@@ -0,0 +1,324 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMHooks.cxx
+
+#include <wm_hooks/wm_hooks.h>
+
+#include <rfb_win32/WMHooks.h>
+#include <rfb_win32/Service.h>
+#include <rfb/Threading.h>
+#include <rfb/LogWriter.h>
+
+#include <list>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("WMHooks");
+
+class WMHooksThread : public Thread {
+public:
+  WMHooksThread() : Thread("WMHookThread"), active(true) {}
+  virtual void run();
+  virtual Thread* join();
+protected:
+  bool active;
+};
+
+WMHooksThread* hook_mgr = 0;
+std::list<WMHooks*> hooks;
+std::list<WMCursorHooks*> cursor_hooks;
+Mutex hook_mgr_lock;
+HCURSOR hook_cursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+
+
+bool
+StartHookThread() {
+  if (hook_mgr) return true;
+  vlog.debug("opening hook thread");
+  hook_mgr = new WMHooksThread();
+  if (!WM_Hooks_Install(hook_mgr->getThreadId(), 0)) {
+    vlog.error("failed to initialise hooks");
+    delete hook_mgr->join();
+    hook_mgr = 0;
+    return false;
+  }
+  hook_mgr->start();
+  return true;
+}
+
+void
+StopHookThread() {
+  if (!hook_mgr) return;
+  if (!hooks.empty() || !cursor_hooks.empty()) return;
+  vlog.debug("closing hook thread");
+  delete hook_mgr->join();
+  hook_mgr = 0;
+}
+
+
+bool
+AddHook(WMHooks* hook) {
+  vlog.debug("adding hook");
+  Lock l(hook_mgr_lock);
+  if (!StartHookThread()) return false;
+  hooks.push_back(hook);
+  return true;
+}
+
+bool
+AddCursorHook(WMCursorHooks* hook) {
+  vlog.debug("adding cursor hook");
+  Lock l(hook_mgr_lock);
+  if (cursor_hooks.empty()) WM_Hooks_EnableCursorShape(TRUE);
+  if (!StartHookThread()) return false;
+  cursor_hooks.push_back(hook);
+  return true;
+}
+
+bool
+RemHook(WMHooks* hook) {
+  {
+    vlog.debug("removing hook");
+    Lock l(hook_mgr_lock);
+    hooks.remove(hook);
+  }
+  StopHookThread();
+  return true;
+}
+
+bool
+RemCursorHook(WMCursorHooks* hook) {
+  {
+    vlog.debug("removing cursor hook");
+    Lock l(hook_mgr_lock);
+    cursor_hooks.remove(hook);
+  }
+  StopHookThread();
+  if (cursor_hooks.empty()) WM_Hooks_EnableCursorShape(FALSE);
+  return true;
+}
+
+void
+NotifyHooksRegion(const Region& r) {
+  Lock l(hook_mgr_lock);
+  std::list<WMHooks*>::iterator i;
+  for (i=hooks.begin(); i!=hooks.end(); i++) {
+    (*i)->new_changes.add_changed(r);
+    if (!(*i)->notified) {
+      (*i)->notified = true;
+      PostMessage((*i)->getHandle(), WM_USER, 0, 0);
+    }
+  }
+}
+
+void
+NotifyHooksCursor(HCURSOR c) {
+  Lock l(hook_mgr_lock);
+  hook_cursor = c;
+}
+
+void
+WMHooksThread::run() {
+  UINT windowMsg = WM_Hooks_WindowChanged();
+  UINT clientAreaMsg = WM_Hooks_WindowClientAreaChanged();
+  UINT borderMsg = WM_Hooks_WindowBorderChanged();
+  UINT rectangleMsg = WM_Hooks_RectangleChanged();
+  UINT cursorMsg = WM_Hooks_CursorChanged();
+#ifdef _DEBUG
+  UINT diagnosticMsg = WM_Hooks_Diagnostic();
+#endif
+  MSG msg;
+  RECT wrect;
+  HWND hwnd;
+  int count = 0;
+
+  vlog.debug("starting hook thread");
+
+  while (active && GetMessage(&msg, NULL, 0, 0)) {
+    count++;
+    if (msg.message == windowMsg) {
+      hwnd = (HWND) msg.lParam;
+      if (IsWindow(hwnd) && IsWindowVisible(hwnd) && !IsIconic(hwnd) &&
+          GetWindowRect(hwnd, &wrect) && !IsRectEmpty(&wrect))
+      {
+        NotifyHooksRegion(Rect(wrect.left, wrect.top,
+                               wrect.right, wrect.bottom));
+
+      }
+    } else if (msg.message == clientAreaMsg) {
+      hwnd = (HWND) msg.lParam;
+      if (IsWindow(hwnd) && IsWindowVisible(hwnd) && !IsIconic(hwnd) &&
+          GetClientRect(hwnd, &wrect) && !IsRectEmpty(&wrect))
+      {
+        POINT pt = {0,0};
+        if (ClientToScreen(hwnd, &pt)) {
+          NotifyHooksRegion(Rect(wrect.left+pt.x, wrect.top+pt.y,
+                                 wrect.right+pt.x, wrect.bottom+pt.y));
+        }
+      }
+    } else if (msg.message == borderMsg) {
+      hwnd = (HWND) msg.lParam;
+      if (IsWindow(hwnd) && IsWindowVisible(hwnd) && !IsIconic(hwnd) &&
+          GetWindowRect(hwnd, &wrect) && !IsRectEmpty(&wrect))
+      {
+        Region changed(Rect(wrect.left, wrect.top, wrect.right, wrect.bottom));
+        RECT crect;
+        POINT pt = {0,0};
+        if (GetClientRect(hwnd, &crect) && ClientToScreen(hwnd, &pt) &&
+            !IsRectEmpty(&crect))
+        {
+          changed.assign_subtract(Rect(crect.left+pt.x, crect.top+pt.y,
+                                       crect.right+pt.x, crect.bottom+pt.y));
+        }
+        NotifyHooksRegion(changed);
+      }
+    } else if (msg.message == rectangleMsg) {
+      Rect r = Rect(LOWORD(msg.wParam), HIWORD(msg.wParam),
+                    LOWORD(msg.lParam), HIWORD(msg.lParam));
+      if (!r.is_empty()) {
+        NotifyHooksRegion(r);
+      }
+    } else if (msg.message == cursorMsg) {
+      NotifyHooksCursor((HCURSOR)msg.lParam);
+#ifdef _DEBUG
+    } else if (msg.message == diagnosticMsg) {
+      vlog.info("DIAG msg=%x(%d) wnd=%lx", msg.wParam, msg.wParam, msg.lParam);
+#endif
+    }
+  }
+
+  vlog.debug("stopping hook thread - processed %d events", count);
+  WM_Hooks_Remove(getThreadId());
+}
+
+Thread*
+WMHooksThread::join() {
+  vlog.debug("stopping WMHooks thread");
+  active = false;
+  PostThreadMessage(thread_id, WM_QUIT, 0, 0);
+  vlog.debug("joining WMHooks thread");
+  return Thread::join();
+}
+
+// -=- WMHooks class
+
+rfb::win32::WMHooks::WMHooks()
+  : clipper(0), new_changes(true), fg_window(0),
+  notified(false), MsgWindow(_T("WMHooks")) {
+}
+
+rfb::win32::WMHooks::~WMHooks() {
+  RemHook(this);
+  if (clipper) delete clipper;
+}
+
+LRESULT
+rfb::win32::WMHooks::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  switch (msg) {
+  case WM_USER:
+    {
+      // *** Yield, to allow the triggering update event to be processed
+      //     BEFORE we try to grab the resulting changes.
+      // *** IMPROVES THINGS NOTICABLY ON WinXP
+      Sleep(0);
+      // ***
+
+      Lock l(hook_mgr_lock);
+      notified = false;
+      new_changes.get_update(*clipper);
+      new_changes.clear();
+    }
+    break;
+  }
+  return MsgWindow::processMessage(msg, wParam, lParam);
+}
+
+bool
+rfb::win32::WMHooks::setClipRect(const Rect& r) {
+  clip_region = r;
+  if (clipper) clipper->set_clip_region(clip_region);
+  return true;
+}
+
+bool
+rfb::win32::WMHooks::setUpdateTracker(UpdateTracker* ut) {
+  if (clipper) delete clipper;
+  clipper = new ClippedUpdateTracker(*ut);
+  clipper->set_clip_region(clip_region);
+  return AddHook(this);
+}
+
+#ifdef _DEBUG
+void
+rfb::win32::WMHooks::setDiagnosticRange(UINT min, UINT max) {
+  WM_Hooks_SetDiagnosticRange(min, max);
+}
+#endif
+
+
+// -=- WMBlockInput class
+
+Mutex blockMutex;
+int blockCount = 0;
+
+rfb::win32::WMBlockInput::WMBlockInput() : active(false) {
+}
+
+rfb::win32::WMBlockInput::~WMBlockInput() {
+  blockInputs(false);
+}
+
+bool rfb::win32::WMBlockInput::blockInputs(bool on) {
+  if (on == active) return true;
+  vlog.debug("blockInput changed");
+  Lock l(blockMutex);
+  int newCount = blockCount;
+  if (on)
+    newCount++;
+  else
+    newCount--;
+  if (WM_Hooks_EnableRealInputs(newCount==0, newCount==0)) {
+    vlog.debug("set blocking to %d", newCount);
+    blockCount = newCount;
+    active = on;
+    return true;
+  }
+  return false;
+}
+
+
+// -=- WMCursorHooks class
+
+rfb::win32::WMCursorHooks::WMCursorHooks() {
+}
+
+rfb::win32::WMCursorHooks::~WMCursorHooks() {
+  RemCursorHook(this);
+}
+
+bool
+rfb::win32::WMCursorHooks::start() {
+  return AddCursorHook(this);
+}
+
+HCURSOR
+rfb::win32::WMCursorHooks::getCursor() const {
+  return hook_cursor;
+}
diff --git a/rfb_win32/WMHooks.h b/rfb_win32/WMHooks.h
new file mode 100644
index 0000000..791df76
--- /dev/null
+++ b/rfb_win32/WMHooks.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMHooks.h
+
+#ifndef __RFB_WIN32_WM_HOOKS_H__
+#define __RFB_WIN32_WM_HOOKS_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <rfb/UpdateTracker.h>
+#include <rdr/Exception.h>
+#include <rfb_win32/MsgWindow.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class WMHooks : public MsgWindow {
+    public:
+      WMHooks();
+      ~WMHooks();
+
+      bool setClipRect(const Rect& cr);
+      bool setUpdateTracker(UpdateTracker* ut);
+
+      virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+#ifdef _DEBUG
+      // Get notifications of any messages in the given range, to any hooked window
+      void setDiagnosticRange(UINT min, UINT max);
+#endif
+
+    protected:
+      ClippedUpdateTracker* clipper;
+      Region clip_region;
+
+      void* fg_window;
+      Rect fg_window_rect;
+
+    public:
+      SimpleUpdateTracker new_changes;
+      bool notified;
+    };
+
+    class WMBlockInput {
+    public:
+      WMBlockInput();
+      ~WMBlockInput();
+      bool blockInputs(bool block);
+    protected:
+      bool active;
+    };
+
+    // - Legacy cursor handling support
+    class WMCursorHooks {
+    public:
+      WMCursorHooks();
+      ~WMCursorHooks();
+
+      bool start();
+
+      HCURSOR getCursor() const;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_WM_HOOKS_H__
diff --git a/rfb_win32/WMNotifier.cxx b/rfb_win32/WMNotifier.cxx
new file mode 100644
index 0000000..9773abf
--- /dev/null
+++ b/rfb_win32/WMNotifier.cxx
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMNotifier.cxx
+
+#include <rfb_win32/WMNotifier.h>
+#include <rfb_win32/WMShatter.h>
+#include <rfb_win32/MsgWindow.h>
+
+#include <rfb/LogWriter.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("WMMonitor");
+
+
+WMMonitor::WMMonitor() : MsgWindow(_T("WMMonitor")) {
+}
+
+WMMonitor::~WMMonitor() {
+}
+
+
+LRESULT
+WMMonitor::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  switch (msg) {
+  case WM_DISPLAYCHANGE:
+    if (notifier) {
+      notifier->notifyDisplayEvent(Notifier::DisplaySizeChanged);
+      notifier->notifyDisplayEvent(Notifier::DisplayPixelFormatChanged);
+    }
+    break;
+	case WM_SYSCOLORCHANGE:
+  case WM_PALETTECHANGED:
+    if (notifier) {
+      notifier->notifyDisplayEvent(Notifier::DisplayColourMapChanged);
+    }
+    break;
+  };
+  return MsgWindow::processMessage(msg, wParam, lParam);
+}
diff --git a/rfb_win32/WMNotifier.h b/rfb_win32/WMNotifier.h
new file mode 100644
index 0000000..564d176
--- /dev/null
+++ b/rfb_win32/WMNotifier.h
@@ -0,0 +1,68 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMNotifier.h
+//
+// The WMNotifier is used to get callbacks indicating changes in the state
+// of the system, for instance in the size/format/palette of the display.
+// The WMNotifier contains a Win32 window, which receives notifications of
+// system events and stores them.  Whenever processEvent is called, any
+// incoming events are processed and the appropriate notifier called.
+
+#ifndef __RFB_WIN32_NOTIFIER_H__
+#define __RFB_WIN32_NOTIFIER_H__
+
+#include <rfb/SDesktop.h>
+#include <rfb/Threading.h>
+#include <rfb_win32/MsgWindow.h>
+#include <rfb_win32/DeviceFrameBuffer.h>
+#include <rfb_win32/SInput.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    // -=- Window Message Monitor implementation
+
+    class WMMonitor : MsgWindow {
+    public:
+
+      class Notifier {
+      public:
+        typedef enum {DisplaySizeChanged, DisplayColourMapChanged,
+          DisplayPixelFormatChanged} DisplayEventType;
+        virtual void notifyDisplayEvent(DisplayEventType evt) = 0;
+      };
+
+      WMMonitor();
+      virtual ~WMMonitor();
+
+      void setNotifier(Notifier* wmn) {notifier=wmn;}
+
+    protected:
+      // - Internal MsgWindow callback
+      virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+      Notifier* notifier;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_WMNOTIFIER_H__
diff --git a/rfb_win32/WMPoller.cxx b/rfb_win32/WMPoller.cxx
new file mode 100644
index 0000000..f568b21
--- /dev/null
+++ b/rfb_win32/WMPoller.cxx
@@ -0,0 +1,101 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMPoller.cxx
+
+#include <rfb_win32/WMPoller.h>
+#include <rfb/Exception.h>
+#include <rfb/LogWriter.h>
+#include <rfb/Configuration.h>
+
+#include <tchar.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("WMPoller");
+
+BoolParameter rfb::win32::WMPoller::poll_console_windows("PollConsoleWindows",
+  "Server should poll console windows for updates", true);
+
+// -=- WMPoller class
+
+rfb::win32::WMPoller::WMPoller() : clipper(0) {
+}
+
+rfb::win32::WMPoller::~WMPoller() {
+  if (clipper) delete clipper;
+}
+
+bool
+rfb::win32::WMPoller::processEvent() {
+  PollInfo info;
+  if (clipper && poll_console_windows) {
+    ::EnumWindows(WMPoller::enumWindowProc, (LPARAM) &info);
+    clipper->add_changed(info.poll_include);
+  }
+  return false;
+}
+
+bool
+rfb::win32::WMPoller::setClipRect(const Rect& r) {
+  clip_region = r;
+  if (clipper) clipper->set_clip_region(clip_region);
+  return true;
+}
+
+bool
+rfb::win32::WMPoller::setUpdateTracker(UpdateTracker* ut) {
+  if (clipper) delete clipper;
+  clipper = new ClippedUpdateTracker(*ut);
+  clipper->set_clip_region(clip_region);
+  return true;
+}
+
+bool
+rfb::win32::WMPoller::checkPollWindow(HWND w) {
+  TCHAR buffer[128];
+  if (!GetClassName(w, buffer, 128))
+    throw rdr::SystemException("unable to get window class:%u", GetLastError());
+  if ((_tcscmp(buffer, _T("tty")) != 0) &&
+    (_tcscmp(buffer, _T("ConsoleWindowClass")) != 0)) {
+    return false;
+  }
+  return true;
+}
+
+void
+rfb::win32::WMPoller::pollWindow(HWND w, PollInfo* i) {
+  RECT r;
+  if (IsWindowVisible(w) && GetWindowRect(w, &r)) {
+    if (IsRectEmpty(&r)) return;
+    Region wrgn(Rect(r.left, r.top, r.right, r.bottom));
+    if (checkPollWindow(w)) {
+      wrgn.assign_subtract(i->poll_exclude);
+      i->poll_include.assign_union(wrgn);
+    } else {
+      i->poll_exclude.assign_union(wrgn);
+    }
+  }
+}
+
+BOOL CALLBACK
+rfb::win32::WMPoller::enumWindowProc(HWND w, LPARAM lp) {
+  pollWindow(w, (PollInfo*)lp);
+  return TRUE;
+}
diff --git a/rfb_win32/WMPoller.h b/rfb_win32/WMPoller.h
new file mode 100644
index 0000000..3f3f402
--- /dev/null
+++ b/rfb_win32/WMPoller.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMPoller.h
+//
+// Polls the foreground window.  If the pollOnlyConsoles flag is set,
+// then checks the window class of the foreground window first and
+// only polls it if it's a console.
+// If the pollAllWindows flag is set then iterates through visible
+// windows, and polls the visible bits.  If pollOnlyConsoles is also
+// set then only visible parts of console windows will be polled.
+
+#ifndef __RFB_WIN32_WM_POLLER_H__
+#define __RFB_WIN32_WM_POLLER_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <rfb/UpdateTracker.h>
+#include <rfb/Configuration.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class WMPoller {
+    public:
+      WMPoller();
+      ~WMPoller();
+
+      bool processEvent();
+      bool setClipRect(const Rect& cr);
+      bool setUpdateTracker(UpdateTracker* ut);
+
+      static BoolParameter poll_console_windows;
+    protected:
+      struct PollInfo {
+        Region poll_include;
+        Region poll_exclude;
+      };
+      static bool checkPollWindow(HWND w);
+      static void pollWindow(HWND w, PollInfo* info);
+      static BOOL CALLBACK enumWindowProc(HWND w, LPARAM lp);
+
+      ClippedUpdateTracker* clipper;
+      Region clip_region;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_WM_POLLER_H__
diff --git a/rfb_win32/WMShatter.cxx b/rfb_win32/WMShatter.cxx
new file mode 100644
index 0000000..f6a7484
--- /dev/null
+++ b/rfb_win32/WMShatter.cxx
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMShatter.cxx
+
+#include <rfb_win32/WMShatter.h>
+
+#include <rfb/LogWriter.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("WMShatter");
+
+bool
+rfb::win32::IsSafeWM(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) {
+  bool result = true;
+  switch (msg) {
+    // - UNSAFE MESSAGES
+  case WM_TIMER:
+    result = lParam == 0;
+    break;
+  };
+  if (!result) {
+    vlog.info("IsSafeWM: 0x%x received 0x%x(%u, %lu) - not safe", window, msg, wParam, lParam);
+  }
+  return result;
+}
+
+LRESULT
+rfb::win32::SafeDefWindowProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) {
+  if (IsSafeWM(window, msg, wParam, lParam))
+    return DefWindowProc(window, msg, wParam, lParam);
+  return 0;
+}
+
+LRESULT
+rfb::win32::SafeDispatchMessage(const MSG* msg) {
+  if (IsSafeWM(msg->hwnd, msg->message, msg->wParam, msg->lParam))
+    return DispatchMessage(msg);
+  return 0;
+}
diff --git a/rfb_win32/WMShatter.h b/rfb_win32/WMShatter.h
new file mode 100644
index 0000000..7b81678
--- /dev/null
+++ b/rfb_win32/WMShatter.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMShatter.h
+//
+// WMShatter provides the IsSafeWM routine, which returns true iff the
+// supplied window message is safe to pass to DispatchMessage, or to
+// process in the window procedure.
+//
+// This is only required, of course, to avoid so-called "shatter" attacks
+// to be made against the VNC server, which take advantage of the noddy
+// design of the Win32 window messaging system.
+//
+// The API here is designed to hopefully be future proof, so that if they
+// ever come up with a proper way to determine whether a message is safe
+// or not then it can just be reimplemented here...
+
+#ifndef __RFB_WIN32_SHATTER_H__
+#define __RFB_WIN32_SHATTER_H__
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    bool IsSafeWM(HWND window, UINT msg, WPARAM wParam, LPARAM lParam);
+
+    LRESULT SafeDefWindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+    LRESULT SafeDispatchMessage(const MSG* msg);
+
+  };
+
+};
+
+#endif // __RFB_WIN32_SHATTER_H__
diff --git a/rfb_win32/WMWindowCopyRect.cxx b/rfb_win32/WMWindowCopyRect.cxx
new file mode 100644
index 0000000..46d85ea
--- /dev/null
+++ b/rfb_win32/WMWindowCopyRect.cxx
@@ -0,0 +1,83 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMCopyRect.cxx
+
+#include <rfb_win32/WMWindowCopyRect.h>
+#include <rfb/LogWriter.h>
+#include <windows.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+static LogWriter vlog("WMCopyRect");
+
+// -=- WMHooks class
+
+rfb::win32::WMCopyRect::WMCopyRect() : clipper(0), fg_window(0) {
+}
+
+rfb::win32::WMCopyRect::~WMCopyRect() {
+  if (clipper) delete clipper;
+}
+
+bool
+rfb::win32::WMCopyRect::processEvent() {
+  if (clipper) {
+    // See if the foreground window has moved
+    HWND window = GetForegroundWindow();
+    if (window) {
+      RECT wrect;
+      if (IsWindow(window) && IsWindowVisible(window) && GetWindowRect(window, &wrect)) {
+        Rect winrect(wrect.left, wrect.top, wrect.right, wrect.bottom);
+        if (fg_window == window) {
+
+          if (!fg_window_rect.tl.equals(winrect.tl)) {
+            // Window has moved - send a copyrect event to the client
+            Point delta = Point(winrect.tl.x-fg_window_rect.tl.x, winrect.tl.y-fg_window_rect.tl.y);
+            Region copy_dest = winrect;
+            clipper->add_copied(copy_dest, delta);
+            clipper->add_changed(Region(fg_window_rect).subtract(copy_dest));
+          }
+        }
+        fg_window = window;
+        fg_window_rect = winrect;
+      } else {
+        fg_window = 0;
+      }
+    } else {
+      fg_window = 0;
+    }
+  }
+  return false;
+}
+
+bool
+rfb::win32::WMCopyRect::setClipRect(const Rect& r) {
+  clip_region = r;
+  if (clipper) clipper->set_clip_region(clip_region);
+  return true;
+}
+
+bool
+rfb::win32::WMCopyRect::setUpdateTracker(UpdateTracker* ut) {
+  if (clipper) delete clipper;
+  clipper = new ClippedUpdateTracker(*ut);
+  clipper->set_clip_region(clip_region);
+  return true;
+}
diff --git a/rfb_win32/WMWindowCopyRect.h b/rfb_win32/WMWindowCopyRect.h
new file mode 100644
index 0000000..0750d86
--- /dev/null
+++ b/rfb_win32/WMWindowCopyRect.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2002-2003 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.
+ */
+
+// -=- WMWindowCopyRect.h
+//
+// Helper class which produces copyRect actions by monitoring the location
+// of the current foreground window.
+// Whenever processEvent is called, the foreground window's position is
+// recalculated and a copy event flushed to the supplied UpdateTracker
+// if appropriate.
+
+#ifndef __RFB_WIN32_WM_WINDOW_COPYRECT_H__
+#define __RFB_WIN32_WM_WINDOW_COPYRECT_H__
+
+#include <rfb/UpdateTracker.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class WMCopyRect {
+    public:
+      WMCopyRect();
+      ~WMCopyRect();
+
+      bool processEvent();
+      bool setClipRect(const Rect& cr);
+      bool setUpdateTracker(UpdateTracker* ut);
+
+    protected:
+      ClippedUpdateTracker* clipper;
+      Region clip_region;
+      void* fg_window;
+      Rect fg_window_rect;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_WM_WINDOW_COPYRECT_H__
diff --git a/rfb_win32/Win32Util.cxx b/rfb_win32/Win32Util.cxx
new file mode 100644
index 0000000..e25f43a
--- /dev/null
+++ b/rfb_win32/Win32Util.cxx
@@ -0,0 +1,447 @@
+/* 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.
+ */
+
+// Win32Util.cxx
+
+#include <rfb_win32/Win32Util.h>
+#include <rdr/Exception.h>
+#include <rdr/HexOutStream.h>
+
+
+namespace rfb {
+namespace win32 {
+
+LogicalPalette::LogicalPalette() : palette(0), numEntries(0) {
+  BYTE buf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
+  LOGPALETTE* logpal = (LOGPALETTE*)buf;
+  logpal->palVersion = 0x300;
+  logpal->palNumEntries = 256;
+  for (int i=0; i<256;i++) {
+    logpal->palPalEntry[i].peRed = 0;
+    logpal->palPalEntry[i].peGreen = 0;
+    logpal->palPalEntry[i].peBlue = 0;
+    logpal->palPalEntry[i].peFlags = 0;
+  }
+  palette = CreatePalette(logpal);
+  if (!palette)
+    throw rdr::SystemException("failed to CreatePalette", GetLastError());
+}
+
+LogicalPalette::~LogicalPalette() {
+  if (palette)
+    if (!DeleteObject(palette))
+      throw rdr::SystemException("del palette failed", GetLastError());
+}
+
+void LogicalPalette::setEntries(int start, int count, const Colour* cols) {
+  if (numEntries < count) {
+    ResizePalette(palette, start+count);
+    numEntries = start+count;
+  }
+  PALETTEENTRY* logpal = new PALETTEENTRY[count];
+  for (int i=0; i<count; i++) {
+    logpal[i].peRed = cols[i].r >> 8;
+    logpal[i].peGreen = cols[i].g >> 8;
+    logpal[i].peBlue = cols[i].b >> 8;
+    logpal[i].peFlags = 0;
+  }
+  UnrealizeObject(palette);
+  SetPaletteEntries(palette, start, count, logpal);
+  delete [] logpal;
+}
+
+
+static LogWriter dcLog("DeviceContext");
+
+PixelFormat DeviceContext::getPF() const {
+  return getPF(dc);
+}
+
+PixelFormat DeviceContext::getPF(HDC dc) {
+  PixelFormat format;
+  CompatibleBitmap bitmap(dc, 1, 1);
+
+  // -=- Get the bitmap format information
+  BitmapInfo bi;
+  memset(&bi, 0, sizeof(bi));
+  bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+  bi.bmiHeader.biBitCount = 0;
+
+  if (!::GetDIBits(dc, bitmap, 0, 1, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) {
+    throw rdr::SystemException("unable to determine device pixel format", GetLastError());
+  }
+  if (!::GetDIBits(dc, bitmap, 0, 1, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) {
+    throw rdr::SystemException("unable to determine pixel shifts/palette", GetLastError());
+  }
+
+  // -=- Munge the bitmap info here
+  switch (bi.bmiHeader.biBitCount) {
+  case 1:
+  case 4:
+    bi.bmiHeader.biBitCount = 8;
+    break;
+  case 24:
+    bi.bmiHeader.biBitCount = 32;
+    break;
+  }
+  bi.bmiHeader.biPlanes = 1;
+
+  format.trueColour = bi.bmiHeader.biBitCount > 8;
+  format.bigEndian = 0;
+  format.bpp = format.depth = bi.bmiHeader.biBitCount;
+
+  if (format.trueColour) {
+    DWORD rMask=0, gMask=0, bMask=0;
+
+    // Which true colour format is the DIB section using?
+    switch (bi.bmiHeader.biCompression) {
+    case BI_RGB:
+      // Default RGB layout
+      switch (bi.bmiHeader.biBitCount) {
+      case 16:
+        // RGB 555 - High Colour
+        dcLog.info("16-bit High Colour");
+        rMask = 0x7c00;
+        bMask = 0x001f;
+        gMask = 0x03e0;
+        format.depth = 15;
+        break;
+      case 24:
+      case 32:
+        // RGB 888 - True Colour
+        dcLog.info("24/32-bit High Colour");
+        rMask = 0xff0000;
+        gMask = 0x00ff00;
+        bMask = 0x0000ff;
+        format.depth = 24;
+        break;
+      default:
+        dcLog.error("bits per pixel %u not supported", bi.bmiHeader.biBitCount);
+        throw rdr::Exception("unknown bits per pixel specified");
+      };
+      break;
+    case BI_BITFIELDS:
+      // Custom RGB layout
+      rMask = bi.mask.red;
+      gMask = bi.mask.green;
+      bMask = bi.mask.blue;
+      dcLog.info("BitFields format: %lu, (%lx, %lx, %lx)",
+        bi.bmiHeader.biBitCount, rMask, gMask, bMask);
+      if (format.bpp == 32)
+        format.depth = 24; // ...probably
+      break;
+    };
+
+    // Convert the data we just retrieved
+    initMaxAndShift(rMask, &format.redMax, &format.redShift);
+    initMaxAndShift(gMask, &format.greenMax, &format.greenShift);
+    initMaxAndShift(bMask, &format.blueMax, &format.blueShift);
+  }
+
+  return format;
+}
+
+
+WindowDC::WindowDC(HWND wnd) : hwnd(wnd) {
+  dc = GetDC(wnd);
+  if (!dc)
+    throw rdr::SystemException("GetDC failed", GetLastError());
+}
+WindowDC::~WindowDC() {
+  if (dc)
+    ReleaseDC(hwnd, dc);
+}
+
+
+CompatibleDC::CompatibleDC(HDC existing) {
+  dc = CreateCompatibleDC(existing);
+  if (!dc)
+    throw rdr::SystemException("CreateCompatibleDC failed", GetLastError());
+}
+CompatibleDC::~CompatibleDC() {
+  if (dc)
+    DeleteDC(dc);
+}
+
+
+BitmapDC::BitmapDC(HDC hdc, HBITMAP hbitmap) : CompatibleDC(hdc){
+  oldBitmap = (HBITMAP)SelectObject(dc, hbitmap);
+  if (!oldBitmap)
+    throw rdr::SystemException("SelectObject to CompatibleDC failed",
+    GetLastError());
+}
+BitmapDC::~BitmapDC() {
+  SelectObject(dc, oldBitmap);
+}
+
+
+CompatibleBitmap::CompatibleBitmap(HDC hdc, int width, int height) {
+  hbmp = CreateCompatibleBitmap(hdc, width, height);
+  if (!hbmp)
+    throw rdr::SystemException("CreateCompatibleBitmap() failed", 
+    GetLastError());
+}
+CompatibleBitmap::~CompatibleBitmap() {
+  if (hbmp) DeleteObject(hbmp);
+}
+
+
+PaletteSelector::PaletteSelector(HDC dc, HPALETTE pal) : device(dc), redrawRequired(false) {
+  oldPal = SelectPalette(dc, pal, FALSE);
+  redrawRequired = RealizePalette(dc) > 0;
+}
+PaletteSelector::~PaletteSelector() {
+  if (oldPal) SelectPalette(device, oldPal, TRUE);
+}
+
+
+IconInfo::IconInfo(HICON icon) {
+  if (!GetIconInfo(icon, this))
+    throw rdr::SystemException("GetIconInfo() failed", GetLastError());
+}
+IconInfo::~IconInfo() {
+  if (hbmColor)
+    DeleteObject(hbmColor);
+  if (hbmMask)
+    DeleteObject(hbmMask);
+}
+
+
+ModuleFileName::ModuleFileName(HMODULE module) : TCharArray(MAX_PATH) {
+  if (!module) module = GetModuleHandle(0);
+  if (!GetModuleFileName(module, buf, MAX_PATH))
+    buf[0] = 0;
+}
+
+
+FileVersionInfo::FileVersionInfo(const TCHAR* filename) {
+  // Get executable name
+  ModuleFileName exeName;
+  if (!filename) filename = exeName.buf;
+
+  // Get version info size
+  DWORD handle;
+  int size = GetFileVersionInfoSize((TCHAR*)filename, &handle);
+  if (!size)
+    throw rdr::SystemException("GetVersionInfoSize failed", GetLastError());
+
+  // Get version info
+  buf = new TCHAR[size];
+  if (!GetFileVersionInfo((TCHAR*)filename, handle, size, buf))
+    throw rdr::SystemException("GetVersionInfo failed", GetLastError());
+}
+
+const TCHAR* FileVersionInfo::getVerString(const TCHAR* name, DWORD langId) {
+  char langIdBuf[sizeof(langId)];
+  for (int i=sizeof(langIdBuf)-1; i>=0; i--) {
+    langIdBuf[i] = langId & 0xff;
+    langId = langId >> 8;
+  }
+
+  TCharArray langIdStr = rdr::HexOutStream::binToHexStr(langIdBuf, sizeof(langId));
+  TCharArray infoName(_tcslen(_T("StringFileInfo")) + 4 + _tcslen(name) + _tcslen(langIdStr.buf));
+  _stprintf(infoName.buf, _T("\\StringFileInfo\\%s\\%s"), langIdStr.buf, name);
+
+  // Locate the required version string within the version info
+  TCHAR* buffer = 0;
+  UINT length = 0;
+  if (!VerQueryValue(buf, infoName.buf, (void**)&buffer, &length)) {
+    printf("unable to find %s version string", CStr(infoName.buf));
+    throw rdr::Exception("VerQueryValue failed");
+  }
+  return buffer;
+}
+
+
+bool splitPath(const TCHAR* path, TCHAR** dir, TCHAR** file) {
+  return tstrSplit(path, '\\', dir, file, true);
+}
+
+
+static LogWriter dfbLog("DynamicFn");
+
+DynamicFnBase::DynamicFnBase(const TCHAR* dllName, const char* fnName) : dllHandle(0), fnPtr(0) {
+  dllHandle = LoadLibrary(dllName);
+  if (!dllHandle) {
+    dfbLog.info("DLL %s not found (%d)", (const char*)CStr(dllName), GetLastError());
+    return;
+  }
+  fnPtr = GetProcAddress(dllHandle, fnName);
+  if (!fnPtr)
+    dfbLog.info("proc %s not found in %s (%d)", fnName, (const char*)CStr(dllName), GetLastError());
+}
+
+DynamicFnBase::~DynamicFnBase() {
+  if (dllHandle)
+    FreeLibrary(dllHandle);
+}
+
+
+static LogWriter miLog("MonitorInfo");
+
+MonitorInfo::MonitorInfo(HWND window) {
+#if (WINVER >= 0x0500)
+  typedef HMONITOR (WINAPI *_MonitorFromWindow_proto)(HWND,DWORD);
+  rfb::win32::DynamicFn<_MonitorFromWindow_proto> _MonitorFromWindow(_T("user32.dll"), "MonitorFromWindow");
+  typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
+  rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
+
+  // Can we dynamically link to the monitor functions?
+  if (_MonitorFromWindow.isValid()) {
+    if (_GetMonitorInfo.isValid()) {
+      HMONITOR monitor = (*_MonitorFromWindow)(window, MONITOR_DEFAULTTONEAREST);
+      miLog.debug("monitor=%lx", monitor);
+      if (monitor) {
+        memset(this, 0, sizeof(MONITORINFOEXA));
+        cbSize = sizeof(MONITORINFOEXA);
+        if ((*_GetMonitorInfo)(monitor, this)) {
+          miLog.debug("monitor is %d,%d-%d,%d", rcMonitor.left, rcMonitor.top, rcMonitor.right, rcMonitor.bottom);
+          miLog.debug("work area is %d,%d-%d,%d", rcWork.left, rcWork.top, rcWork.right, rcWork.bottom);
+          miLog.debug("device is \"%s\"", szDevice);
+          return;
+        }
+        miLog.error("failed to get monitor info: %ld", GetLastError());
+      }
+    } else {
+      miLog.debug("GetMonitorInfo not found");
+    }
+  } else {
+      miLog.debug("MonitorFromWindow not found");
+  }
+#else
+#pragma message ("not building in GetMonitorInfo")
+  cbSize = sizeof(MonitorInfo);
+  szDevice[0] = 0;
+#endif
+
+  // Legacy fallbacks - just return the desktop settings
+  miLog.debug("using legacy fall-backs");
+  HWND desktop = GetDesktopWindow();
+  GetWindowRect(desktop, &rcMonitor);
+  SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
+  dwFlags = 0;
+}
+
+
+#if (WINVER >= 0x0500)
+
+struct moveToMonitorData {
+  HWND window;
+  const char* monitorName;
+};
+
+typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
+static rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
+
+static BOOL CALLBACK moveToMonitorEnumProc(HMONITOR monitor,
+                                    HDC dc,
+                                    LPRECT pos,
+                                    LPARAM d) {
+  moveToMonitorData* data = (moveToMonitorData*)d;
+  MONITORINFOEXA info;
+  memset(&info, 0, sizeof(info));
+  info.cbSize = sizeof(info);
+
+  if ((*_GetMonitorInfo)(monitor, &info)) {
+    if (stricmp(data->monitorName, info.szDevice) == 0) {
+      SetWindowPos(data->window, 0,
+        info.rcMonitor.left, info.rcMonitor.top,
+        info.rcMonitor.right, info.rcMonitor.bottom,
+        SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+#endif
+
+void moveToMonitor(HWND handle, const char* device) {
+  miLog.debug("moveToMonitor %s", device);
+
+#if (WINVER >= 0x500)
+  typedef BOOL (WINAPI *_EnumDisplayMonitors_proto)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
+  rfb::win32::DynamicFn<_EnumDisplayMonitors_proto> _EnumDisplayMonitors(_T("user32.dll"), "EnumDisplayMonitors");
+  if (!_EnumDisplayMonitors.isValid()) {
+    miLog.debug("EnumDisplayMonitors not found");
+    return;
+  }
+
+  moveToMonitorData data;
+  data.window = handle;
+  data.monitorName = device;
+
+  (*_EnumDisplayMonitors)(0, 0, &moveToMonitorEnumProc, (LPARAM)&data);
+#endif
+}
+
+
+void centerWindow(HWND handle, HWND parent, bool clipToParent) {
+  RECT r;
+  if (parent && IsWindowVisible(parent)) {
+    if (!GetWindowRect(parent, &r)) return;
+  } else {
+    MonitorInfo mi(handle);
+    r=mi.rcWork;
+  }
+  centerWindow(handle, r, clipToParent);
+}
+
+void centerWindow(HWND handle, const RECT& r, bool clipToRect) {
+  RECT wr;
+  if (!GetWindowRect(handle, &wr)) return;
+  int w = wr.right-wr.left;
+  int h = wr.bottom-wr.top;
+  if (clipToRect) {
+    w = min(r.right-r.left, w);
+    h = min(r.bottom-r.top, h);
+  }
+  int x = (r.left + r.right - w)/2;
+  int y = (r.top + r.bottom - h)/2;
+  UINT flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | (clipToRect ? 0 : SWP_NOSIZE);
+  SetWindowPos(handle, 0, x, y, w, h, flags);
+}
+
+
+int MsgBox(HWND parent, const TCHAR* msg, UINT flags) {
+  const TCHAR* msgType = 0;
+  UINT tflags = flags & 0x70;
+  if (tflags == MB_ICONHAND)
+    msgType = _T("Error");
+  else if (tflags == MB_ICONQUESTION)
+    msgType = _T("Question");
+  else if (tflags == MB_ICONEXCLAMATION)
+    msgType = _T("Warning");
+  else if (tflags == MB_ICONASTERISK)
+    msgType = _T("Information");
+  flags |= MB_TOPMOST | MB_SETFOREGROUND;
+  int len = _tcslen(AppName.buf) + 1;
+  if (msgType) len += _tcslen(msgType) + 3;
+  TCharArray title = new TCHAR[len];
+  _tcscpy(title.buf, AppName.buf);
+  if (msgType) {
+    _tcscat(title.buf, _T(" : "));
+    _tcscat(title.buf, msgType);
+  }
+  return MessageBox(parent, msg, title.buf, flags);
+}
+
+
+};
+};
diff --git a/rfb_win32/Win32Util.h b/rfb_win32/Win32Util.h
new file mode 100644
index 0000000..5f0ab5a
--- /dev/null
+++ b/rfb_win32/Win32Util.h
@@ -0,0 +1,217 @@
+/* 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.
+ */
+
+// -=- Win32Util.h
+
+// Miscellaneous but useful Win32 API utility functions & classes.
+// In particular, a set of classes which wrap GDI objects,
+// and some to handle palettes.
+
+#ifndef __RFB_WIN32_GDIUTIL_H__
+#define __RFB_WIN32_GDIUTIL_H__
+
+#include <rfb/ColourMap.h>
+#include <rfb/PixelFormat.h>
+#include <rfb/Rect.h>
+#include <rfb_win32/TCharArray.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class LogicalPalette {
+    public:
+      LogicalPalette();
+      ~LogicalPalette();
+      void setEntries(int start, int count, const Colour* cols);
+      HPALETTE getHandle() {return palette;}
+    protected:
+      HPALETTE palette;
+      int numEntries;
+    };
+
+    class DeviceContext {
+    public:
+      DeviceContext() : dc(0) {}
+      virtual ~DeviceContext() {}
+      operator HDC() const {return dc;}
+      PixelFormat getPF() const;
+      static PixelFormat getPF(HDC dc);
+    protected:
+      HDC dc;
+    };
+
+    class WindowDC : public DeviceContext {
+    public:
+      WindowDC(HWND wnd);
+      virtual ~WindowDC();
+    protected:
+      HWND hwnd;
+    };
+
+    class CompatibleDC : public DeviceContext {
+    public:
+      CompatibleDC(HDC existing);
+      virtual ~CompatibleDC();
+    };
+
+    class BitmapDC : public CompatibleDC {
+    public:
+      BitmapDC(HDC hdc, HBITMAP hbitmap);
+      ~BitmapDC();
+    protected:
+      HBITMAP oldBitmap;
+    };
+
+    class CompatibleBitmap {
+    public:
+      CompatibleBitmap(HDC hdc, int width, int height);
+      virtual ~CompatibleBitmap();
+      operator HBITMAP() const {return hbmp;}
+    protected:
+      HBITMAP hbmp;
+    };
+
+    struct BitmapInfo {
+      BITMAPINFOHEADER bmiHeader;
+      union {
+        struct {
+          DWORD red;
+          DWORD green;
+          DWORD blue;
+        } mask;
+        RGBQUAD color[256];
+      };
+    };
+
+    inline void initMaxAndShift(DWORD mask, int* max, int* shift) {
+      for ((*shift) = 0; (mask & 1) == 0; (*shift)++) mask >>= 1;
+        (*max) = (rdr::U16)mask;
+    }
+
+    class PaletteSelector {
+    public:
+      PaletteSelector(HDC dc, HPALETTE pal);
+      ~PaletteSelector();
+      bool isRedrawRequired() {return redrawRequired;}
+    protected:
+      HPALETTE oldPal;
+      HDC device;
+      bool redrawRequired;
+    };
+
+    struct IconInfo : public ICONINFO {
+      IconInfo(HICON icon);
+      ~IconInfo();
+    };
+
+    struct ModuleFileName : public TCharArray {
+      ModuleFileName(HMODULE module=0);
+    };
+
+    struct FileVersionInfo : public TCharArray {
+      FileVersionInfo(const TCHAR* filename=0);
+      const TCHAR* getVerString(const TCHAR* name, DWORD langId = 0x080904b0);
+    };
+
+    bool splitPath(const TCHAR* path, TCHAR** dir, TCHAR** file);
+
+    class DynamicFnBase {
+    public:
+      DynamicFnBase(const TCHAR* dllName, const char* fnName);
+      ~DynamicFnBase();
+      bool isValid() const {return fnPtr != 0;}
+    protected:
+      void* fnPtr;
+      HMODULE dllHandle;
+    };
+
+    template<class T> class DynamicFn : public DynamicFnBase {
+    public:
+      DynamicFn(const TCHAR* dllName, const char* fnName) : DynamicFnBase(dllName, fnName) {}
+      T operator *() const {return (T)fnPtr;};
+    };
+
+    // Structure containing info on the monitor nearest the window.
+    // Copes with multi-monitor OSes and older ones.
+#if (WINVER >= 0x0500)
+    struct MonitorInfo : MONITORINFOEXA {
+      MonitorInfo(HWND hwnd);
+    };
+#else
+    struct MonitorInfo {
+      MonitorInfo(HWND hwnd);
+      DWORD cbSize;
+      RECT rcMonitor;
+      RECT rcWork;
+      DWORD dwFlags;
+      char szDevice[1]; // Always null...
+    };
+#endif
+    void moveToMonitor(HWND handle, const char* device);
+
+    class Handle {
+    public:
+      Handle(HANDLE h_=0) : h(h_) {}
+      ~Handle() {
+        if (h) CloseHandle(h);
+      }
+      operator HANDLE() {return h;}
+      HANDLE h;
+    };
+
+    // Center the window to a rectangle, or to a parent window.
+    // Optionally, resize the window to lay within the rect or parent window
+    // If the parent window is NULL then the working area if the window's
+    // current monitor is used instead.
+    void centerWindow(HWND handle, const RECT& r, bool clipToRect=false);
+    void centerWindow(HWND handle, HWND parent, bool clipToRect=false);
+
+    // MsgBox helper function.  Define rfb::win32::AppName somewhere in your
+    // code and MsgBox will use its value in informational messages.
+    extern TStr AppName;
+    int MsgBox(HWND parent, const TCHAR* message, UINT flags);
+
+    // Get the computer name
+    struct ComputerName : TCharArray {
+      ComputerName() : TCharArray(MAX_COMPUTERNAME_LENGTH+1) {
+        ULONG namelength = MAX_COMPUTERNAME_LENGTH+1;
+        if (!GetComputerName(buf, &namelength))
+          _tcscpy(buf, _T(""));
+      }
+    };
+
+    // Allocate and/or manage LocalAlloc memory.
+    struct LocalMem {
+      LocalMem(int size) : ptr(LocalAlloc(LMEM_FIXED, size)) {
+        if (!ptr) throw rdr::SystemException("LocalAlloc", GetLastError());
+      }
+      LocalMem(void* p) : ptr(p) {}
+      ~LocalMem() {LocalFree(ptr);}
+      operator void*() {return ptr;}
+      void* takePtr() {
+        void* t = ptr; ptr = 0; return t;
+      }
+      void* ptr;
+    };
+
+  };
+
+};
+
+#endif
diff --git a/rfb_win32/keymap.h b/rfb_win32/keymap.h
new file mode 100644
index 0000000..69ce66f
--- /dev/null
+++ b/rfb_win32/keymap.h
@@ -0,0 +1,149 @@
+/* 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.
+ */
+
+// keymap.h - this file is shared between SInput.cxx and CKeyboard.cxx
+//
+// Mapping of X keysyms to and from Windows VK codes.  Ordering here must be
+// such that when we look up a Windows VK code we get the preferred X keysym.
+// Going the other way there is no problem because an X keysym always maps to
+// exactly one Windows VK code.  This map only contain keys which are not the
+// normal keys for printable ASCII characters.  For example it does not contain
+// VK_SPACE (note that things like VK_ADD are for the plus key on the keypad,
+// not on the main keyboard).
+
+struct keymap_t {
+  rdr::U32 keysym;
+  rdr::U8 vk;
+  bool extended;
+};
+
+static keymap_t keymap[] = {
+
+  { XK_BackSpace,        VK_BACK, 0 },
+  { XK_Tab,              VK_TAB, 0 },
+  { XK_Clear,            VK_CLEAR, 0 },
+  { XK_Return,           VK_RETURN, 0 },
+  { XK_Pause,            VK_PAUSE, 0 },
+  { XK_Escape,           VK_ESCAPE, 0 },
+  { XK_Delete,           VK_DELETE, 1 },
+
+  // Cursor control & motion
+
+  { XK_Home,             VK_HOME, 1 },
+  { XK_Left,             VK_LEFT, 1 },
+  { XK_Up,               VK_UP, 1 },
+  { XK_Right,            VK_RIGHT, 1 },
+  { XK_Down,             VK_DOWN, 1 },
+  { XK_Page_Up,          VK_PRIOR, 1 },
+  { XK_Page_Down,        VK_NEXT, 1 },
+  { XK_End,              VK_END, 1 },
+
+  // Misc functions
+
+  { XK_Select,           VK_SELECT, 0 },
+  { XK_Print,            VK_SNAPSHOT, 0 },
+  { XK_Execute,          VK_EXECUTE, 0 },
+  { XK_Insert,           VK_INSERT, 1 },
+  { XK_Help,             VK_HELP, 0 },
+  { XK_Break,            VK_CANCEL, 1 },
+
+  // Auxilliary Functions - must come before XK_KP_F1, etc
+
+  { XK_F1,               VK_F1, 0 },
+  { XK_F2,               VK_F2, 0 },
+  { XK_F3,               VK_F3, 0 },
+  { XK_F4,               VK_F4, 0 },
+  { XK_F5,               VK_F5, 0 },
+  { XK_F6,               VK_F6, 0 },
+  { XK_F7,               VK_F7, 0 },
+  { XK_F8,               VK_F8, 0 },
+  { XK_F9,               VK_F9, 0 },
+  { XK_F10,              VK_F10, 0 },
+  { XK_F11,              VK_F11, 0 },
+  { XK_F12,              VK_F12, 0 },
+  { XK_F13,              VK_F13, 0 },
+  { XK_F14,              VK_F14, 0 },
+  { XK_F15,              VK_F15, 0 },
+  { XK_F16,              VK_F16, 0 },
+  { XK_F17,              VK_F17, 0 },
+  { XK_F18,              VK_F18, 0 },
+  { XK_F19,              VK_F19, 0 },
+  { XK_F20,              VK_F20, 0 },
+  { XK_F21,              VK_F21, 0 },
+  { XK_F22,              VK_F22, 0 },
+  { XK_F23,              VK_F23, 0 },
+  { XK_F24,              VK_F24, 0 },
+
+  // Keypad Functions, keypad numbers
+
+  { XK_KP_Tab,           VK_TAB, 0 },
+  { XK_KP_Enter,         VK_RETURN, 1 },
+  { XK_KP_F1,            VK_F1, 0 },
+  { XK_KP_F2,            VK_F2, 0 },
+  { XK_KP_F3,            VK_F3, 0 },
+  { XK_KP_F4,            VK_F4, 0 },
+  { XK_KP_Home,          VK_HOME, 0 },
+  { XK_KP_Left,          VK_LEFT, 0 },
+  { XK_KP_Up,            VK_UP, 0 },
+  { XK_KP_Right,         VK_RIGHT, 0 },
+  { XK_KP_Down,          VK_DOWN, 0 },
+  { XK_KP_End,           VK_END, 0 },
+  { XK_KP_Page_Up,       VK_PRIOR, 0 },
+  { XK_KP_Page_Down,     VK_NEXT, 0 },
+  { XK_KP_Begin,         VK_CLEAR, 0 },
+  { XK_KP_Insert,        VK_INSERT, 0 },
+  { XK_KP_Delete,        VK_DELETE, 0 },
+  { XK_KP_Multiply,      VK_MULTIPLY, 0 },
+  { XK_KP_Add,           VK_ADD, 0 },
+  { XK_KP_Separator,     VK_SEPARATOR, 0 },
+  { XK_KP_Subtract,      VK_SUBTRACT, 0 },
+  { XK_KP_Decimal,       VK_DECIMAL, 0 },
+  { XK_KP_Divide,        VK_DIVIDE, 1 },
+
+  { XK_KP_0,             VK_NUMPAD0, 0 },
+  { XK_KP_1,             VK_NUMPAD1, 0 },
+  { XK_KP_2,             VK_NUMPAD2, 0 },
+  { XK_KP_3,             VK_NUMPAD3, 0 },
+  { XK_KP_4,             VK_NUMPAD4, 0 },
+  { XK_KP_5,             VK_NUMPAD5, 0 },
+  { XK_KP_6,             VK_NUMPAD6, 0 },
+  { XK_KP_7,             VK_NUMPAD7, 0 },
+  { XK_KP_8,             VK_NUMPAD8, 0 },
+  { XK_KP_9,             VK_NUMPAD9, 0 },
+
+  // Modifiers
+    
+  { XK_Shift_L,          VK_SHIFT, 0 },
+  { XK_Shift_R,          VK_SHIFT, 0 },
+  { XK_Control_L,        VK_CONTROL, 0 },
+  { XK_Control_R,        VK_CONTROL, 1 },
+  { XK_Alt_L,            VK_MENU, 0 },
+  { XK_Alt_R,            VK_MENU, 1 },
+
+  // Left & Right Windows keys & Windows Menu Key
+
+  { XK_Super_L,          VK_LWIN, 0 },
+  { XK_Super_R,          VK_RWIN, 0 },
+  { XK_Menu,             VK_APPS, 0 },
+
+  // Japanese stuff - almost certainly wrong...
+
+  { XK_Kanji,            VK_KANJI, 0 },
+  { XK_Kana_Shift,       VK_KANA, 0 },
+
+};
diff --git a/rfb_win32/msvcwarning.h b/rfb_win32/msvcwarning.h
new file mode 100644
index 0000000..e50d9c1
--- /dev/null
+++ b/rfb_win32/msvcwarning.h
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002-2003 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.
+ */
+#pragma warning( disable : 4244 ) // loss of data e.g. int to char
+#pragma warning( disable : 4800 ) // forcing bool 'true' or 'false'
+#pragma warning( disable : 4786 ) // debug info truncated
diff --git a/rfb_win32/rfb_win32.dsp b/rfb_win32/rfb_win32.dsp
new file mode 100644
index 0000000..2118bcb
--- /dev/null
+++ b/rfb_win32/rfb_win32.dsp
@@ -0,0 +1,341 @@
+# Microsoft Developer Studio Project File - Name="rfb_win32" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=rfb_win32 - Win32 Debug Unicode
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "rfb_win32.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "rfb_win32.mak" CFG="rfb_win32 - Win32 Debug Unicode"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "rfb_win32 - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "rfb_win32 - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "rfb_win32 - Win32 Debug Unicode" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "rfb_win32 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /FI"msvcwarning.h" /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF  "$(CFG)" == "rfb_win32 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF  "$(CFG)" == "rfb_win32 - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "rfb_win32___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "rfb_win32___Win32_Debug_Unicode"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_LIB" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF 
+
+# Begin Target
+
+# Name "rfb_win32 - Win32 Release"
+# Name "rfb_win32 - Win32 Debug"
+# Name "rfb_win32 - Win32 Debug Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\AboutDialog.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CKeyboard.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CleanDesktop.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Clipboard.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CPointer.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CurrentUser.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\DeviceFrameBuffer.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dialog.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\DIBSectionBuffer.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\LaunchProcess.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\MsgWindow.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\OSVersion.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegConfig.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\SDisplay.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Service.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\SInput.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\SocketManager.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\TCharArray.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Win32Util.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMCursor.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMHooks.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMNotifier.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMPoller.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMShatter.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMWindowCopyRect.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\AboutDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CKeyboard.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CleanDesktop.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Clipboard.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CPointer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CurrentUser.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DeviceFrameBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DIBSectionBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IntervalTimer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\keymap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LaunchProcess.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MsgWindow.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OSVersion.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SDisplay.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Security.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Service.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SInput.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SocketManager.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TCharArray.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TrayIcon.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Win32Util.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMCursor.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMHooks.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMNotifier.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMPoller.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMShatter.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WMWindowCopyRect.h
+# End Source File
+# End Group
+# End Target
+# End Project
