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);
+}
+
+
+};
+};
