diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
new file mode 100644
index 0000000..2d90730
--- /dev/null
+++ b/vncviewer/CConn.cxx
@@ -0,0 +1,708 @@
+/* Copyright (C) 2002-2005 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 <windows.h>
+#include <winsock2.h>
+#include <vncviewer/UserPasswdDialog.h>
+#include <vncviewer/CConn.h>
+#include <vncviewer/CConnThread.h>
+#include <vncviewer/resource.h>
+#include <rfb/encodings.h>
+#include <rfb/secTypes.h>
+#include <rfb/CSecurityNone.h>
+#include <rfb/CSecurityVncAuth.h>
+#include <rfb/CMsgWriter.h>
+#include <rfb/Configuration.h>
+#include <rfb/LogWriter.h>
+#include <rfb_win32/AboutDialog.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+using namespace rdr;
+
+// - Statics & consts
+
+static LogWriter vlog("CConn");
+
+
+const int IDM_FULLSCREEN = ID_FULLSCREEN;
+const int IDM_SEND_MENU_KEY = ID_SEND_MENU_KEY;
+const int IDM_SEND_CAD = ID_SEND_CAD;
+const int IDM_SEND_CTLESC = ID_SEND_CTLESC;
+const int IDM_ABOUT = ID_ABOUT;
+const int IDM_OPTIONS = ID_OPTIONS;
+const int IDM_INFO = ID_INFO;
+const int IDM_NEWCONN = ID_NEW_CONNECTION;
+const int IDM_REQUEST_REFRESH = ID_REQUEST_REFRESH;
+const int IDM_CTRL_KEY = ID_CTRL_KEY;
+const int IDM_ALT_KEY = ID_ALT_KEY;
+const int IDM_FILE_TRANSFER = ID_FILE_TRANSFER;
+const int IDM_CONN_SAVE_AS = ID_CONN_SAVE_AS;
+
+
+static IntParameter debugDelay("DebugDelay","Milliseconds to display inverted "
+                               "pixel data - a debugging feature", 0);
+
+
+//
+// -=- CConn implementation
+//
+
+RegKey            CConn::userConfigKey;
+
+
+CConn::CConn() 
+  : window(0), sock(0), sockEvent(CreateEvent(0, TRUE, FALSE, 0)), requestUpdate(false),
+    sameMachine(false), encodingChange(false), formatChange(false),
+    reverseConnection(false), lastUsedEncoding_(encodingRaw), isClosed_(false) {
+}
+
+CConn::~CConn() {
+  delete window;
+}
+
+bool CConn::initialise(network::Socket* s, bool reverse) {
+  // Set the server's name for MRU purposes
+  CharArray endpoint(s->getPeerEndpoint());
+  setServerName(endpoint.buf);
+  if (!options.host.buf)
+    options.setHost(endpoint.buf);
+
+  // Initialise the underlying CConnection
+  setStreams(&s->inStream(), &s->outStream());
+
+  // Enable processing of window messages while blocked on I/O
+  s->inStream().setBlockCallback(this);
+
+  // Initialise the viewer options
+  applyOptions(options);
+
+  // - Set which auth schemes we support, in order of preference
+  addSecType(secTypeVncAuth);
+  addSecType(secTypeNone);
+
+  // Start the RFB protocol
+  sock = s;
+  reverseConnection = reverse;
+  initialiseProtocol();
+
+  m_fileTransfer.initialize(&s->inStream(), &s->outStream());
+
+  return true;
+}
+
+
+void
+CConn::applyOptions(CConnOptions& opt) {
+  // - If any encoding-related settings have changed then we must
+  //   notify the server of the new settings
+  encodingChange |= ((options.useLocalCursor != opt.useLocalCursor) ||
+                     (options.useDesktopResize != opt.useDesktopResize) ||
+                     (options.customCompressLevel != opt.customCompressLevel) ||
+                     (options.compressLevel != opt.compressLevel) ||
+                     (options.noJpeg != opt.noJpeg) ||
+                     (options.qualityLevel != opt.qualityLevel) ||
+                     (options.preferredEncoding != opt.preferredEncoding));
+
+  // - If the preferred pixel format has changed then notify the server
+  formatChange |= (options.fullColour != opt.fullColour);
+  if (!opt.fullColour)
+    formatChange |= (options.lowColourLevel != opt.lowColourLevel);
+
+  // - Save the new set of options
+  options = opt;
+
+  // - Set optional features in ConnParams
+  cp.supportsLocalCursor = options.useLocalCursor;
+  cp.supportsDesktopResize = options.useDesktopResize;
+  cp.customCompressLevel = options.customCompressLevel;
+  cp.compressLevel = options.compressLevel;
+  cp.noJpeg = options.noJpeg;
+  cp.qualityLevel = options.qualityLevel;
+
+  // - Configure connection sharing on/off
+  setShared(options.shared);
+
+  // - Whether to use protocol 3.3 for legacy compatibility
+  setProtocol3_3(options.protocol3_3);
+
+  // - Apply settings that affect the window, if it is visible
+  if (window) {
+    window->setMonitor(options.monitor.buf);
+    window->setFullscreen(options.fullScreen);
+    window->setEmulate3(options.emulate3);
+    window->setPointerEventInterval(options.pointerEventInterval);
+    window->setMenuKey(options.menuKey);
+    window->setDisableWinKeys(options.disableWinKeys);
+    window->setShowToolbar(options.showToolbar);
+    if (!options.useLocalCursor)
+      window->setCursor(0, 0, Point(), 0, 0);
+  }
+}
+
+
+void
+CConn::displayChanged() {
+  // Display format has changed - recalculate the full-colour pixel format
+  calculateFullColourPF();
+}
+
+void
+CConn::paintCompleted() {
+  // A repaint message has just completed - request next update if necessary
+  requestNewUpdate();
+}
+
+bool
+CConn::sysCommand(WPARAM wParam, LPARAM lParam) {
+  // - If it's one of our (F8 Menu) messages
+  switch (wParam) {
+  case IDM_FULLSCREEN:
+    options.fullScreen = !window->isFullscreen();
+    window->setFullscreen(options.fullScreen);
+    return true;
+  case IDM_SHOW_TOOLBAR:
+    options.showToolbar = !options.showToolbar;
+    window->setShowToolbar(options.showToolbar);
+    // FIXME: Update menu in DesktopWindow?
+    // FIXME: Actually show or hide the toolbar?
+    return true;
+  case IDM_CTRL_KEY:
+    window->kbd.keyEvent(this, VK_CONTROL, 0, !window->kbd.keyPressed(VK_CONTROL));
+    return true;
+  case IDM_ALT_KEY:
+    window->kbd.keyEvent(this, VK_MENU, 0, !window->kbd.keyPressed(VK_MENU));
+    return true;
+  case IDM_SEND_MENU_KEY:
+    window->kbd.keyEvent(this, options.menuKey, 0, true);
+    window->kbd.keyEvent(this, options.menuKey, 0, false);
+    return true;
+  case IDM_SEND_CAD:
+    window->kbd.keyEvent(this, VK_CONTROL, 0, true);
+    window->kbd.keyEvent(this, VK_MENU, 0, true);
+    window->kbd.keyEvent(this, VK_DELETE, 0x1000000, true);
+    window->kbd.keyEvent(this, VK_DELETE, 0x1000000, false);
+    window->kbd.keyEvent(this, VK_MENU, 0, false);
+    window->kbd.keyEvent(this, VK_CONTROL, 0, false);
+    return true;
+  case IDM_SEND_CTLESC:
+    window->kbd.keyEvent(this, VK_CONTROL, 0, true);
+    window->kbd.keyEvent(this, VK_ESCAPE, 0, true);
+    window->kbd.keyEvent(this, VK_ESCAPE, 0, false);
+    window->kbd.keyEvent(this, VK_CONTROL, 0, false);
+    return true;
+  case IDM_REQUEST_REFRESH:
+    try {
+      writer()->writeFramebufferUpdateRequest(Rect(0,0,cp.width,cp.height), false);
+      requestUpdate = false;
+    } catch (rdr::Exception& e) {
+      close(e.str());
+    }
+    return true;
+  case IDM_NEWCONN:
+    {
+      Thread* newThread = new CConnThread;
+    }
+    return true;
+  case IDM_OPTIONS:
+    // Update the monitor device name in the CConnOptions instance
+    options.monitor.replaceBuf(window->getMonitor());
+    showOptionsDialog();
+    return true;
+  case IDM_INFO:
+    infoDialog.showDialog(this);
+    return true;
+  case IDM_ABOUT:
+    AboutDialog::instance.showDialog();
+    return true;
+  case IDM_FILE_TRANSFER:
+    m_fileTransfer.show(window->getHandle());
+    return true;
+  case IDM_CONN_SAVE_AS:
+    return true;
+  case ID_CLOSE:
+    // FIXME: Remove the corresponding toolbar button.
+    return true;
+  };
+  return false;
+}
+
+
+void
+CConn::closeWindow() {
+  vlog.info("window closed");
+  close();
+}
+
+
+void
+CConn::refreshMenu(bool enableSysItems) {
+  HMENU menu = GetSystemMenu(window->getHandle(), FALSE);
+
+  if (!enableSysItems) {
+    // Gray out menu items that might cause a World Of Pain
+    EnableMenuItem(menu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
+    EnableMenuItem(menu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
+    EnableMenuItem(menu, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
+    EnableMenuItem(menu, SC_MINIMIZE, MF_BYCOMMAND | MF_ENABLED);
+    EnableMenuItem(menu, SC_MAXIMIZE, MF_BYCOMMAND | MF_ENABLED);
+  }
+
+  // Update the modifier key menu items
+  UINT ctrlCheckFlags = window->kbd.keyPressed(VK_CONTROL) ? MF_CHECKED : MF_UNCHECKED;
+  UINT altCheckFlags = window->kbd.keyPressed(VK_MENU) ? MF_CHECKED : MF_UNCHECKED;
+  CheckMenuItem(menu, IDM_CTRL_KEY, MF_BYCOMMAND | ctrlCheckFlags);
+  CheckMenuItem(menu, IDM_ALT_KEY, MF_BYCOMMAND | altCheckFlags);
+
+  // Ensure that the Send <MenuKey> menu item has the correct text
+  if (options.menuKey) {
+    TCharArray menuKeyStr(options.menuKeyName());
+    TCharArray tmp(_tcslen(menuKeyStr.buf) + 6);
+    _stprintf(tmp.buf, _T("Send %s"), menuKeyStr.buf);
+    if (!ModifyMenu(menu, IDM_SEND_MENU_KEY, MF_BYCOMMAND | MF_STRING, IDM_SEND_MENU_KEY, tmp.buf))
+      InsertMenu(menu, IDM_SEND_CAD, MF_BYCOMMAND | MF_STRING, IDM_SEND_MENU_KEY, tmp.buf);
+  } else {
+    RemoveMenu(menu, IDM_SEND_MENU_KEY, MF_BYCOMMAND);
+  }
+
+  // Set the menu fullscreen option tick
+  CheckMenuItem(menu, IDM_FULLSCREEN, (window->isFullscreen() ? MF_CHECKED : 0) | MF_BYCOMMAND);
+
+  // In the full-screen mode, "Show toolbar" should be grayed.
+  int toolbarFlags = options.fullScreen ? MF_GRAYED : MF_ENABLED;
+  EnableMenuItem(menu, IDM_SHOW_TOOLBAR, MF_BYCOMMAND | toolbarFlags);
+}
+
+
+void
+CConn::blockCallback() {
+  // - An InStream has blocked on I/O while processing an RFB message
+  //   We re-enable socket event notifications, so we'll know when more
+  //   data is available, then we sit and dispatch window events until
+  //   the notification arrives.
+  if (!isClosed()) {
+    if (WSAEventSelect(sock->getFd(), sockEvent, FD_READ | FD_CLOSE) == SOCKET_ERROR)
+      throw rdr::SystemException("Unable to wait for sokcet data", WSAGetLastError());
+  }
+  while (true) {
+    // If we have closed then we can't block waiting for data
+    if (isClosed())
+      throw rdr::EndOfStream();
+
+    // Wait for socket data, or a message to process
+    DWORD result = MsgWaitForMultipleObjects(1, &sockEvent.h, FALSE, INFINITE, QS_ALLINPUT);
+    if (result == WAIT_OBJECT_0) {
+      // - Network event notification.  Return control to I/O routine.
+      break;
+    } else if (result == WAIT_FAILED) {
+      // - The wait operation failed - raise an exception
+      throw rdr::SystemException("blockCallback wait error", GetLastError());
+    }
+
+    // - There should be a message in the message queue
+    MSG msg;
+    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+      // IMPORTANT: We mustn't call TranslateMessage() here, because instead we
+      // call ToAscii() in CKeyboard::keyEvent().  ToAscii() stores dead key
+      // state from one call to the next, which would be messed up by calls to
+      // TranslateMessage() (actually it looks like TranslateMessage() calls
+      // ToAscii() internally).
+      DispatchMessage(&msg);
+    }
+  }
+
+  // Before we return control to the InStream, reset the network event
+  WSAEventSelect(sock->getFd(), sockEvent, 0);
+  ResetEvent(sockEvent);
+}
+
+
+void CConn::keyEvent(rdr::U32 key, bool down) {
+  if (!options.sendKeyEvents) return;
+  try {
+    writer()->keyEvent(key, down);
+  } catch (rdr::Exception& e) {
+    close(e.str());
+  }
+}
+void CConn::pointerEvent(const Point& pos, int buttonMask) {
+  if (!options.sendPtrEvents) return;
+  try {
+    writer()->pointerEvent(pos, buttonMask);
+  } catch (rdr::Exception& e) {
+    close(e.str());
+  }
+}
+void CConn::clientCutText(const char* str, int len) {
+  if (!options.clientCutText) return;
+  if (state() != RFBSTATE_NORMAL) return;
+  try {
+    writer()->clientCutText(str, len);
+  } catch (rdr::Exception& e) {
+    close(e.str());
+  }
+}
+
+
+CSecurity* CConn::getCSecurity(int secType)
+{
+  switch (secType) {
+  case secTypeNone:
+    return new CSecurityNone();
+  case secTypeVncAuth:
+    return new CSecurityVncAuth(this);
+  default:
+    throw Exception("Unsupported secType?");
+  }
+}
+
+
+void
+CConn::setColourMapEntries(int first, int count, U16* rgbs) {
+  vlog.debug("setColourMapEntries: first=%d, count=%d", first, count);
+  int i;
+  for (i=0;i<count;i++)
+    window->setColour(i+first, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]);
+  // *** change to 0, 256?
+  window->refreshWindowPalette(first, count);
+}
+
+void
+CConn::bell() {
+  if (options.acceptBell)
+    MessageBeep(-1);
+}
+
+
+void
+CConn::setDesktopSize(int w, int h) {
+  vlog.debug("setDesktopSize %dx%d", w, h);
+
+  // Resize the window's buffer
+  if (window)
+    window->setSize(w, h);
+
+  // Tell the underlying CConnection
+  CConnection::setDesktopSize(w, h);
+}
+
+void
+CConn::setCursor(int w, int h, const Point& hotspot, void* data, void* mask) {
+  if (!options.useLocalCursor) return;
+
+  // Set the window to use the new cursor
+  window->setCursor(w, h, hotspot, data, mask);
+}
+
+
+void
+CConn::close(const char* reason) {
+  // If already closed then ignore this
+  if (isClosed())
+    return;
+
+  // Hide the window, if it exists
+  if (window)
+    ShowWindow(window->getHandle(), SW_HIDE);
+
+  // Save the reason & flag that we're closed & shutdown the socket
+  isClosed_ = true;
+  closeReason_.replaceBuf(strDup(reason));
+  sock->shutdown();
+}
+
+
+void
+CConn::showOptionsDialog() {
+  optionsDialog.showDialog(this);
+}
+
+
+void
+CConn::framebufferUpdateEnd() {
+  if (debugDelay != 0) {
+    vlog.debug("debug delay %d",(int)debugDelay);
+    UpdateWindow(window->getHandle());
+    Sleep(debugDelay);
+    std::list<rfb::Rect>::iterator i;
+    for (i = debugRects.begin(); i != debugRects.end(); i++) {
+      window->invertRect(*i);
+    }
+    debugRects.clear();
+  }
+  if (options.autoSelect)
+    autoSelectFormatAndEncoding();
+
+  // Always request the next update
+  requestUpdate = true;
+
+  // Check that at least part of the window has changed
+  if (!GetUpdateRect(window->getHandle(), 0, FALSE)) {
+    if (!(GetWindowLong(window->getHandle(), GWL_STYLE) & WS_MINIMIZE))
+      requestNewUpdate();
+  }
+
+  // Make sure the local cursor is shown
+  window->showCursor();
+}
+
+
+// Note: The method below is duplicated in vncviewer_unix/CConn.cxx!
+
+// autoSelectFormatAndEncoding() chooses the format and encoding appropriate
+// to the connection speed:
+//
+//   Above 16Mbps (timing for at least a second), switch to hextile
+//   Otherwise, switch to ZRLE
+//
+//   Above 256Kbps, use full colour mode
+//
+void
+CConn::autoSelectFormatAndEncoding() {
+  int kbitsPerSecond = sock->inStream().kbitsPerSecond();
+  unsigned int newEncoding = options.preferredEncoding;
+
+  bool newFullColour = options.fullColour;
+  unsigned int timeWaited = sock->inStream().timeWaited();
+
+  // Select best encoding
+  if (kbitsPerSecond > 16000 && timeWaited >= 10000) {
+    newEncoding = encodingHextile;
+  } else {
+    newEncoding = encodingZRLE;
+  }
+
+  if (newEncoding != options.preferredEncoding) {
+    vlog.info("Throughput %d kbit/s - changing to %s encoding",
+            kbitsPerSecond, encodingName(newEncoding));
+    options.preferredEncoding = newEncoding;
+    encodingChange = true;
+  }
+
+  if (kbitsPerSecond == 0) {
+    return;
+  }
+
+  if (cp.beforeVersion(3, 8)) {
+    // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with
+    // cursors "asynchronously". If this happens in the middle of a
+    // pixel format change, the server will encode the cursor with
+    // the old format, but the client will try to decode it
+    // according to the new format. This will lead to a
+    // crash. Therefore, we do not allow automatic format change for
+    // old servers.
+    return;
+  }
+  
+  // Select best color level
+  newFullColour = (kbitsPerSecond > 256);
+  if (newFullColour != options.fullColour) {
+    vlog.info("Throughput %d kbit/s - full color is now %s", 
+              kbitsPerSecond,
+              newFullColour ? "enabled" : "disabled");
+    options.fullColour = newFullColour;
+    formatChange = true;
+  }
+}
+
+void
+CConn::requestNewUpdate() {
+  if (!requestUpdate) return;
+
+  if (formatChange) {
+    // Select the required pixel format
+    if (options.fullColour) {
+      window->setPF(fullColourPF);
+    } else {
+      switch (options.lowColourLevel) {
+      case 0:
+        window->setPF(PixelFormat(8,3,0,1,1,1,1,2,1,0));
+        break;
+      case 1:
+        window->setPF(PixelFormat(8,6,0,1,3,3,3,4,2,0));
+        break;
+      case 2:
+        window->setPF(PixelFormat(8,8,0,0,0,0,0,0,0,0));
+        break;
+      }
+    }
+
+    // Print the current pixel format
+    char str[256];
+    window->getPF().print(str, 256);
+    vlog.info("Using pixel format %s",str);
+
+    // Save the connection pixel format and tell server to use it
+    cp.setPF(window->getPF());
+    writer()->writeSetPixelFormat(cp.pf());
+
+    // Correct the local window's palette
+    if (!window->getNativePF().trueColour)
+      window->refreshWindowPalette(0, 1 << cp.pf().depth);
+  }
+
+  if (encodingChange) {
+    vlog.info("Using %s encoding",encodingName(options.preferredEncoding));
+    writer()->writeSetEncodings(options.preferredEncoding, true);
+  }
+
+  writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height),
+                                          !formatChange);
+
+  encodingChange = formatChange = requestUpdate = false;
+}
+
+
+void
+CConn::calculateFullColourPF() {
+  // If the server is palette based then use palette locally
+  // Also, don't bother doing bgr222
+  if (!serverDefaultPF.trueColour || (serverDefaultPF.depth < 6)) {
+    fullColourPF = serverDefaultPF;
+    options.fullColour = true;
+  } else {
+    // If server is trueColour, use lowest depth PF
+    PixelFormat native = window->getNativePF();
+    if ((serverDefaultPF.bpp < native.bpp) ||
+        ((serverDefaultPF.bpp == native.bpp) &&
+        (serverDefaultPF.depth < native.depth)))
+      fullColourPF = serverDefaultPF;
+    else
+      fullColourPF = window->getNativePF();
+  }
+  formatChange = true;
+}
+
+
+void
+CConn::setName(const char* name) {
+  if (window)
+    window->setName(name);
+  CConnection::setName(name);
+}
+
+
+void CConn::serverInit() {
+  CConnection::serverInit();
+
+  // If using AutoSelect with old servers, start in FullColor
+  // mode. See comment in autoSelectFormatAndEncoding. 
+  if (cp.beforeVersion(3, 8) && options.autoSelect) {
+    options.fullColour = true;
+  }
+
+  // Show the window
+  window = new DesktopWindow(this);
+  window->setName(cp.name());
+  window->setSize(cp.width, cp.height);
+  applyOptions(options);
+
+  // Save the server's current format
+  serverDefaultPF = cp.pf();
+
+  // Calculate the full-colour format to use
+  calculateFullColourPF();
+
+  // Request the initial update
+  vlog.info("requesting initial update");
+  formatChange = encodingChange = requestUpdate = true;
+  requestNewUpdate();
+
+  // Update the window menu
+  HMENU wndmenu = GetSystemMenu(window->getHandle(), FALSE);
+  int toolbarChecked = options.showToolbar ? MF_CHECKED : 0;
+
+  AppendMenu(wndmenu, MF_SEPARATOR, 0, 0);
+  AppendMenu(wndmenu, MF_STRING, IDM_FULLSCREEN, _T("&Full screen"));
+  AppendMenu(wndmenu, MF_STRING | toolbarChecked, IDM_SHOW_TOOLBAR,
+             _T("Show tool&bar"));
+  AppendMenu(wndmenu, MF_SEPARATOR, 0, 0);
+  AppendMenu(wndmenu, MF_STRING, IDM_CTRL_KEY, _T("Ctr&l"));
+  AppendMenu(wndmenu, MF_STRING, IDM_ALT_KEY, _T("Al&t"));
+  AppendMenu(wndmenu, MF_STRING, IDM_SEND_CAD, _T("Send Ctrl-Alt-&Del"));
+  AppendMenu(wndmenu, MF_STRING, IDM_SEND_CTLESC, _T("Send Ctrl-&Esc"));
+  AppendMenu(wndmenu, MF_STRING, IDM_REQUEST_REFRESH, _T("Refres&h Screen"));
+  AppendMenu(wndmenu, MF_SEPARATOR, 0, 0);
+  AppendMenu(wndmenu, MF_STRING, IDM_NEWCONN, _T("Ne&w Connection..."));
+  AppendMenu(wndmenu, MF_STRING, IDM_OPTIONS, _T("&Options..."));
+  AppendMenu(wndmenu, MF_STRING, IDM_INFO, _T("Connection &Info..."));
+  AppendMenu(wndmenu, MF_STRING, IDM_ABOUT, _T("&About..."));
+}
+
+void
+CConn::serverCutText(const char* str, int len) {
+  if (!options.serverCutText) return;
+  window->serverCutText(str, len);
+}
+
+
+void CConn::beginRect(const Rect& r, unsigned int encoding) {
+  sock->inStream().startTiming();
+}
+
+void CConn::endRect(const Rect& r, unsigned int encoding) {
+  sock->inStream().stopTiming();
+  lastUsedEncoding_ = encoding;
+  if (debugDelay != 0) {
+    window->invertRect(r);
+    debugRects.push_back(r);
+  }
+}
+
+void CConn::fillRect(const Rect& r, Pixel pix) {
+  window->fillRect(r, pix);
+}
+void CConn::imageRect(const Rect& r, void* pixels) {
+  window->imageRect(r, pixels);
+}
+void CConn::copyRect(const Rect& r, int srcX, int srcY) {
+  window->copyRect(r, srcX, srcY);
+}
+
+void CConn::getUserPasswd(char** user, char** password) {
+/*
+  if (!user && options.passwordFile.buf[0]) {
+    FILE* fp = fopen(options.passwordFile.buf, "rb");
+    if (!fp) return false;
+    char data[256];
+    int datalen = fread(data, 1, 256, fp);
+    fclose(fp);
+    if (datalen != 8) return false;
+    vncAuthUnobfuscatePasswd(data);
+    *password = strDup(data);
+    memset(data, 0, strlen(data));
+    return true;
+  }
+*/
+  if (user && options.userName.buf)
+    *user = strDup(options.userName.buf);
+  if (password && options.password.buf)
+    *password = strDup(options.password.buf);
+  if ((user && !*user) || (password && !*password)) {
+    // Missing username or password - prompt the user
+    UserPasswdDialog userPasswdDialog;
+    userPasswdDialog.setCSecurity(getCurrentCSecurity());
+    userPasswdDialog.getUserPasswd(user, password);
+  }
+  if (user) options.setUserName(*user);
+  if (password) options.setPassword(*password);
+}
+
+bool CConn::processFTMsg(int type) {
+  return m_fileTransfer.processFTMsg(type);
+}
diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h
new file mode 100644
index 0000000..29023f3
--- /dev/null
+++ b/vncviewer/CConn.h
@@ -0,0 +1,165 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- CConn.h
+
+// Windows-specific implementation of CConnection
+
+#ifndef __RFB_WIN32_CCONN_H__
+#define __RFB_WIN32_CCONN_H__
+
+#include <network/Socket.h>
+#include <rfb/CConnection.h>
+#include <rfb/Cursor.h>
+#include <rfb/UserPasswdGetter.h>
+#include <rfb_win32/Registry.h>
+#include <rfb_win32/Handle.h>
+#include <vncviewer/InfoDialog.h>
+#include <vncviewer/OptionsDialog.h>
+#include <vncviewer/CConnOptions.h>
+#include <vncviewer/DesktopWindow.h>
+#include <vncviewer/FileTransfer.h>
+#include <list>
+
+
+namespace rfb {
+
+  namespace win32 {
+
+    class CConn : public CConnection,
+                  UserPasswdGetter,
+                  DesktopWindow::Callback,
+                  rdr::FdInStreamBlockCallback
+    {
+    public:
+      CConn();
+      ~CConn();
+
+      // - Start the VNC session on the supplied socket
+      //   The socket must already be connected to a host
+      bool initialise(network::Socket* s, bool reverse=false);
+
+      // - Set/get the session options
+      void applyOptions(CConnOptions& opt);
+      const CConnOptions& getOptions() const { return options; };
+
+      // - Show the options dialog for the connection
+      void showOptionsDialog();
+
+      // - Close the socket & set the reason for closure
+      void close(const char* reason=0);
+      bool isClosed() const { return isClosed_; }
+      const char* closeReason() const { return closeReason_.buf; }
+
+      // - Last received encoding, for the Info dialog
+      int lastUsedEncoding() const { return lastUsedEncoding_; }
+
+      // - Get at the DesktopWindow, if any
+      DesktopWindow* getWindow() { return window; }
+
+      // - Get at the underlying Socket
+      network::Socket* getSocket() { return sock; }
+
+      // - Get the server's preferred format
+      const PixelFormat& getServerDefaultPF() const { return serverDefaultPF; }
+
+      // Global user-config registry key
+      static RegKey userConfigKey;
+
+      bool processFTMsg(int type);
+
+    protected:
+      // InputHandler interface (via DesktopWindow::Callback)
+      void keyEvent(rdr::U32 key, bool down);
+      void pointerEvent(const Point& pos, int buttonMask);
+      void clientCutText(const char* str, int len);
+
+      // DesktopWindow::Callback interface
+      void displayChanged();
+      void paintCompleted();
+      bool sysCommand(WPARAM wParam, LPARAM lParam);
+      void closeWindow();
+      void refreshMenu(bool enableSysCommands);
+
+      // CConnection interface
+      CSecurity* getCSecurity(int secType);
+      void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
+      void bell();
+      void framebufferUpdateEnd();
+      void setDesktopSize(int w, int h);
+      void setCursor(int w, int h, const Point& hotspot, void* data, void* mask);
+      void setName(const char* name);
+      void serverInit();
+      void serverCutText(const char* str, int len);
+      void beginRect(const Rect& r, unsigned int encoding);
+      void endRect(const Rect& r, unsigned int encoding);
+      void fillRect(const Rect& r, Pixel pix);
+      void imageRect(const Rect& r, void* pixels);
+      void copyRect(const Rect& r, int srcX, int srcY);
+
+      // rdr::FdInStreamBlockCallback interface
+      void blockCallback();
+
+      // UserPasswdGetter interface
+      // (overridden to allow a pre-supplied username & password)
+      void getUserPasswd(char** user, char** password);
+
+      // CConn-specific internal interface
+      void autoSelectFormatAndEncoding();
+      void requestNewUpdate();
+      void calculateFullColourPF();
+
+      // The desktop window
+      DesktopWindow* window;
+
+      // Info and Options dialogs
+      OptionsDialog optionsDialog;
+      InfoDialog infoDialog;
+
+      // VNC Viewer options
+      CConnOptions options;
+
+      // Pixel format and encoding
+      PixelFormat serverDefaultPF;
+      PixelFormat fullColourPF;
+      bool sameMachine;
+      bool encodingChange;
+      bool formatChange;
+      int lastUsedEncoding_;
+
+      // Networking and RFB protocol
+      network::Socket* sock;
+      Handle sockEvent;
+      bool reverseConnection;
+      bool requestUpdate;
+
+      // Debugging/logging
+      std::list<Rect> debugRects;
+      CharArray closeReason_;
+      bool isClosed_;
+
+      FileTransfer m_fileTransfer;
+    };
+
+  };
+
+};
+
+#endif
+
+
diff --git a/vncviewer/CViewOptions.cxx b/vncviewer/CConnOptions.cxx
similarity index 85%
rename from vncviewer/CViewOptions.cxx
rename to vncviewer/CConnOptions.cxx
index 76a624b..0c35acc 100644
--- a/vncviewer/CViewOptions.cxx
+++ b/vncviewer/CConnOptions.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -16,12 +16,11 @@
  * USA.
  */
 
-#include <vncviewer/CViewOptions.h>
+#include <vncviewer/CConnOptions.h>
 #include <rfb/Configuration.h>
 #include <rfb/encodings.h>
-#include <rfb/vncAuth.h>
 #include <rfb/LogWriter.h>
-#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/MsgBox.h>
 #include <rfb_win32/Registry.h>
 #include <rdr/HexInStream.h>
 #include <rdr/HexOutStream.h>
@@ -33,6 +32,9 @@
 static StringParameter passwordFile("PasswordFile",
 				    "Password file for VNC authentication", "");
 
+// - Settings stored in the registry & in .vnc files, by Save Defaults and
+//   Save Configuration respectively.
+
 static BoolParameter useLocalCursor("UseLocalCursor", "Render the mouse cursor locally", true);
 static BoolParameter useDesktopResize("UseDesktopResize", "Support dynamic desktop resizing", true);
 
@@ -74,6 +76,9 @@
 static BoolParameter serverCutText("ServerCutText",
                          "Accept clipboard changes from the server.", true);
 
+static BoolParameter disableWinKeys("DisableWinKeys",
+                         "Pass special Windows keys directly to the server.", true);
+
 static BoolParameter protocol3_3("Protocol3.3",
                          "Only use protocol version 3.3", false);
 
@@ -92,6 +97,8 @@
 
 static StringParameter monitor("Monitor", "The monitor to open the VNC Viewer window on, if available.", "");
 static StringParameter menuKey("MenuKey", "The key which brings up the popup menu", "F8");
+static BoolParameter autoReconnect("AutoReconnect", "Offer to reconnect to the remote server if the connection"
+                                   "is dropped because an error occurs.", true);
 
 static BoolParameter customCompressLevel("CustomCompressLevel",
 					 "Use custom compression level. "
@@ -111,18 +118,24 @@
 				 "0 = Low, 9 = High",
 				 6);
 
-CViewOptions::CViewOptions()
+CConnOptions::CConnOptions()
 : useLocalCursor(::useLocalCursor), useDesktopResize(::useDesktopResize),
 autoSelect(::autoSelect), fullColour(::fullColour), fullScreen(::fullScreen),
 shared(::sharedConnection), sendPtrEvents(::sendPtrEvents), sendKeyEvents(::sendKeyEvents), sendSysKeys(::sendSysKeys),
 preferredEncoding(encodingZRLE), clientCutText(::clientCutText), serverCutText(::serverCutText),
-protocol3_3(::protocol3_3), acceptBell(::acceptBell), showToolbar(::showToolbar), lowColourLevel(::lowColourLevel),
-pointerEventInterval(ptrEventInterval), emulate3(::emulate3), monitor(::monitor.getData()),
+disableWinKeys(::disableWinKeys), protocol3_3(::protocol3_3), acceptBell(::acceptBell),
+lowColourLevel(::lowColourLevel), pointerEventInterval(ptrEventInterval),
+emulate3(::emulate3), monitor(::monitor.getData()), showToolbar(::showToolbar),
 customCompressLevel(::customCompressLevel), compressLevel(::compressLevel), 
-noJpeg(::noJpeg), qualityLevel(::qualityLevel), passwordFile(::passwordFile.getData())
+noJpeg(::noJpeg), qualityLevel(::qualityLevel), passwordFile(::passwordFile.getData()),
+autoReconnect(::autoReconnect)
 {
-  CharArray encodingName(::preferredEncoding.getData());
-  preferredEncoding = encodingNum(encodingName.buf);
+  if (autoSelect) {
+    preferredEncoding = encodingZRLE;
+  } else {
+    CharArray encodingName(::preferredEncoding.getData());
+    preferredEncoding = encodingNum(encodingName.buf);
+  }
   setMenuKey(CharArray(::menuKey.getData()).buf);
 
   if (!::autoSelect.hasBeenSet()) {
@@ -138,7 +151,7 @@
 }
 
 
-void CViewOptions::readFromFile(const char* filename) {
+void CConnOptions::readFromFile(const char* filename) {
   FILE* f = fopen(filename, "r");
   if (!f)
     throw rdr::Exception("Failed to read configuration file");
@@ -185,15 +198,10 @@
           } else if (stricmp(name.buf, "UserName") == 0) {
             userName.replaceBuf(value.takeBuf());
           } else if (stricmp(name.buf, "Password") == 0) {
-            int len = 0;
-            CharArray obfuscated;
-            rdr::HexInStream::hexStrToBin(value.buf, &obfuscated.buf, &len);
-            if (len == 8) {
-              password.replaceBuf(new char[9]);
-              memcpy(password.buf, obfuscated.buf, 8);
-              vncAuthUnobfuscatePasswd(password.buf);
-              password.buf[8] = 0;
-            }
+            ObfuscatedPasswd obfPwd;
+            rdr::HexInStream::hexStrToBin(value.buf, (char**)&obfPwd.buf, &obfPwd.length);
+            PlainPasswd passwd(obfPwd);
+            password.replaceBuf(passwd.takeBuf());
           }
         } else if (stricmp(section.buf, "Options") == 0) {
             // V4 options
@@ -224,6 +232,8 @@
             clientCutText = atoi(value.buf);
           } else if (stricmp(name.buf, "AcceptCutText") == 0) {
             serverCutText = atoi(value.buf);
+          } else if (stricmp(name.buf, "DisableWinKeys") == 0) {
+            disableWinKeys = atoi(value.buf);
           } else if (stricmp(name.buf, "AcceptBell") == 0) {
             acceptBell = atoi(value.buf);
           } else if (stricmp(name.buf, "Emulate3") == 0) {
@@ -236,6 +246,9 @@
             monitor.replaceBuf(value.takeBuf());
           } else if (stricmp(name.buf, "MenuKey") == 0) {
             setMenuKey(value.buf);
+          } else if (stricmp(name.buf, "AutoReconnect") == 0) {
+            autoReconnect = atoi(value.buf);
+
           } else if (stricmp(name.buf, "CustomCompressLevel") == 0) {
 	    customCompressLevel = atoi(value.buf);
           } else if (stricmp(name.buf, "CompressLevel") == 0) {
@@ -274,6 +287,10 @@
       }
     }
 
+    // If AutoSelect is enabled then override the preferred encoding
+    if (autoSelect)
+      preferredEncoding = encodingZRLE;
+
     setConfigFileName(filename);
   } catch (rdr::Exception&) {
     if (f) fclose(f);
@@ -281,7 +298,7 @@
   }
 }
 
-void CViewOptions::writeToFile(const char* filename) {
+void CConnOptions::writeToFile(const char* filename) {
   FILE* f = fopen(filename, "w");
   if (!f)
     throw rdr::Exception("Failed to write configuration file");
@@ -298,11 +315,8 @@
       if (MsgBox(0, _T("Do you want to include the VNC Password in this configuration file?\n")
                     _T("Storing the password is more convenient but poses a security risk."),
                     MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING) == IDYES) {
-        char obfuscated[9];
-        memset(obfuscated, 0, sizeof(obfuscated));
-        strCopy(obfuscated, password.buf, sizeof(obfuscated));
-        vncAuthObfuscatePasswd(obfuscated);
-        CharArray obfuscatedHex = rdr::HexOutStream::binToHexStr(obfuscated, 8);
+        ObfuscatedPasswd obfPwd(password);
+        CharArray obfuscatedHex = rdr::HexOutStream::binToHexStr(obfPwd.buf, obfPwd.length);
         fprintf(f, "Password=%s\n", obfuscatedHex.buf);
       }
     }
@@ -323,6 +337,7 @@
     fprintf(f, "SendSysKeys=%d\n", (int)sendSysKeys);
     fprintf(f, "SendCutText=%d\n", (int)clientCutText);
     fprintf(f, "AcceptCutText=%d\n", (int)serverCutText);
+    fprintf(f, "DisableWinKeys=%d\n", (int)disableWinKeys);
     fprintf(f, "AcceptBell=%d\n", (int)acceptBell);
     fprintf(f, "Emulate3=%d\n", (int)emulate3);
     fprintf(f, "ShowToolbar=%d\n", (int)showToolbar);
@@ -330,6 +345,7 @@
     if (monitor.buf)
       fprintf(f, "Monitor=%s\n", monitor.buf);
     fprintf(f, "MenuKey=%s\n", CharArray(menuKeyName()).buf);
+    fprintf(f, "AutoReconnect=%d\n", (int)autoReconnect);
     fprintf(f, "CustomCompressLevel=%d\n", customCompressLevel);
     fprintf(f, "CompressLevel=%d\n", compressLevel);
     fprintf(f, "NoJPEG=%d\n", noJpeg);
@@ -344,7 +360,7 @@
 }
 
 
-void CViewOptions::writeDefaults() {
+void CConnOptions::writeDefaults() {
   RegKey key;
   key.createKey(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCviewer4"));
   key.setBool(_T("UseLocalCursor"), useLocalCursor);
@@ -360,6 +376,7 @@
   key.setBool(_T("SendSysKeys"), sendSysKeys);
   key.setBool(_T("ClientCutText"), clientCutText);
   key.setBool(_T("ServerCutText"), serverCutText);
+  key.setBool(_T("DisableWinKeys"), disableWinKeys);
   key.setBool(_T("Protocol3.3"), protocol3_3);
   key.setBool(_T("AcceptBell"), acceptBell);
   key.setBool(_T("ShowToolbar"), showToolbar);
@@ -368,6 +385,7 @@
   if (monitor.buf)
     key.setString(_T("Monitor"), TStr(monitor.buf));
   key.setString(_T("MenuKey"), TCharArray(menuKeyName()).buf);
+  key.setBool(_T("AutoReconnect"), autoReconnect);
   key.setInt(_T("CustomCompressLevel"), customCompressLevel);
   key.setInt(_T("CompressLevel"), compressLevel);
   key.setInt(_T("NoJPEG"), noJpeg);
@@ -375,13 +393,13 @@
 }
 
 
-void CViewOptions::setUserName(const char* user) {userName.replaceBuf(strDup(user));}
-void CViewOptions::setPassword(const char* pwd) {password.replaceBuf(strDup(pwd));}
-void CViewOptions::setConfigFileName(const char* cfn) {configFileName.replaceBuf(strDup(cfn));}
-void CViewOptions::setHost(const char* h) {host.replaceBuf(strDup(h));}
-void CViewOptions::setMonitor(const char* m) {monitor.replaceBuf(strDup(m));}
+void CConnOptions::setUserName(const char* user) {userName.replaceBuf(strDup(user));}
+void CConnOptions::setPassword(const char* pwd) {password.replaceBuf(strDup(pwd));}
+void CConnOptions::setConfigFileName(const char* cfn) {configFileName.replaceBuf(strDup(cfn));}
+void CConnOptions::setHost(const char* h) {host.replaceBuf(strDup(h));}
+void CConnOptions::setMonitor(const char* m) {monitor.replaceBuf(strDup(m));}
 
-void CViewOptions::setMenuKey(const char* keyName) {
+void CConnOptions::setMenuKey(const char* keyName) {
   if (!keyName[0]) {
     menuKey = 0;
   } else {
@@ -393,7 +411,7 @@
     }
   }
 }
-char* CViewOptions::menuKeyName() {
+char* CConnOptions::menuKeyName() {
   int fNum = (menuKey-VK_F1)+1;
   if (fNum<1 || fNum>12)
     return strDup("");
@@ -403,7 +421,7 @@
 }
 
 
-CViewOptions& CViewOptions::operator=(const CViewOptions& o) {
+CConnOptions& CConnOptions::operator=(const CConnOptions& o) {
   useLocalCursor = o.useLocalCursor;
   useDesktopResize = o.useDesktopResize;
   fullScreen = o.fullScreen;
@@ -417,6 +435,7 @@
   sendSysKeys = o.sendSysKeys;
   clientCutText = o.clientCutText;
   serverCutText = o.serverCutText;
+  disableWinKeys = o.disableWinKeys;
   emulate3 = o.emulate3;
   pointerEventInterval = o.pointerEventInterval;
   protocol3_3 = o.protocol3_3;
@@ -428,6 +447,7 @@
   setHost(o.host.buf);
   setMonitor(o.monitor.buf);
   menuKey = o.menuKey;
+  autoReconnect = o.autoReconnect;
   customCompressLevel = o.customCompressLevel;
   compressLevel = o.compressLevel;
   noJpeg = o.noJpeg;
diff --git a/vncviewer/CViewOptions.h b/vncviewer/CConnOptions.h
similarity index 76%
rename from vncviewer/CViewOptions.h
rename to vncviewer/CConnOptions.h
index febd284..52c3996 100644
--- a/vncviewer/CViewOptions.h
+++ b/vncviewer/CConnOptions.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -16,15 +16,15 @@
  * USA.
  */
 
-// -=- CViewOptions.h
+// -=- CConnOptions.h
 
-// Definition of the CViewOptions class, responsible for storing the
-// current & requested VNCviewer options.
+// Definition of the CConnOptions class, responsible for storing the
+// current & requested VNC Viewer options.
 
-#ifndef __RFB_WIN32_CVIEW_OPTIONS_H__
-#define __RFB_WIN32_CVIEW_OPTIONS_H__
+#ifndef __RFB_WIN32_CCONN_OPTIONS_H__
+#define __RFB_WIN32_CCONN_OPTIONS_H__
 
-#include <rfb/util.h>
+#include <rfb/Password.h>
 
 namespace rfb {
 
@@ -32,19 +32,19 @@
 
     //
     // -=- Options structure.  Each viewer option has a corresponding
-    //     entry in CViewOptions.  The viewer options are set by calling
-    //     CView::applyOptions(...)
-    //     The CViewOptions structure automatically picks up the default
+    //     entry in CConnOptions.  The viewer options are set by calling
+    //     CConn::applyOptions(...)
+    //     The CConnOptions structure automatically picks up the default
     //     value of each option from the Configuration system
     //     The readFromFile and writeFromFile methods can be used to load
     //     and save VNC configuration files.  readFromFile is backwards
     //     compatible with 3.3 releases, while writeToFile is not.
 
-    class CViewOptions {
+    class CConnOptions {
     public:
-      CViewOptions();
-      CViewOptions(const CViewOptions& o) {operator=(o);}
-      CViewOptions& operator=(const CViewOptions& o);
+      CConnOptions();
+      CConnOptions(const CConnOptions& o) {operator=(o);}
+      CConnOptions& operator=(const CConnOptions& o);
       void readFromFile(const char* filename_);
       void writeToFile(const char* filename_);
       void writeDefaults();
@@ -62,13 +62,14 @@
       bool showToolbar;
       bool clientCutText;
       bool serverCutText;
+      bool disableWinKeys;
       bool emulate3;
       int pointerEventInterval;
       bool protocol3_3;
       bool acceptBell;
       CharArray userName;
       void setUserName(const char* user);
-      CharArray password;
+      PlainPasswd password;
       void setPassword(const char* pwd);
       CharArray configFileName;
       void setConfigFileName(const char* cfn);
@@ -79,6 +80,7 @@
       unsigned int menuKey;
       void setMenuKey(const char* keyName);
       char* menuKeyName();
+      bool autoReconnect;
 
       bool customCompressLevel;
       int compressLevel;
diff --git a/vncviewer/CConnThread.cxx b/vncviewer/CConnThread.cxx
new file mode 100644
index 0000000..cfd2695
--- /dev/null
+++ b/vncviewer/CConnThread.cxx
@@ -0,0 +1,198 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- CConnThread.cxx
+
+// A CConnThread instance is created for each new connection.
+// The CConnThread creates the corresponding CConn instance
+// and manages it.
+
+#include <stdlib.h>
+#include <rfb/LogWriter.h>
+#include <rfb/Hostname.h>
+#include <rfb_win32/MsgBox.h>
+#include <network/TcpSocket.h>
+#include <vncviewer/CConnThread.h>
+#include <vncviewer/CConn.h>
+#include <vncviewer/ConnectionDialog.h>
+#include <vncviewer/ConnectingDialog.h>
+#include <vncviewer/UserPasswdDialog.h>
+#include <set>
+
+using namespace rfb;
+using namespace win32;
+
+static LogWriter vlog("CConnThread");
+
+static std::set<CConnThread*> threads;
+static Mutex threadsLock;
+static Handle noMoreThreads(CreateEvent(0, TRUE, FALSE, 0));
+
+
+CConnThread::CConnThread() : Thread("CConnThread"), isConfig(false),
+                             sock(0), reverse(false) {
+  vlog.info("CConnThread (dialog)");
+  setDeleteAfterRun();
+  Lock l(threadsLock);
+  threads.insert(this);
+  start();
+}
+
+CConnThread::CConnThread(const char* hostOrConfig_, bool isConfig_)
+ : Thread("CConnThread"), hostOrConfig(strDup(hostOrConfig_)),
+   isConfig(isConfig_), sock(0), reverse(false) {
+  vlog.info("CConnThread (host/port)");
+  setDeleteAfterRun();
+  Lock l(threadsLock);
+  threads.insert(this);
+  start();
+}
+
+CConnThread::CConnThread(network::Socket* sock_, bool reverse_)
+ : Thread("CConnThread"), isConfig(false), sock(sock_), reverse(reverse_) {
+  vlog.info("CConnThread (reverse connection)");
+  setDeleteAfterRun();
+  Lock l(threadsLock);
+  threads.insert(this);
+  start();
+}
+
+CConnThread::~CConnThread() {
+  Lock l(threadsLock);
+  threads.erase(this);
+  if (threads.empty())
+    SetEvent(noMoreThreads);
+  delete sock;
+}
+
+
+void CConnThread::run() {
+  CConnOptions options;
+  bool reconnect;
+
+  do {
+    {
+      CConn conn;
+      reconnect = false;
+
+      // If there is no socket object then set the host & port info
+      if (!sock && !options.host.buf) {
+        try {
+          if (isConfig) {
+            // A configuration file name was specified - load it
+            CharArray filename = hostOrConfig.takeBuf();
+            options.readFromFile(filename.buf);
+          } else {
+            // An actual hostname (and possibly port) was specified
+            options.host.replaceBuf(hostOrConfig.takeBuf());
+          }
+
+          if (!options.host.buf) {
+            // No host was specified - prompt for one
+            ConnectionDialog connDlg(&conn);
+            if (!connDlg.showDialog())
+              return;
+            options = conn.getOptions();
+            options.setHost(CStr(connDlg.hostname.buf));
+          }
+        } catch (rdr::Exception& e) {
+          MsgBox(0, TStr(e.str()), MB_ICONERROR | MB_OK);
+          return;
+        }
+      }
+
+      // Apply the connection options to the CConn
+      conn.applyOptions(options);
+
+      if (!sock) {
+        // There is no existing connection - better make one
+        const char* hostAndPort = conn.getOptions().host.buf;
+
+        try {
+          ConnectingDialog dlg;
+          sock = dlg.connect(hostAndPort);
+
+          // If the connection was cancelled by the user, just quit
+          if (!sock)
+            return;
+        } catch(rdr::Exception& e) {
+          MsgBox(NULL, TStr(e.str()), MB_ICONERROR | MB_OK);
+          return;
+        }
+
+        // Try to add the caller to the MRU
+        MRU::addToMRU(hostAndPort);
+      }
+
+      // Run the RFB protocol over the connected socket
+      conn.initialise(sock, reverse);
+      while (!conn.isClosed()) {
+        try {
+          conn.getInStream()->check(1,1);
+          conn.processMsg();
+        } catch (rdr::EndOfStream) {
+          if (conn.state() == CConnection::RFBSTATE_NORMAL)
+            conn.close();
+          else
+            conn.close("The connection closed unexpectedly");
+        } catch (rfb::AuthCancelledException) {
+          conn.close();
+        } catch (rfb::AuthFailureException& e) {
+          // Clear the password, in case we auto-reconnect
+          options = conn.getOptions();
+          options.password.replaceBuf(0);
+          conn.applyOptions(options);
+          conn.close(e.str());
+        } catch (rdr::Exception& e) {
+          conn.close(e.str());
+        }
+      }
+
+      // If there is a cause for closing the connection logged then display it
+      if (conn.closeReason()) {
+        reconnect = !reverse && conn.getOptions().autoReconnect;
+        if (!reconnect) {
+          MsgBox(0, TStr(conn.closeReason()), MB_ICONINFORMATION | MB_OK);
+        } else {
+          options = conn.getOptions();
+          const char* format = "%s\nDo you wish to attempt to reconnect to %s?";
+          CharArray message(strlen(conn.closeReason()) + strlen(format) +
+                            strlen(conn.getOptions().host.buf));
+          sprintf(message.buf, format, conn.closeReason(), conn.getOptions().host.buf);
+          if (MsgBox(0, TStr(message.buf), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) != IDYES)
+            reconnect = false;
+        }
+      }
+    } // Exit the CConn's scope, implicitly destroying it & making it safe to delete the TcpSocket
+
+    // Clean up the old socket, if any
+    delete sock; sock = 0;
+  } while (reconnect);
+}
+
+
+BOOL CConnThread::getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg) {
+  while (!PeekMessage(msg, hwnd, minMsg, maxMsg, PM_REMOVE)) {
+    DWORD result = MsgWaitForMultipleObjects(1, &noMoreThreads.h, FALSE, INFINITE, QS_ALLINPUT);
+    if (result == WAIT_OBJECT_0)
+      return FALSE;
+    else if (result == WAIT_FAILED)
+      throw rdr::SystemException("CConnThread::getMessage wait failed", GetLastError());
+  }
+  return msg->message != WM_QUIT;
+}
diff --git a/vncviewer/CConnThread.h b/vncviewer/CConnThread.h
new file mode 100644
index 0000000..7a8451c
--- /dev/null
+++ b/vncviewer/CConnThread.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- CConnThread.h
+
+// CConn-managing Thread implementation.
+
+#ifndef __RFB_WIN32_CCONN_THREAD_H__
+#define __RFB_WIN32_CCONN_THREAD_H__
+
+#include <network/Socket.h>
+#include <rfb/Threading.h>
+#include <rfb/util.h>
+
+namespace rfb {
+
+  namespace win32 {
+
+    class CConnThread : public Thread {
+    public:
+      CConnThread();
+      CConnThread(const char* hostOrConfig, bool isConfig=false);
+      CConnThread(network::Socket* sock, bool reverse=false);
+      ~CConnThread();
+
+      void run();
+
+      // Special getMessage call that returns FALSE if message is WM_QUIT,
+      // OR if there are no more CConnThreads running.
+      static BOOL getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg);
+    protected:
+      CharArray hostOrConfig;
+      bool isConfig;
+      network::Socket* sock;
+      bool reverse;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_CCONN_THREAD_H__
diff --git a/vncviewer/CViewManager.cxx b/vncviewer/CViewManager.cxx
deleted file mode 100644
index 09ed1fe..0000000
--- a/vncviewer/CViewManager.cxx
+++ /dev/null
@@ -1,252 +0,0 @@
-/* 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 <winsock2.h>
-#include <vncviewer/CViewManager.h>
-#include <vncviewer/CView.h>
-#include <vncviewer/ConnectionDialog.h>
-#include <vncviewer/ConnectingDialog.h>
-#include <rfb/Hostname.h>
-#include <rfb/util.h>
-#include <rfb/LogWriter.h>
-#include <rfb/vncAuth.h>
-#include <rdr/HexInStream.h>
-#include <network/TcpSocket.h>
-
-using namespace rfb;
-using namespace win32;
-
-static LogWriter vlog("CViewManager");
-
-
-// -=- Custom thread class used internally
-
-class CViewThread : public Thread {
-public:
-  CViewThread(network::Socket* s, CViewManager& cvm);
-  CViewThread(const char* conninfo, CViewManager& cvm, bool infoIsConfigFile);
-  virtual ~CViewThread();
-
-  virtual void run();
-protected:
-  void setSocket(network::Socket* sock);
-
-  network::Socket* sock;
-  CharArray hostname;
-  CViewManager& manager;
-
-  bool useConfigFile;
-};
-
-
-CViewThread::CViewThread(network::Socket* s, CViewManager& cvm)
-: Thread("CView"), sock(s), manager(cvm) {
-  setDeleteAfterRun();
-}
-
-CViewThread::CViewThread(const char* h, CViewManager& cvm, bool hIsConfigFile)
-: Thread("CView"), sock(0), manager(cvm), useConfigFile(hIsConfigFile) {
-  setDeleteAfterRun();
-  if (h) hostname.buf = strDup(h);
-}
-
-
-CViewThread::~CViewThread() {
-  vlog.debug("~CViewThread");
-  manager.remThread(this);
-  delete sock;
-}
-
-
-void CViewThread::run() {
-  try {
-    CView view;
-    view.setManager(&manager);
-
-    if (!sock) {
-      try {
-        // If the hostname is actually a config filename then read it
-        if (useConfigFile) {
-          CharArray filename = hostname.takeBuf();
-          CViewOptions options;
-          options.readFromFile(filename.buf);
-          if (options.host.buf)
-            hostname.buf = strDup(options.host.buf);
-          view.applyOptions(options);
-        }
-
-        // If there is no hostname then present the connection
-        // dialog
-        if (!hostname.buf) {
-          ConnectionDialog conn(&view);
-          if (!conn.showDialog())
-            return;
-          hostname.buf = strDup(conn.hostname.buf);
-
-          // *** hack - Tell the view object the hostname
-          CViewOptions opt(view.getOptions());
-          opt.setHost(hostname.buf);
-          view.applyOptions(opt);
-        }
-
-        // Parse the host name & port
-        CharArray host;
-        int port;
-        getHostAndPort(hostname.buf, &host.buf, &port);
-
-        // Attempt to connect
-        ConnectingDialog dlg;
-        // this is a nasty hack to get round a Win2K and later "feature" which
-        // puts your second window in the background unless the first window
-        // you put up actually gets some input.  Just generate a fake shift
-        // event, which seems to do the trick.
-        keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), 0, 0);
-        keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), KEYEVENTF_KEYUP, 0);
-        sock = new network::TcpSocket(host.buf, port);
-      } catch(rdr::Exception& e) {
-        vlog.error("unable to connect to %s (%s)", hostname, e.str());
-        MsgBox(NULL, TStr(e.str()), MB_ICONERROR | MB_OK);
-        return;
-      }
-
-      // Try to add the caller to the MRU
-      MRU::addToMRU(hostname.buf);
-    }
-
-    view.initialise(sock);
-    try {
-      view.postQuitOnDestroy(true);
-      while (true) {
-        // - processMsg is designed to be callable in response to select().
-        //   As a result, it can be called when FdInStream data is available,
-        //   BUT there may be no actual RFB data available.  This is the case
-        //   for example when reading data over an encrypted stream - an
-        //   entire block must be read from the FdInStream before any data
-        //   becomes available through the top-level encrypted stream.
-        //   Since we are using blockCallback and not doing a select() here,
-        //   we simply check() for some data on the top-level RFB stream.
-        //   This ensures that processMsg will only be called when there is
-        //   actually something to do.  In the meantime, blockCallback()
-        //   will be called, keeping the user interface responsive.
-        view.getInStream()->check(1,1);
-        view.processMsg();
-      }
-    } catch (CView::QuitMessage& e) {
-      // - Cope silently with WM_QUIT messages
-      vlog.debug("QuitMessage received (wParam=%d)", e.wParam);
-    } catch (rdr::EndOfStream& e) {
-      // - Copy silently with disconnection if in NORMAL state
-      if (view.state() == CConnection::RFBSTATE_NORMAL)
-        vlog.debug(e.str());
-      else {
-        view.postQuitOnDestroy(false);
-        throw rfb::Exception("server closed connection unexpectedly");
-      }
-    } catch (rdr::Exception&) {
-      // - We MUST do this, otherwise ~CView will cause a
-      //   PostQuitMessage and any MessageBox call will quit immediately.
-      view.postQuitOnDestroy(false);
-      throw;
-    }
-  } catch(rdr::Exception& e) {
-    // - Something went wrong - display the error
-    vlog.error("error: %s", e.str());
-    MsgBox(NULL, TStr(e.str()), MB_ICONERROR | MB_OK);
-  }
-}
-
-
-// -=- CViewManager itself
-
-CViewManager::CViewManager()
-: MsgWindow(_T("CViewManager")), threadsSig(threadsMutex),
-  mainThread(Thread::self()) {
-}
-
-CViewManager::~CViewManager() {
-  while (!socks.empty()) {
-    network::SocketListener* sock = socks.front();
-    delete sock;
-    socks.pop_front();
-  }
-  awaitEmpty();
-}
-
-
-void CViewManager::awaitEmpty() {
-  Lock l(threadsMutex);
-  while (!threads.empty()) {
-    threadsSig.wait(true);
-  }
-}
-
-
-void CViewManager::addThread(Thread* t) {
-  Lock l(threadsMutex);
-  threads.push_front(t);
-}
-
-void CViewManager::remThread(Thread* t) {
-  Lock l(threadsMutex);
-  threads.remove(t);
-  threadsSig.signal();
-
-  // If there are no listening sockets then post a quit message when the
-  // last client disconnects
-  if (socks.empty())
-    PostThreadMessage(mainThread->getThreadId(), WM_QUIT, 0, 0);
-}
-
-
-bool CViewManager::addClient(const char* hostinfo, bool isConfigFile) {
-  CViewThread* thread = new CViewThread(hostinfo, *this, isConfigFile);
-  addThread(thread);
-  thread->start();
-  return true;
-}
-
-bool CViewManager::addListener(network::SocketListener* sock) {
-  socks.push_back(sock);
-  WSAAsyncSelect(sock->getFd(), getHandle(), WM_USER, FD_ACCEPT);
-  return true;
-}
-
-bool CViewManager::addDefaultTCPListener(int port) {
-  return addListener(new network::TcpListener(port));
-}
-
-
-LRESULT CViewManager::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
-  switch (msg) {
-  case WM_USER:
-    std::list<network::SocketListener*>::iterator i;
-    for (i=socks.begin(); i!=socks.end(); i++) {
-      if (wParam == (*i)->getFd()) {
-        network::Socket* new_sock = (*i)->accept();
-        CharArray connname;
-        connname.buf = new_sock->getPeerEndpoint();
-        vlog.debug("accepted connection: %s", connname);
-        CViewThread* thread = new CViewThread(new_sock, *this);
-        addThread(thread);
-        thread->start();
-        break;
-      }
-    }
-    break;
-  }
-  return MsgWindow::processMessage(msg, wParam, lParam);
-}
diff --git a/vncviewer/CViewManager.h b/vncviewer/CViewManager.h
deleted file mode 100644
index 3d11dd9..0000000
--- a/vncviewer/CViewManager.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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.
- */
-
-// -=- CViewManager.h
-
-// Creates and manages threads to run CView instances.
-
-#ifndef __RFB_WIN32_CVIEW_MANAGER_H__
-#define __RFB_WIN32_CVIEW_MANAGER_H__
-
-#include <list>
-#include <network/Socket.h>
-#include <rfb/Threading.h>
-#include <rfb_win32/MsgWindow.h>
-
-namespace rfb {
-
-  namespace win32 {
-
-    class CViewManager : public MsgWindow {
-    public:
-      CViewManager();
-      ~CViewManager();
-
-      void awaitEmpty();
-
-      void addThread(Thread* t);
-      void remThread(Thread* t);
-
-      bool addClient(const char* hostinfo, bool isConfigFile=false);
-
-      bool addListener(network::SocketListener* sock);
-      bool addDefaultTCPListener(int port);
-
-      LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
-
-    protected:
-      std::list<network::SocketListener*> socks;
-      std::list<Thread*> threads;
-      Mutex threadsMutex;
-      Condition threadsSig;
-      Thread* mainThread;
-    };
-
-  };
-
-};
-
-#endif
diff --git a/vncviewer/ConnectingDialog.cxx b/vncviewer/ConnectingDialog.cxx
new file mode 100644
index 0000000..60fcb66
--- /dev/null
+++ b/vncviewer/ConnectingDialog.cxx
@@ -0,0 +1,160 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- ConnectingDialog.cxx
+
+#include <stdlib.h>
+#include <vncviewer/ConnectingDialog.h>
+#include <vncviewer/resource.h>
+#include <network/TcpSocket.h>
+#include <rfb/Threading.h>
+#include <rfb/Hostname.h>
+#include <map>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+
+// ConnectingDialog callback
+static BOOL CALLBACK ConnectingDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
+  bool* activePtr = (bool*)GetWindowLong(hwnd, GWL_USERDATA);
+  switch (uMsg) {
+  case WM_INITDIALOG:
+    SetWindowLong(hwnd, GWL_USERDATA, lParam);
+    return TRUE;
+	case WM_COMMAND:
+	  switch (LOWORD(wParam)) {
+	  case IDCANCEL:
+      if (activePtr)
+        *activePtr = false;
+		  return TRUE;
+		}
+		break;
+	case WM_DESTROY:
+    if (activePtr)
+      *activePtr = false;
+	  return TRUE;
+	}
+	return 0;
+}
+
+
+// Global map, used by ConnectingDialog::Threads to call back to their owning
+// ConnectingDialogs, while coping with the fact that the owner may already have quit.
+static std::map<int, ConnectingDialog*> dialogs;
+static int nextDialogId = 0;
+static Mutex dialogsLock;
+
+
+// ConnectingDialog::Thread
+//   Attempts to connect to the specified host.  If the connection succeeds, the
+//   socket is saved in the owning ConnectingDialog, if still available, and the
+//   event is signalled.  If the connection fails, the Exception text is returned
+//   to the dialog.  If the dialog is already gone, the Exception/socket are discarded.
+//   NB: This thread class cleans itself up on exit - DO NOT join()!
+class ConnectingDialog::Thread : public rfb::Thread {
+public:
+  Thread(int dialogId_, const char* hostAndPort) : dialogId(dialogId_) {
+    setDeleteAfterRun();
+    getHostAndPort(hostAndPort, &host.buf, &port);
+  }
+  virtual void run() {
+    try {
+      returnSock(new network::TcpSocket(host.buf, port));
+    } catch (rdr::Exception& e) {
+      returnException(e);
+    }
+  }
+  void returnSock(network::Socket* s) {
+    Lock l(dialogsLock);
+    if (dialogs.count(dialogId)) {
+      dialogs[dialogId]->newSocket = s;
+      SetEvent(dialogs[dialogId]->readyEvent);
+    } else {
+      delete s;
+    }
+  }
+  void returnException(const rdr::Exception& e) {
+    Lock l(dialogsLock);
+    if (dialogs.count(dialogId)) {
+      dialogs[dialogId]->errMsg.replaceBuf(strDup(e.str()));
+      SetEvent(dialogs[dialogId]->readyEvent);
+    }
+  };
+  CharArray host;
+  int port;
+  int dialogId;
+};
+
+
+ConnectingDialog::ConnectingDialog() : dialog(0), readyEvent(CreateEvent(0, TRUE, FALSE, 0)),
+                                       newSocket(0), dialogId(0) {
+}
+
+network::Socket* ConnectingDialog::connect(const char* hostAndPort) {
+  Thread* connectThread = 0;
+  bool active = true;
+  errMsg.replaceBuf(0);
+  newSocket = 0;
+
+  // Get a unique dialog identifier and create the dialog window
+  {
+    Lock l(dialogsLock);
+    dialogId = ++nextDialogId;
+    dialogs[dialogId] = this;
+    dialog = CreateDialogParam(GetModuleHandle(0),
+      MAKEINTRESOURCE(IDD_CONNECTING_DLG), 0, &ConnectingDlgProc, (long)&active);
+    ShowWindow(dialog, SW_SHOW);
+    ResetEvent(readyEvent);
+  }
+
+  // Create and start the connection thread
+  try {
+    connectThread = new Thread(dialogId, hostAndPort);
+    connectThread->start();
+  } catch (rdr::Exception& e) {
+    errMsg.replaceBuf(strDup(e.str()));
+    active = false;
+  }
+
+  // Process window messages until the connection thread signals readyEvent, or the dialog is cancelled
+  while (active && (MsgWaitForMultipleObjects(1, &readyEvent.h, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)) {
+    MSG msg;
+    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+      DispatchMessage(&msg);
+  }
+
+  // Remove this dialog from the table
+  //   NB: If the dialog was cancelled then the thread is still running, and will only
+  //       discover that we're gone when it looks up our unique Id in the dialog table.
+  {
+    Lock l(dialogsLock);
+    dialogs.erase(dialogId);
+  }
+
+  // Close the dialog window
+  DestroyWindow(dialog); dialog=0;
+
+  // Throw the exception, if there was one
+  if (errMsg.buf)
+    throw rdr::Exception(errMsg.buf);
+
+  // Otherwise, return the socket
+  //   NB: The socket will be null if the dialog was cancelled
+  return newSocket;
+}
diff --git a/vncviewer/ConnectingDialog.h b/vncviewer/ConnectingDialog.h
index b146ced..c38b3a1 100644
--- a/vncviewer/ConnectingDialog.h
+++ b/vncviewer/ConnectingDialog.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -18,78 +18,48 @@
 
 // -=- ConnectingDialog.h
 
-// Dialog to indicate to the user that the viewer is attempting to make an
-// outgoing connection.
+// ConnectingDialog instances are used to display a status dialog while a
+// connection attempt is in progress.  The connection attempt is performed
+// in a background thread by the ConnectingDialog, to allow the status dialog
+// to remain interactive.  If the dialog is cancelled then it will close and
+// the connection dialog will eventually tidy itself up.
 
 #ifndef __RFB_WIN32_CONNECTING_DLG_H__
 #define __RFB_WIN32_CONNECTING_DLG_H__
 
-#include <rfb_win32/Dialog.h>
-#include <rfb/Threading.h>
-#include <vncviewer/resource.h>
+#include <windows.h>
+#include <network/Socket.h>
+#include <rfb/util.h>
+#include <rfb_win32/Handle.h>
 
 namespace rfb {
 
   namespace win32 {
 
-    BOOL CALLBACK ConnectingDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
-	    switch (uMsg) {
-	    case WM_INITDIALOG:
-		    {
-			    SetWindowLong(hwnd, GWL_USERDATA, lParam);
-			    return TRUE;
-		    }
-	    case WM_COMMAND:
-		    switch (LOWORD(wParam)) {
-		    case IDCANCEL:
-          network::Socket* sock = (network::Socket*) GetWindowLong(hwnd, GWL_USERDATA);
-          sock->shutdown();
-			    EndDialog(hwnd, FALSE);
-			    return TRUE;
-		    }
-		    break;
-	    case WM_DESTROY:
-		    EndDialog(hwnd, TRUE);
-		    return TRUE;
-	    }
-	    return 0;
-    }
-
-    // *** hacky bit - should use async connect so dialog behaves properly
-    class ConnectingDialog : public Thread {
+    class ConnectingDialog {
     public:
-      ConnectingDialog() : Thread("ConnectingDialog") {
-        dialog = 0;
-        active = true;
-        start();
-      }
-      virtual ~ConnectingDialog() {
-        // *** join() required here because otherwise ~Thread calls Thread::join()
-        join();
-      }
-      virtual void run() {
-        dialog = CreateDialogParam(GetModuleHandle(0),
-          MAKEINTRESOURCE(IDD_CONNECTING_DLG), 0, &ConnectingDlgProc, 0);
-        ShowWindow(dialog, SW_SHOW);
-        MSG msg;
-        while (active && GetMessage(&msg, dialog, 0, 0)) {
-          DispatchMessage(&msg);
-        }
-        DestroyWindow(dialog);
-      }
-      virtual Thread* join() {
-        active = false;
-        if (dialog)
-          PostMessage(dialog, WM_QUIT, 0, 0);
-        return Thread::join();
-      }
+      ConnectingDialog();
+
+      // connect
+      //   Show a Connecting dialog and attempt to connect to the specified host
+      //   in the background.
+      //   If the connection succeeds then the Socket is returned.
+      //   If an error occurs, an Exception is thrown.
+      //   If the dialog is cancelled then null is returned.
+      network::Socket* connect(const char* hostAndPort);
     protected:
       HWND dialog;
-      bool active;
+      network::Socket* newSocket;
+      CharArray errMsg;
+      Handle readyEvent;
+      int dialogId;
+
+      class Thread;
+      friend class Thread;
     };
 
   };
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/vncviewer/ConnectionDialog.cxx b/vncviewer/ConnectionDialog.cxx
index c083444..e7c6b0a 100644
--- a/vncviewer/ConnectionDialog.cxx
+++ b/vncviewer/ConnectionDialog.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -15,9 +15,11 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
+
 #include <vncviewer/ConnectionDialog.h>
-#include <vncviewer/CView.h>
+#include <vncviewer/CConn.h>
 #include <vncviewer/resource.h>
+#include <rfb_win32/AboutDialog.h>
 
 #include <tchar.h>
 
@@ -25,7 +27,7 @@
 using namespace rfb::win32;
 
 
-ConnectionDialog::ConnectionDialog(CView* view_) : Dialog(GetModuleHandle(0)), view(view_) {
+ConnectionDialog::ConnectionDialog(CConn* conn_) : Dialog(GetModuleHandle(0)), conn(conn_) {
 }
 
 
@@ -47,6 +49,13 @@
 
   // Select the first item in the list
   SendMessage(box, CB_SETCURSEL, 0, 0);
+
+  // Fill out the Security: drop-down and select the preferred option
+  HWND security = GetDlgItem(handle, IDC_SECURITY_LEVEL);
+  LRESULT n = SendMessage(security, CB_ADDSTRING, 0, (LPARAM)_T("Always Off"));
+  if (n != CB_ERR)
+    SendMessage(security, CB_SETCURSEL, n, 0);
+  enableItem(IDC_SECURITY_LEVEL, false);
 }
 
 
@@ -63,7 +72,7 @@
     AboutDialog::instance.showDialog();
     return true;
   case IDC_OPTIONS:
-    view->optionsDialog.showDialog(view);
+    conn->showOptionsDialog();
     return true;
   };
   return false;
diff --git a/vncviewer/ConnectionDialog.h b/vncviewer/ConnectionDialog.h
index 554c86f..f739280 100644
--- a/vncviewer/ConnectionDialog.h
+++ b/vncviewer/ConnectionDialog.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -31,18 +31,18 @@
 
   namespace win32 {
 
-    class CView;
+    class CConn;
 
     class ConnectionDialog : Dialog {
     public:
-      ConnectionDialog(CView* view);
+      ConnectionDialog(CConn* view);
       virtual bool showDialog();
       virtual void initDialog();
       virtual bool onOk();
       virtual bool onCommand(int id, int cmd);
       TCharArray hostname;
     protected:
-      CView* view;
+      CConn* conn;
     };
 
   };
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
new file mode 100644
index 0000000..311a586
--- /dev/null
+++ b/vncviewer/DesktopWindow.cxx
@@ -0,0 +1,1076 @@
+/* Copyright (C) 2002-2005 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 <windows.h>
+#include <commctrl.h>
+#include <rfb/Configuration.h>
+#include <rfb/LogWriter.h>
+#include <rfb_win32/WMShatter.h>
+#include <rfb_win32/LowLevelKeyEvents.h>
+#include <rfb_win32/MonitorInfo.h>
+#include <rfb_win32/DeviceContext.h>
+#include <rfb_win32/Win32Util.h>
+#include <vncviewer/DesktopWindow.h>
+#include <vncviewer/resource.h>
+
+using namespace rfb;
+using namespace rfb::win32;
+
+
+// - Statics & consts
+
+static LogWriter vlog("DesktopWindow");
+
+const int TIMER_BUMPSCROLL = 1;
+const int TIMER_POINTER_INTERVAL = 2;
+const int TIMER_POINTER_3BUTTON = 3;
+
+
+//
+// -=- DesktopWindowClass
+
+//
+// Window class used as the basis for all DesktopWindow instances
+//
+
+class DesktopWindowClass {
+public:
+  DesktopWindowClass();
+  ~DesktopWindowClass();
+  ATOM classAtom;
+  HINSTANCE instance;
+};
+
+LRESULT CALLBACK DesktopWindowProc(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);
+  DesktopWindow* _this = (DesktopWindow*) GetWindowLong(wnd, GWL_USERDATA);
+  if (!_this) {
+    vlog.info("null _this in %x, message %u", wnd, msg);
+    return rfb::win32::SafeDefWindowProc(wnd, msg, wParam, lParam);
+  }
+
+  try {
+    result = _this->processMessage(msg, wParam, lParam);
+  } catch (rdr::Exception& e) {
+    vlog.error("untrapped: %s", e.str());
+  }
+
+  return result;
+};
+
+static HCURSOR dotCursor = (HCURSOR)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDC_DOT_CURSOR), IMAGE_CURSOR, 0, 0, LR_SHARED);
+static HCURSOR arrowCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED); 
+
+DesktopWindowClass::DesktopWindowClass() : classAtom(0) {
+  WNDCLASS wndClass;
+  wndClass.style = 0;
+  wndClass.lpfnWndProc = DesktopWindowProc;
+  wndClass.cbClsExtra = 0;
+  wndClass.cbWndExtra = 0;
+  wndClass.hInstance = instance = GetModuleHandle(0);
+  wndClass.hIcon = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 0, 0, LR_SHARED);
+  if (!wndClass.hIcon)
+    printf("unable to load icon:%ld", GetLastError());
+  wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+  wndClass.hbrBackground = NULL;
+  wndClass.lpszMenuName = 0;
+  wndClass.lpszClassName = _T("rfb::win32::DesktopWindowClass");
+  classAtom = RegisterClass(&wndClass);
+  if (!classAtom) {
+    throw rdr::SystemException("unable to register DesktopWindow window class", GetLastError());
+  }
+}
+
+DesktopWindowClass::~DesktopWindowClass() {
+  if (classAtom) {
+    UnregisterClass((const TCHAR*)classAtom, instance);
+  }
+}
+
+DesktopWindowClass baseClass;
+
+//
+// -=- FrameClass
+
+//
+// Window class used for child windows that display pixel data
+//
+
+class FrameClass {
+public:
+  FrameClass();
+  ~FrameClass();
+  ATOM classAtom;
+  HINSTANCE instance;
+};
+
+LRESULT CALLBACK FrameProc(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);
+  DesktopWindow* _this = (DesktopWindow*) GetWindowLong(wnd, GWL_USERDATA);
+  if (!_this) {
+    vlog.info("null _this in %x, message %u", wnd, msg);
+    return rfb::win32::SafeDefWindowProc(wnd, msg, wParam, lParam);
+  }
+
+  try {
+    result = _this->processFrameMessage(msg, wParam, lParam);
+  } catch (rdr::Exception& e) {
+    vlog.error("untrapped: %s", e.str());
+  }
+
+  return result;
+}
+
+FrameClass::FrameClass() : classAtom(0) {
+  WNDCLASS wndClass;
+  wndClass.style = 0;
+  wndClass.lpfnWndProc = FrameProc;
+  wndClass.cbClsExtra = 0;
+  wndClass.cbWndExtra = 0;
+  wndClass.hInstance = instance = GetModuleHandle(0);
+  wndClass.hIcon = 0;
+  wndClass.hCursor = NULL;
+  wndClass.hbrBackground = NULL;
+  wndClass.lpszMenuName = 0;
+  wndClass.lpszClassName = _T("rfb::win32::FrameClass");
+  classAtom = RegisterClass(&wndClass);
+  if (!classAtom) {
+    throw rdr::SystemException("unable to register Frame window class", GetLastError());
+  }
+}
+
+FrameClass::~FrameClass() {
+  if (classAtom) {
+    UnregisterClass((const TCHAR*)classAtom, instance);
+  }
+}
+
+FrameClass frameClass;
+
+
+//
+// -=- DesktopWindow instance implementation
+//
+
+DesktopWindow::DesktopWindow(Callback* cb) 
+  : buffer(0),
+    showToolbar(true),
+    client_size(0, 0, 16, 16), window_size(0, 0, 32, 32),
+    cursorVisible(false), cursorAvailable(false), cursorInBuffer(false),
+    systemCursorVisible(true), trackingMouseLeave(false),
+    handle(0), frameHandle(0), has_focus(false), palette_changed(false),
+    fullscreenActive(false), fullscreenRestore(false),
+    bumpScroll(false), callback(cb) {
+
+  // Create the window
+  const char* name = "DesktopWindow";
+  handle = CreateWindow((const TCHAR*)baseClass.classAtom, TStr(name),
+    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
+    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)", name, handle);
+
+  // Create the toolbar
+  tb.create(getHandle());
+  vlog.debug("created toolbar window \"%s\" (%x)", "ViewerToolBar", tb.getHandle());
+
+  // Create the frame window
+  frameHandle = CreateWindowEx(WS_EX_CLIENTEDGE, (const TCHAR*)frameClass.classAtom,
+    0, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
+    CW_USEDEFAULT, CW_USEDEFAULT, getHandle(), 0, frameClass.instance, this);
+  if (!frameHandle) {
+    throw rdr::SystemException("unable to create rfb frame window instance", GetLastError());
+  }
+  vlog.debug("created window \"%s\" (%x)", "Frame Window", frameHandle);
+
+  // Initialise the CPointer pointer handler
+  ptr.setHWND(frameHandle);
+  ptr.setIntervalTimerId(TIMER_POINTER_INTERVAL);
+  ptr.set3ButtonTimerId(TIMER_POINTER_3BUTTON);
+
+  // Initialise the bumpscroll timer
+  bumpScrollTimer.setHWND(handle);
+  bumpScrollTimer.setId(TIMER_BUMPSCROLL);
+
+  // Hook the clipboard
+  clipboard.setNotifier(this);
+
+  // Create the backing buffer
+  buffer = new win32::DIBSectionBuffer(frameHandle);
+
+  // Show the window
+  centerWindow(handle, 0);
+  ShowWindow(handle, SW_SHOW);
+}
+
+DesktopWindow::~DesktopWindow() {
+  vlog.debug("~DesktopWindow");
+  showSystemCursor();
+  if (handle) {
+    disableLowLevelKeyEvents(handle);
+    DestroyWindow(handle);
+    handle = 0;
+  }
+  delete buffer;
+  vlog.debug("~DesktopWindow done");
+}
+
+
+void DesktopWindow::setFullscreen(bool fs) {
+  if (fs && !fullscreenActive) {
+    fullscreenActive = bumpScroll = true;
+
+    // Un-minimize the window if required
+    if (GetWindowLong(handle, GWL_STYLE) & WS_MINIMIZE)
+      ShowWindow(handle, SW_RESTORE);
+
+    // Save the current window position
+    GetWindowRect(handle, &fullscreenOldRect);
+
+    // Find the size of the display the window is on
+    MonitorInfo mi(handle);
+
+    // Hide the toolbar
+    if (showToolbar)
+      tb.hide();
+    SetWindowLong(frameHandle, GWL_EXSTYLE, 0);
+
+    // Set the window full-screen
+    DWORD flags = GetWindowLong(handle, GWL_STYLE);
+    fullscreenOldFlags = flags;
+    flags = flags & ~(WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZE | WS_MINIMIZE);
+    vlog.debug("flags=%x", flags);
+
+    SetWindowLong(handle, GWL_STYLE, flags);
+    SetWindowPos(handle, HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top,
+      mi.rcMonitor.right-mi.rcMonitor.left,
+      mi.rcMonitor.bottom-mi.rcMonitor.top,
+      SWP_FRAMECHANGED);
+  } else if (!fs && fullscreenActive) {
+    fullscreenActive = bumpScroll = false;
+
+    // Show the toolbar
+    if (showToolbar)
+      tb.show();
+    SetWindowLong(frameHandle, GWL_EXSTYLE, WS_EX_CLIENTEDGE);
+
+    // Set the window non-fullscreen
+    SetWindowLong(handle, GWL_STYLE, fullscreenOldFlags);
+
+    // Set the window position
+    SetWindowPos(handle, HWND_NOTOPMOST,
+      fullscreenOldRect.left, fullscreenOldRect.top,
+      fullscreenOldRect.right - fullscreenOldRect.left, 
+      fullscreenOldRect.bottom - fullscreenOldRect.top,
+      SWP_FRAMECHANGED);
+  }
+
+  // Adjust the viewport offset to cope with change in size between FS
+  // and previous window state.
+  setViewportOffset(scrolloffset);
+}
+
+void DesktopWindow::setDisableWinKeys(bool dwk) {
+  // Enable low-level event hooking, so we get special keys directly
+  if (dwk)
+    enableLowLevelKeyEvents(handle);
+  else
+    disableLowLevelKeyEvents(handle);
+}
+
+
+void DesktopWindow::setMonitor(const char* monitor) {
+  MonitorInfo mi(monitor);
+  mi.moveTo(handle);
+}
+
+char* DesktopWindow::getMonitor() const {
+  MonitorInfo mi(handle);
+  return strDup(mi.szDevice);
+}
+
+
+bool DesktopWindow::setViewportOffset(const Point& tl) {
+  Point np = Point(max(0, min(tl.x, buffer->width()-client_size.width())),
+    max(0, min(tl.y, buffer->height()-client_size.height())));
+  Point delta = np.translate(scrolloffset.negate());
+  if (!np.equals(scrolloffset)) {
+    scrolloffset = np;
+    ScrollWindowEx(frameHandle, -delta.x, -delta.y, 0, 0, 0, 0, SW_INVALIDATE);
+    UpdateWindow(frameHandle);
+    return true;
+  }
+  return false;
+}
+
+
+bool DesktopWindow::processBumpScroll(const Point& pos)
+{
+  if (!bumpScroll) return false;
+  int bumpScrollPixels = 20;
+  bumpScrollDelta = Point();
+
+  if (pos.x == client_size.width()-1)
+    bumpScrollDelta.x = bumpScrollPixels;
+  else if (pos.x == 0)
+    bumpScrollDelta.x = -bumpScrollPixels;
+  if (pos.y == client_size.height()-1)
+    bumpScrollDelta.y = bumpScrollPixels;
+  else if (pos.y == 0)
+    bumpScrollDelta.y = -bumpScrollPixels;
+
+  if (bumpScrollDelta.x || bumpScrollDelta.y) {
+    if (bumpScrollTimer.isActive()) return true;
+    if (setViewportOffset(scrolloffset.translate(bumpScrollDelta))) {
+      bumpScrollTimer.start(25);
+      return true;
+    }
+  }
+
+  bumpScrollTimer.stop();
+  return false;
+}
+
+
+LRESULT
+DesktopWindow::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  switch (msg) {
+
+    // -=- Process standard window messages
+
+  case WM_NOTIFY:
+    if (wParam == ID_TOOLBAR)
+      tb.processWM_NOTIFY(wParam, lParam);
+    break;
+
+  case WM_DISPLAYCHANGE:
+    // Display format has changed - notify callback
+    callback->displayChanged();
+    break;
+
+    // -=- Window position
+
+    // Prevent the window from being resized to be too large if in normal mode.
+    // If maximized or fullscreen the allow oversized windows.
+
+  case WM_WINDOWPOSCHANGING:
+    {
+      WINDOWPOS* wpos = (WINDOWPOS*)lParam;
+      if (wpos->flags & SWP_NOSIZE)
+        break;
+
+      // Work out how big the window should ideally be
+      DWORD current_style = GetWindowLong(frameHandle, GWL_STYLE);
+      DWORD style = current_style & ~(WS_VSCROLL | WS_HSCROLL);
+      DWORD style_ex = GetWindowLong(frameHandle, GWL_EXSTYLE);
+
+      RECT r;
+      SetRect(&r, 0, 0, buffer->width(), buffer->height());
+      AdjustWindowRectEx(&r, style, FALSE, style_ex);
+      Rect reqd_size = Rect(r.left, r.top, r.right, r.bottom);
+      if (current_style & WS_VSCROLL)
+        reqd_size.br.x += GetSystemMetrics(SM_CXVSCROLL);
+      if (current_style & WS_HSCROLL)
+        reqd_size.br.y += GetSystemMetrics(SM_CXHSCROLL);
+
+      SetRect(&r, reqd_size.tl.x, reqd_size.br.x, reqd_size.tl.y, reqd_size.br.y);
+      if (tb.isVisible())
+        r.bottom += tb.getHeight();
+      AdjustWindowRect(&r, GetWindowLong(handle, GWL_STYLE), FALSE);
+      reqd_size = Rect(r.left, r.top, r.right, r.bottom);
+
+      RECT current;
+      GetWindowRect(handle, &current);
+
+      if (!(GetWindowLong(handle, GWL_STYLE) & WS_MAXIMIZE) && !fullscreenActive) {
+        // Ensure that the window isn't resized too large
+        if (wpos->cx > reqd_size.width()) {
+          wpos->cx = reqd_size.width();
+          wpos->x = current.left;
+        }
+        if (wpos->cy > reqd_size.height()) {
+          wpos->cy = reqd_size.height();
+          wpos->y = current.top;
+        }
+      }
+    }
+    break;
+
+    // Resize child windows and update window size info we have cached.
+
+  case WM_SIZE:
+    {
+      Point old_offset = desktopToClient(Point(0, 0));
+      RECT r;
+
+      // Resize child windows
+      GetClientRect(getHandle(), &r);
+      if (tb.isVisible()) {
+        MoveWindow(getFrameHandle(), 0, tb.getHeight(),
+                   r.right, r.bottom - tb.getHeight(), TRUE);
+      } else {
+        MoveWindow(getFrameHandle(), 0, 0, r.right, r.bottom, TRUE);
+      }
+      tb.autoSize();
+ 
+      // Update the cached sizing information
+      GetWindowRect(frameHandle, &r);
+      window_size = Rect(r.left, r.top, r.right, r.bottom);
+      GetClientRect(frameHandle, &r);
+      client_size = Rect(r.left, r.top, r.right, r.bottom);
+
+      // Determine whether scrollbars are required
+      calculateScrollBars();
+
+      // Redraw if required
+      if ((!old_offset.equals(desktopToClient(Point(0, 0)))))
+        InvalidateRect(frameHandle, 0, TRUE);
+    }
+    break;
+
+    // -=- Bump-scrolling
+
+  case WM_TIMER:
+    switch (wParam) {
+    case TIMER_BUMPSCROLL:
+      if (!setViewportOffset(scrolloffset.translate(bumpScrollDelta)))
+        bumpScrollTimer.stop();
+      break;
+    case TIMER_POINTER_INTERVAL:
+    case TIMER_POINTER_3BUTTON:
+      ptr.handleTimer(callback, wParam);
+      break;
+    }
+    break;
+
+    // -=- Track whether or not the window has focus
+
+  case WM_SETFOCUS:
+    has_focus = true;
+    break;
+  case WM_KILLFOCUS:
+    has_focus = false;
+    cursorOutsideBuffer();
+    // Restore the keyboard to a consistent state
+    kbd.releaseAllKeys(callback);
+    break;
+
+    // -=- Handle the extra window menu items
+
+    // Pass system menu messages to the callback and only attempt
+    // to process them ourselves if the callback returns false.
+  case WM_SYSCOMMAND:
+    // Call the supplied callback
+    if (callback->sysCommand(wParam, lParam))
+      break;
+
+    // - Not processed by the callback, so process it as a system message
+    switch (wParam & 0xfff0) {
+
+      // When restored, ensure that full-screen mode is re-enabled if required.
+    case SC_RESTORE:
+      {
+      if (GetWindowLong(handle, GWL_STYLE) & WS_MINIMIZE) {
+        rfb::win32::SafeDefWindowProc(handle, msg, wParam, lParam);
+        setFullscreen(fullscreenRestore);
+      }
+      else if (fullscreenActive)
+        setFullscreen(false);
+      else
+        rfb::win32::SafeDefWindowProc(handle, msg, wParam, lParam);
+
+      return 0;
+      }
+
+      // If we are maximized or minimized then that cancels full-screen mode.
+    case SC_MINIMIZE:
+    case SC_MAXIMIZE:
+      fullscreenRestore = fullscreenActive;
+      setFullscreen(false);
+      break;
+
+      // If the menu is about to be shown, make sure it's up to date
+    case SC_KEYMENU:
+    case SC_MOUSEMENU:
+      callback->refreshMenu(true);
+      break;
+
+    };
+    break;
+
+    // Treat all menu commands as system menu commands
+  case WM_COMMAND:
+    SendMessage(handle, WM_SYSCOMMAND, wParam, lParam);
+    return 0;
+
+    // -=- Handle keyboard input
+
+  case WM_KEYUP:
+  case WM_KEYDOWN:
+    // Hook the MenuKey to pop-up the window menu
+    if (menuKey && (wParam == menuKey)) {
+
+      bool ctrlDown = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0;
+      bool altDown = (GetAsyncKeyState(VK_MENU) & 0x8000) != 0;
+      bool shiftDown = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0;
+      if (!(ctrlDown || altDown || shiftDown)) {
+
+        // If MenuKey is being released then pop-up the menu
+        if ((msg == WM_KEYDOWN)) {
+          // Make sure it's up to date
+          callback->refreshMenu(false);
+
+          // Show it under the pointer
+          POINT pt;
+          GetCursorPos(&pt);
+          cursorInBuffer = false;
+          TrackPopupMenu(GetSystemMenu(handle, FALSE),
+            TPM_CENTERALIGN | TPM_VCENTERALIGN, pt.x, pt.y, 0, handle, 0);
+        }
+
+        // Ignore the MenuKey keypress for both press & release events
+        return 0;
+      }
+    }
+	case WM_SYSKEYDOWN:
+	case WM_SYSKEYUP:
+    kbd.keyEvent(callback, wParam, lParam, (msg == WM_KEYDOWN) || (msg == WM_SYSKEYDOWN));
+    return 0;
+
+    // -=- Handle the window closing
+
+  case WM_CLOSE:
+    vlog.debug("WM_CLOSE %x", handle);
+    callback->closeWindow();
+    break;
+
+  }
+
+  return rfb::win32::SafeDefWindowProc(handle, msg, wParam, lParam);
+}
+
+LRESULT
+DesktopWindow::processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+  switch (msg) {
+
+    // -=- Paint the remote frame buffer
+
+  case WM_PAINT:
+    {
+      PAINTSTRUCT ps;
+      HDC paintDC = BeginPaint(frameHandle, &ps);
+      if (!paintDC)
+        throw rdr::SystemException("unable to BeginPaint", GetLastError());
+      Rect pr = Rect(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
+
+      if (!pr.is_empty()) {
+
+        // Draw using the correct palette
+        PaletteSelector pSel(paintDC, windowPalette.getHandle());
+
+        if (buffer->bitmap) {
+          // Update the bitmap's palette
+          if (palette_changed) {
+            palette_changed = false;
+            buffer->refreshPalette();
+          }
+
+          // Get device context
+          BitmapDC bitmapDC(paintDC, buffer->bitmap);
+
+          // Blit the border if required
+          Rect bufpos = desktopToClient(buffer->getRect());
+          if (!pr.enclosed_by(bufpos)) {
+            vlog.debug("draw border");
+            HBRUSH black = (HBRUSH) GetStockObject(BLACK_BRUSH);
+            RECT r;
+            SetRect(&r, 0, 0, bufpos.tl.x, client_size.height()); FillRect(paintDC, &r, black);
+            SetRect(&r, bufpos.tl.x, 0, bufpos.br.x, bufpos.tl.y); FillRect(paintDC, &r, black);
+            SetRect(&r, bufpos.br.x, 0, client_size.width(), client_size.height()); FillRect(paintDC, &r, black);
+            SetRect(&r, bufpos.tl.x, bufpos.br.y, bufpos.br.x, client_size.height()); FillRect(paintDC, &r, black);
+          }
+
+          // Do the blit
+          Point buf_pos = clientToDesktop(pr.tl);
+
+          if (!BitBlt(paintDC, pr.tl.x, pr.tl.y, pr.width(), pr.height(),
+                      bitmapDC, buf_pos.x, buf_pos.y, SRCCOPY))
+            throw rdr::SystemException("unable to BitBlt to window", GetLastError());
+        }
+      }
+
+      EndPaint(frameHandle, &ps);
+
+      // - Notify the callback that a paint message has finished processing
+      callback->paintCompleted();
+    }
+    return 0;
+
+    // -=- Palette management
+
+  case WM_PALETTECHANGED:
+    vlog.debug("WM_PALETTECHANGED");
+    if ((HWND)wParam == frameHandle) {
+      vlog.debug("ignoring");
+      break;
+    }
+  case WM_QUERYNEWPALETTE:
+    vlog.debug("re-selecting palette");
+    {
+      WindowDC wdc(frameHandle);
+      PaletteSelector pSel(wdc, windowPalette.getHandle());
+      if (pSel.isRedrawRequired()) {
+        InvalidateRect(frameHandle, 0, FALSE);
+        UpdateWindow(frameHandle);
+      }
+    }
+    return TRUE;
+
+  case WM_VSCROLL:
+  case WM_HSCROLL: 
+    {
+      Point delta;
+      int newpos = (msg == WM_VSCROLL) ? scrolloffset.y : scrolloffset.x;
+
+      switch (LOWORD(wParam)) {
+      case SB_PAGEUP: newpos -= 50; break;
+      case SB_PAGEDOWN: newpos += 50; break;
+      case SB_LINEUP: newpos -= 5; break;
+      case SB_LINEDOWN: newpos += 5; break;
+      case SB_THUMBTRACK:
+      case SB_THUMBPOSITION: newpos = HIWORD(wParam); break;
+      default: vlog.info("received unknown scroll message");
+      };
+
+      if (msg == WM_HSCROLL)
+        setViewportOffset(Point(newpos, scrolloffset.y));
+      else
+        setViewportOffset(Point(scrolloffset.x, newpos));
+  
+      SCROLLINFO si;
+      si.cbSize = sizeof(si); 
+      si.fMask  = SIF_POS; 
+      si.nPos   = newpos; 
+      SetScrollInfo(frameHandle, (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ, &si, TRUE); 
+    }
+    break;
+
+    // -=- Cursor shape/visibility handling
+
+  case WM_SETCURSOR:
+    if (LOWORD(lParam) != HTCLIENT)
+      break;
+    SetCursor(cursorInBuffer ? dotCursor : arrowCursor);
+    return TRUE;
+
+  case WM_MOUSELEAVE:
+    trackingMouseLeave = false;
+    cursorOutsideBuffer();
+    return 0;
+
+    // -=- Mouse input handling
+
+  case WM_MOUSEMOVE:
+  case WM_LBUTTONUP:
+  case WM_MBUTTONUP:
+  case WM_RBUTTONUP:
+  case WM_LBUTTONDOWN:
+  case WM_MBUTTONDOWN:
+  case WM_RBUTTONDOWN:
+#ifdef WM_MOUSEWHEEL
+  case WM_MOUSEWHEEL:
+#endif
+    if (has_focus)
+    {
+      if (!trackingMouseLeave) {
+        TRACKMOUSEEVENT tme;
+        tme.cbSize = sizeof(TRACKMOUSEEVENT);
+        tme.dwFlags = TME_LEAVE;
+        tme.hwndTrack = frameHandle;
+        _TrackMouseEvent(&tme);
+        trackingMouseLeave = true;
+      }
+      int mask = 0;
+      if (LOWORD(wParam) & MK_LBUTTON) mask |= 1;
+      if (LOWORD(wParam) & MK_MBUTTON) mask |= 2;
+      if (LOWORD(wParam) & MK_RBUTTON) mask |= 4;
+
+#ifdef WM_MOUSEWHEEL
+      if (msg == WM_MOUSEWHEEL) {
+        int delta = (short)HIWORD(wParam);
+        int repeats = (abs(delta)+119) / 120;
+        int wheelMask = (delta > 0) ? 8 : 16;
+        vlog.debug("repeats %d, mask %d\n",repeats,wheelMask);
+        for (int i=0; i<repeats; i++) {
+          ptr.pointerEvent(callback, oldpos, mask | wheelMask);
+          ptr.pointerEvent(callback, oldpos, mask);
+        }
+      } else {
+#endif
+        Point clientPos = Point(LOWORD(lParam), HIWORD(lParam));
+        Point p = clientToDesktop(clientPos);
+
+        // If the mouse is not within the server buffer area, do nothing
+        cursorInBuffer = buffer->getRect().contains(p);
+        if (!cursorInBuffer) {
+          cursorOutsideBuffer();
+          break;
+        }
+
+        // If we're locally rendering the cursor then redraw it
+        if (cursorAvailable) {
+          // - Render the cursor!
+          if (!p.equals(cursorPos)) {
+            hideLocalCursor();
+            cursorPos = p;
+            showLocalCursor();
+            if (cursorVisible)
+              hideSystemCursor();
+          }
+        }
+
+        // If we are doing bump-scrolling then try that first...
+        if (processBumpScroll(clientPos))
+          break;
+
+        // Send a pointer event to the server
+        ptr.pointerEvent(callback, p, mask);
+        oldpos = p;
+#ifdef WM_MOUSEWHEEL
+      }
+#endif
+    } else {
+      cursorOutsideBuffer();
+    }
+    break;
+  }
+
+  return rfb::win32::SafeDefWindowProc(frameHandle, msg, wParam, lParam);
+}
+
+
+void
+DesktopWindow::hideLocalCursor() {
+  // - Blit the cursor backing store over the cursor
+  // *** ALWAYS call this BEFORE changing buffer PF!!!
+  if (cursorVisible) {
+    cursorVisible = false;
+    buffer->imageRect(cursorBackingRect, cursorBacking.data);
+    invalidateDesktopRect(cursorBackingRect);
+  }
+}
+
+void
+DesktopWindow::showLocalCursor() {
+  if (cursorAvailable && !cursorVisible && cursorInBuffer) {
+    if (!buffer->getPF().equal(cursor.getPF()) ||
+      cursor.getRect().is_empty()) {
+      vlog.info("attempting to render invalid local cursor");
+      cursorAvailable = false;
+      showSystemCursor();
+      return;
+    }
+    cursorVisible = true;
+    
+    cursorBackingRect = cursor.getRect().translate(cursorPos).translate(cursor.hotspot.negate());
+    cursorBackingRect = cursorBackingRect.intersect(buffer->getRect());
+    buffer->getImage(cursorBacking.data, cursorBackingRect);
+
+    renderLocalCursor();
+
+    invalidateDesktopRect(cursorBackingRect);
+  }
+}
+
+void DesktopWindow::cursorOutsideBuffer()
+{
+  cursorInBuffer = false;
+  hideLocalCursor();
+  showSystemCursor();
+}
+
+void
+DesktopWindow::renderLocalCursor()
+{
+  Rect r = cursor.getRect();
+  r = r.translate(cursorPos).translate(cursor.hotspot.negate());
+  buffer->maskRect(r, cursor.data, cursor.mask.buf);
+}
+
+void
+DesktopWindow::hideSystemCursor() {
+  if (systemCursorVisible) {
+    vlog.debug("hide system cursor");
+    systemCursorVisible = false;
+    ShowCursor(FALSE);
+  }
+}
+
+void
+DesktopWindow::showSystemCursor() {
+  if (!systemCursorVisible) {
+    vlog.debug("show system cursor");
+    systemCursorVisible = true;
+    ShowCursor(TRUE);
+  }
+}
+
+
+bool
+DesktopWindow::invalidateDesktopRect(const Rect& crect) {
+  Rect rect = desktopToClient(crect);
+  if (rect.intersect(client_size).is_empty()) return false;
+  RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
+  InvalidateRect(frameHandle, &invalid, FALSE);
+  return true;
+}
+
+
+void
+DesktopWindow::notifyClipboardChanged(const char* text, int len) {
+  callback->clientCutText(text, len);
+}
+
+
+void
+DesktopWindow::setPF(const PixelFormat& pf) {
+  // If the cursor is the wrong format then clear it
+  if (!pf.equal(buffer->getPF()))
+    setCursor(0, 0, Point(), 0, 0);
+
+  // Update the desktop buffer
+  buffer->setPF(pf);
+  
+  // Redraw the window
+  InvalidateRect(handle, 0, 0);
+}
+
+void
+DesktopWindow::setSize(int w, int h) {
+  vlog.debug("setSize %dx%d", w, h);
+
+  // If the locally-rendered cursor is visible then remove it
+  hideLocalCursor();
+
+  // Resize the backing buffer
+  buffer->setSize(w, h);
+
+  // If the window is not maximised or full-screen then resize it
+  if (!(GetWindowLong(handle, GWL_STYLE) & WS_MAXIMIZE) && !fullscreenActive) {
+    // Resize the window to the required size
+    RECT r = {0, 0, w, h};
+    AdjustWindowRectEx(&r, GetWindowLong(frameHandle, GWL_STYLE), FALSE,
+                       GetWindowLong(frameHandle, GWL_EXSTYLE));
+    if (tb.isVisible())
+      r.bottom += tb.getHeight();
+    AdjustWindowRect(&r, GetWindowLong(handle, GWL_STYLE), FALSE);
+
+    // Resize about the center of the window, and clip to current monitor
+    MonitorInfo mi(handle);
+    resizeWindow(handle, r.right-r.left, r.bottom-r.top);
+    mi.clipTo(handle);
+  } else {
+    // Ensure the screen contents are consistent
+    InvalidateRect(frameHandle, 0, FALSE);
+  }
+
+  // Enable/disable scrollbars as appropriate
+  calculateScrollBars();
+}
+
+void
+DesktopWindow::setCursor(int w, int h, const Point& hotspot, void* data, void* mask) {
+  hideLocalCursor();
+
+  cursor.hotspot = hotspot;
+
+  cursor.setSize(w, h);
+  cursor.setPF(buffer->getPF());
+  cursor.imageRect(cursor.getRect(), data);
+  memcpy(cursor.mask.buf, mask, cursor.maskLen());
+  cursor.crop();
+
+  cursorBacking.setSize(w, h);
+  cursorBacking.setPF(buffer->getPF());
+
+  cursorAvailable = true;
+
+  showLocalCursor();
+}
+
+PixelFormat
+DesktopWindow::getNativePF() const {
+  vlog.debug("getNativePF()");
+  return WindowDC(handle).getPF();
+}
+
+
+void
+DesktopWindow::refreshWindowPalette(int start, int count) {
+  vlog.debug("refreshWindowPalette(%d, %d)", start, count);
+
+  Colour colours[256];
+  if (count > 256) {
+    vlog.debug("%d palette entries", count);
+    throw rdr::Exception("too many palette entries");
+  }
+
+  // Copy the palette from the DIBSectionBuffer
+  ColourMap* cm = buffer->getColourMap();
+  if (!cm) return;
+  for (int i=0; i<count; i++) {
+    int r, g, b;
+    cm->lookup(i, &r, &g, &b);
+    colours[i].r = r;
+    colours[i].g = g;
+    colours[i].b = b;
+  }
+
+  // Set the window palette
+  windowPalette.setEntries(start, count, colours);
+
+  // Cause the window to be redrawn
+  palette_changed = true;
+  InvalidateRect(handle, 0, FALSE);
+}
+
+
+void DesktopWindow::calculateScrollBars() {
+  // Calculate the required size of window
+  DWORD current_style = GetWindowLong(frameHandle, GWL_STYLE);
+  DWORD style = current_style & ~(WS_VSCROLL | WS_HSCROLL);
+  DWORD style_ex = GetWindowLong(frameHandle, GWL_EXSTYLE);
+  DWORD old_style;
+  RECT r;
+  SetRect(&r, 0, 0, buffer->width(), buffer->height());
+  AdjustWindowRectEx(&r, style, FALSE, style_ex);
+  Rect reqd_size = Rect(r.left, r.top, r.right, r.bottom);
+
+  if (!bumpScroll) {
+    // We only enable scrollbars if bump-scrolling is not active.
+    // Effectively, this means if full-screen is not active,
+    // but I think it's better to make these things explicit.
+    
+    // Work out whether scroll bars are required
+    do {
+      old_style = style;
+
+      if (!(style & WS_HSCROLL) && (reqd_size.width() > window_size.width())) {
+        style |= WS_HSCROLL;
+        reqd_size.br.y += GetSystemMetrics(SM_CXHSCROLL);
+      }
+      if (!(style & WS_VSCROLL) && (reqd_size.height() > window_size.height())) {
+        style |= WS_VSCROLL;
+        reqd_size.br.x += GetSystemMetrics(SM_CXVSCROLL);
+      }
+    } while (style != old_style);
+  }
+
+  // Tell Windows to update the window style & cached settings
+  if (style != current_style) {
+    SetWindowLong(frameHandle, GWL_STYLE, style);
+    SetWindowPos(frameHandle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+  }
+
+  // Update the scroll settings
+  SCROLLINFO si;
+  if (style & WS_VSCROLL) {
+    si.cbSize = sizeof(si); 
+    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
+    si.nMin   = 0; 
+    si.nMax   = buffer->height(); 
+    si.nPage  = buffer->height() - (reqd_size.height() - window_size.height()); 
+    maxscrolloffset.y = max(0, si.nMax-si.nPage);
+    scrolloffset.y = min(maxscrolloffset.y, scrolloffset.y);
+    si.nPos   = scrolloffset.y;
+    SetScrollInfo(frameHandle, SB_VERT, &si, TRUE);
+  }
+  if (style & WS_HSCROLL) {
+    si.cbSize = sizeof(si); 
+    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
+    si.nMin   = 0;
+    si.nMax   = buffer->width(); 
+    si.nPage  = buffer->width() - (reqd_size.width() - window_size.width()); 
+    maxscrolloffset.x = max(0, si.nMax-si.nPage);
+    scrolloffset.x = min(maxscrolloffset.x, scrolloffset.x);
+    si.nPos   = scrolloffset.x;
+    SetScrollInfo(frameHandle, SB_HORZ, &si, TRUE);
+  }
+
+  // Update the cached client size
+  GetClientRect(frameHandle, &r);
+  client_size = Rect(r.left, r.top, r.right, r.bottom);
+}
+
+
+void
+DesktopWindow::setName(const char* name) {
+  SetWindowText(handle, TStr(name));
+}
+
+
+void
+DesktopWindow::serverCutText(const char* str, int len) {
+  CharArray t(len+1);
+  memcpy(t.buf, str, len);
+  t.buf[len] = 0;
+  clipboard.setClipText(t.buf);
+}
+
+
+void DesktopWindow::fillRect(const Rect& r, Pixel pix) {
+  if (cursorBackingRect.overlaps(r)) hideLocalCursor();
+  buffer->fillRect(r, pix);
+  invalidateDesktopRect(r);
+}
+void DesktopWindow::imageRect(const Rect& r, void* pixels) {
+  if (cursorBackingRect.overlaps(r)) hideLocalCursor();
+  buffer->imageRect(r, pixels);
+  invalidateDesktopRect(r);
+}
+void DesktopWindow::copyRect(const Rect& r, int srcX, int srcY) {
+  if (cursorBackingRect.overlaps(r) ||
+      cursorBackingRect.overlaps(Rect(srcX, srcY, srcX+r.width(), srcY+r.height())))
+    hideLocalCursor();
+  buffer->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY));
+  invalidateDesktopRect(r);
+}
+
+void DesktopWindow::invertRect(const Rect& r) {
+  int stride;
+  rdr::U8* p = buffer->getPixelsRW(r, &stride);
+  for (int y = 0; y < r.height(); y++) {
+    for (int x = 0; x < r.width(); x++) {
+      switch (buffer->getPF().bpp) {
+      case 8:  ((rdr::U8* )p)[x+y*stride] ^= 0xff;       break;
+      case 16: ((rdr::U16*)p)[x+y*stride] ^= 0xffff;     break;
+      case 32: ((rdr::U32*)p)[x+y*stride] ^= 0xffffffff; break;
+      }
+    }
+  }
+  invalidateDesktopRect(r);
+}
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
new file mode 100644
index 0000000..dd1bcdc
--- /dev/null
+++ b/vncviewer/DesktopWindow.h
@@ -0,0 +1,254 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- DesktopWindow.h
+
+// Each VNC connection instance (CConn) creates a DesktopWindow the
+// server initialisation message has been received.  The CConn is
+// responsible for all RFB-specific and network issues.  The
+// DesktopWindow is responsible for all GUI management issues.
+//
+// DesktopWindow provides a FullFramePixelBuffer interface for the
+// CConn to render updates into.  It also requires a callback object
+// to be supplied, which will be notified when various events occur.
+
+#ifndef __RFB_WIN32_DESKTOP_WINDOW_H__
+#define __RFB_WIN32_DESKTOP_WINDOW_H__
+
+#include <rfb/Cursor.h>
+#include <rfb_win32/CKeyboard.h>
+#include <rfb_win32/CPointer.h>
+#include <rfb_win32/Clipboard.h>
+#include <rfb_win32/DIBSectionBuffer.h>
+#include <rfb_win32/LogicalPalette.h>
+#include <vncviewer/ViewerToolBar.h>
+
+
+namespace rfb {
+
+  namespace win32 {
+
+    class DesktopWindow : rfb::win32::Clipboard::Notifier {
+    public:
+      class Callback;
+
+      DesktopWindow(Callback* cb_);
+      ~DesktopWindow();
+
+      // - Window message handling procedure
+      LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+      // - Window message handling procedure for the framebuffer window
+      LRESULT processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam);
+
+      // - Determine the native pixel format of the window
+      //   This can (and often will) differ from the PixelBuffer format
+      PixelFormat getNativePF() const;
+
+      // - Get the underlying window handle
+      //   This is used by F8Menu to modify the window's menu
+      HWND getHandle() const {return handle;}
+
+      // - Get the framebuffer window handle
+      HWND getFrameHandle() const {return frameHandle;}
+
+      // - Set the window title
+      void setName(const char* name);
+
+      // - Set the key that causes the system/F8 menu to be displayed
+      void setMenuKey(rdr::U8 key) { menuKey = key; }
+
+      // - Pointer event handling
+      void setEmulate3(bool em3) { ptr.enableEmulate3(em3); }
+      void setPointerEventInterval(int interval) { ptr.enableInterval(interval); }
+
+      // - Set the pixel format, size etc of the underlying PixelBuffer
+      void setPF(const PixelFormat& pf);
+      PixelFormat getPF() const { return buffer->getPF(); }
+      void setSize(int w, int h);
+      void setColour(int i, int r, int g, int b) {buffer->setColour(i, r, g, b);}
+
+      // - Set the cursor to render when the pointer is within the desktop buffer
+      void setCursor(int w, int h, const Point& hotspot, void* data, void* mask);
+      void showCursor() { showLocalCursor(); }
+
+      // - Set whether to show the toolbar
+      // FIXME: Actually show/hide the toolbar.
+      void setShowToolbar(bool st) { showToolbar = st; }
+
+      // - Set the window fullscreen / determine whether it is fullscreen
+      void setFullscreen(bool fs);
+      bool isFullscreen() { return fullscreenActive; }
+
+      // - Set whether to disable special Windows keys & pass them straight to server
+      void setDisableWinKeys(bool dwk);
+
+      // - Set/get which monitor the window should be displayed on
+      void setMonitor(const char* monitor);
+      char* getMonitor() const;
+
+      // - Set the local clipboard
+      void serverCutText(const char* str, int len);
+
+      // - Draw into the desktop buffer & update the window
+      void fillRect(const Rect& r, Pixel pix);
+      void imageRect(const Rect& r, void* pixels);
+      void copyRect(const Rect& r, int srcX, int srcY);
+
+      void invertRect(const Rect& r);
+
+      // - Update the window palette if the display is palette-based.
+      //   Colours are pulled from the desktop buffer's ColourMap.
+      //   Only the specified range of indexes is dealt with.
+      //   After the update, the entire window is redrawn.
+      void refreshWindowPalette(int start, int count);
+
+      // Clipboard::Notifier interface
+      void notifyClipboardChanged(const char* text, int len);
+
+      // DesktopWindow Callback interface
+      class Callback : public InputHandler {
+      public:
+        virtual ~Callback() {}
+        virtual void displayChanged() = 0;
+        virtual void paintCompleted() = 0;
+        virtual bool sysCommand(WPARAM wParam, LPARAM lParam) = 0;
+        virtual void closeWindow() = 0;
+        virtual void refreshMenu(bool enableSysItems) = 0;
+      };
+
+      // Currently accessible so that the CConn can releaseAllKeys & check
+      // whether Ctrl and Alt are down...
+      rfb::win32::CKeyboard kbd;
+
+    protected:
+      // Routines to convert between Desktop and client (window) coordinates
+      Point desktopToClient(const Point& p) {
+        Point pos = p;
+        if (client_size.width() > buffer->width())
+          pos.x += (client_size.width() - buffer->width()) / 2;
+        else if (client_size.width() < buffer->width())
+          pos.x -= scrolloffset.x;
+        if (client_size.height() > buffer->height())
+          pos.y += (client_size.height() - buffer->height()) / 2;
+        else if (client_size.height() < buffer->height())
+          pos.y -= scrolloffset.y;
+        return pos;
+      }
+      Rect desktopToClient(const Rect& r) {
+        return Rect(desktopToClient(r.tl), desktopToClient(r.br));
+      }
+      Point clientToDesktop(const Point& p) {
+        Point pos = p;
+        if (client_size.width() > buffer->width())
+          pos.x -= (client_size.width() - buffer->width()) / 2;
+        else if (client_size.width() < buffer->width())
+          pos.x += scrolloffset.x;
+        if (client_size.height() > buffer->height())
+          pos.y -= (client_size.height() - buffer->height()) / 2;
+        else if (client_size.height() < buffer->height())
+          pos.y += scrolloffset.y;
+        return pos;
+      }
+      Rect clientToDesktop(const Rect& r) {
+        return Rect(clientToDesktop(r.tl), clientToDesktop(r.br));
+      }
+
+      // Internal routine used by the scrollbars & bump scroller to select
+      // the portion of the Desktop to display
+      bool setViewportOffset(const Point& tl);
+    
+      // Bump scroll handling.  Bump scrolling is used if the window is
+      // in fullscreen mode and the Desktop is larger than the window
+      bool processBumpScroll(const Point& cursorPos);
+      void setBumpScroll(bool on);
+      bool bumpScroll;
+      Point bumpScrollDelta;
+      IntervalTimer bumpScrollTimer;
+
+      // Locally-rendered VNC cursor
+      void hideLocalCursor();
+      void showLocalCursor();
+      void renderLocalCursor();
+
+      // The system-rendered cursor
+      void hideSystemCursor();
+      void showSystemCursor();
+
+      // cursorOutsideBuffer() is called whenever we detect that the mouse has
+      // moved outside the desktop.  It restores the system arrow cursor.
+      void cursorOutsideBuffer();
+
+      // Returns true if part of the supplied rect is visible, false otherwise
+      bool invalidateDesktopRect(const Rect& crect);
+
+      // Determine whether or not we need to enable/disable scrollbars and set the
+      // window style accordingly
+      void calculateScrollBars();
+
+      // Win32-specific input handling
+      rfb::win32::CPointer ptr;
+      Point oldpos;
+      rfb::win32::Clipboard clipboard;
+
+      // Palette handling
+      LogicalPalette windowPalette;
+      bool palette_changed;
+
+      // - Full-screen mode
+      RECT fullscreenOldRect;
+      DWORD fullscreenOldFlags;
+      bool fullscreenActive;
+      bool fullscreenRestore;
+
+      // Cursor handling
+      Cursor cursor;
+      bool systemCursorVisible;  // Should system-cursor be drawn?
+      bool trackingMouseLeave;
+      bool cursorInBuffer;    // Is cursor position within server buffer? (ONLY for LocalCursor)
+      bool cursorVisible;     // Is cursor currently rendered?
+      bool cursorAvailable;   // Is cursor available for rendering?
+      Point cursorPos;
+      ManagedPixelBuffer cursorBacking;
+      Rect cursorBackingRect;
+
+      // ToolBar handling
+      ViewerToolBar tb;
+      bool showToolbar;
+
+      // Local window state
+      win32::DIBSectionBuffer* buffer;
+      bool has_focus;
+      Rect window_size;
+      Rect client_size;
+      Point scrolloffset;
+      Point maxscrolloffset;
+      HWND handle;
+      HWND frameHandle;
+      rdr::U8 menuKey;
+
+      Callback* callback;
+    };
+
+  };
+
+};
+
+#endif // __RFB_WIN32_DESKTOP_WINDOW_H__
+
+
diff --git a/vncviewer/InfoDialog.cxx b/vncviewer/InfoDialog.cxx
index 0d2313a..e74896d 100644
--- a/vncviewer/InfoDialog.cxx
+++ b/vncviewer/InfoDialog.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -17,7 +17,7 @@
  */
 #include <vncviewer/InfoDialog.h>
 #include <vncviewer/resource.h>
-#include <vncviewer/CView.h>
+#include <vncviewer/CConn.h>
 #include <rfb/secTypes.h>
 #include <rfb/encodings.h>
 #include <rfb/CSecurity.h>
@@ -29,37 +29,37 @@
 static LogWriter vlog("Info");
 
 
-bool InfoDialog::showDialog(CView* vw) {
-  view = vw;
+bool InfoDialog::showDialog(CConn* cc) {
+  conn = cc;
   return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONNECTION_INFO));
 }
 
 void InfoDialog::initDialog() {
   char buf[256];
 
-  setItemString(IDC_INFO_NAME, TStr(view->cp.name()));
+  setItemString(IDC_INFO_NAME, TStr(conn->cp.name()));
 
-  setItemString(IDC_INFO_HOST, TCharArray(view->sock->getPeerAddress()).buf);
+  setItemString(IDC_INFO_HOST, TCharArray(conn->getSocket()->getPeerAddress()).buf);
 
-  Rect bufRect = view->buffer->getRect();
-  sprintf(buf, "%dx%d", bufRect.width(), bufRect.height());
+  sprintf(buf, "%dx%d", conn->cp.width, conn->cp.height);
   setItemString(IDC_INFO_SIZE, TStr(buf));
 
-  view->cp.pf().print(buf, 256);
+  conn->cp.pf().print(buf, 256);
   setItemString(IDC_INFO_PF, TStr(buf));
 
-  view->serverDefaultPF.print(buf, 256);
+  conn->getServerDefaultPF().print(buf, 256);
   setItemString(IDC_INFO_DEF_PF, TStr(buf));
 
-  setItemString(IDC_REQUESTED_ENCODING, TStr(encodingName(view->getOptions().preferredEncoding)));
-  setItemString(IDC_LAST_ENCODING, TStr(encodingName(view->lastUsedEncoding())));
+  setItemString(IDC_REQUESTED_ENCODING, TStr(encodingName(conn->getOptions().preferredEncoding)));
+  setItemString(IDC_LAST_ENCODING, TStr(encodingName(conn->lastUsedEncoding())));
 
-  sprintf(buf, "%d kbits/s", view->sock->inStream().kbitsPerSecond());
+  sprintf(buf, "%d kbits/s", conn->getSocket()->inStream().kbitsPerSecond());
   setItemString(IDC_INFO_LINESPEED, TStr(buf));
 
-  sprintf(buf, "%d.%d", view->cp.majorVersion, view->cp.minorVersion);
+  sprintf(buf, "%d.%d", conn->cp.majorVersion, conn->cp.minorVersion);
   setItemString(IDC_INFO_VERSION, TStr(buf));
 
-  int secType = view->getCurrentCSecurity()->getType();
-  setItemString(IDC_INFO_SECURITY, TStr(secTypeName(secType)));
+  const CSecurity* cSec = conn->getCurrentCSecurity();
+  setItemString(IDC_INFO_SECURITY, TStr(secTypeName(cSec->getType())));
+  setItemString(IDC_INFO_ENCRYPTION, TStr(cSec->description()));
 }
diff --git a/vncviewer/InfoDialog.h b/vncviewer/InfoDialog.h
index 7a64d38..752d53c 100644
--- a/vncviewer/InfoDialog.h
+++ b/vncviewer/InfoDialog.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -30,15 +30,15 @@
 
   namespace win32 {
 
-    class CView;
+    class CConn;
 
     class InfoDialog : Dialog {
     public:
-      InfoDialog() : Dialog(GetModuleHandle(0)), view(0) {}
-      virtual bool showDialog(CView* vw);
+      InfoDialog() : Dialog(GetModuleHandle(0)), conn(0) {}
+      virtual bool showDialog(CConn* vw);
       virtual void initDialog();
     protected:
-      CView* view;
+      CConn* conn;
     };
 
   };
diff --git a/vncviewer/ListenServer.h b/vncviewer/ListenServer.h
new file mode 100644
index 0000000..4d1590c
--- /dev/null
+++ b/vncviewer/ListenServer.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- ListenServer.h
+
+#ifndef __RFB_WIN32_LISTEN_SERVER_H__
+#define __RFB_WIN32_LISTEN_SERVER_H__
+
+#include <windows.h>
+#include <winsock2.h>
+#include <network/Socket.h>
+#include <rfb_win32/MsgWindow.h>
+#include <vncviewer/CConnThread.h>
+
+
+namespace rfb {
+  namespace win32 {
+
+    class ListenServer : MsgWindow {
+    public:
+      ListenServer(network::SocketListener* l) : MsgWindow(_T("rfb::win32::ListenServer")), sock(l) {
+        if (WSAAsyncSelect(l->getFd(), getHandle(), WM_USER, FD_ACCEPT) == SOCKET_ERROR)
+          throw rdr::SystemException("unable to monitor listen socket", WSAGetLastError());
+      }
+
+      LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+        if (msg == WM_USER) {
+          network::Socket* newConn = sock->accept();
+          Thread* newThread = new CConnThread(newConn, true);
+          return 0;
+        }
+        return MsgWindow::processMessage(msg, wParam, lParam);
+      }
+    protected:
+      network::SocketListener* sock;
+    };
+
+  };
+};
+
+#endif
\ No newline at end of file
diff --git a/vncviewer/ListenTrayIcon.h b/vncviewer/ListenTrayIcon.h
new file mode 100644
index 0000000..7e334d9
--- /dev/null
+++ b/vncviewer/ListenTrayIcon.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 2002-2005 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.
+ */
+
+// -=- ListenTrayIcon.h
+
+#ifndef __RFB_WIN32_LISTEN_TRAY_ICON_H__
+#define __RFB_WIN32_LISTEN_TRAY_ICON_H__
+
+#include <rfb_win32/TrayIcon.h>
+#include <rfb_win32/AboutDialog.h>
+
+namespace rfb {
+  namespace win32 {
+
+    class ListenTrayIcon : public TrayIcon {
+    public:
+      ListenTrayIcon() {
+        setIcon(IDI_ICON);
+        setToolTip(_T("VNC Viewer"));
+      }
+      virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+        switch(msg) {
+
+        case WM_USER:
+          switch (lParam) {
+          case WM_LBUTTONDBLCLK:
+            SendMessage(getHandle(), WM_COMMAND, ID_NEW_CONNECTION, 0);
+            break;
+          case WM_RBUTTONUP:
+            HMENU menu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_TRAY));
+            HMENU trayMenu = GetSubMenu(menu, 0);
+
+            // First item is New Connection, the default
+            SetMenuDefaultItem(trayMenu, ID_NEW_CONNECTION, FALSE);
+
+            // SetForegroundWindow is required, otherwise Windows ignores the
+            // TrackPopupMenu because the window isn't the foreground one, on
+            // some older Windows versions...
+            SetForegroundWindow(getHandle());
+
+            // Display the menu
+            POINT pos;
+            GetCursorPos(&pos);
+            TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, getHandle(), 0);
+            break;
+			    } 
+			    return 0;
+
+        case WM_COMMAND:
+          switch (LOWORD(wParam)) {
+          case ID_NEW_CONNECTION:
+            {
+              Thread* connThread = new CConnThread();
+              break;
+            }
+          case ID_OPTIONS:
+            OptionsDialog::global.showDialog(0);
+            break;
+          case ID_ABOUT:
+            AboutDialog::instance.showDialog();
+            break;
+          case ID_CLOSE:
+            SendMessage(getHandle(), WM_CLOSE, 0, 0);
+            break;
+          }
+          return 0;
+
+        case WM_CLOSE:
+          PostQuitMessage(0);
+          return 0;
+        }
+
+        return TrayIcon::processMessage(msg, wParam, lParam);
+      }
+    };
+
+  };
+};
+
+#endif // __RFB_WIN32_LISTEN_TRAY_ICON_H__
\ No newline at end of file
diff --git a/vncviewer/MRU.h b/vncviewer/MRU.h
index f065a06..ae703b3 100644
--- a/vncviewer/MRU.h
+++ b/vncviewer/MRU.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -18,13 +18,10 @@
 #ifndef __VIEWER_MRU_H__
 #define __VIEWER_MRU_H__
 
-#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <list>
 #include <set>
-
 #include <rfb_win32/Registry.h>
-
 #include <rfb/util.h>
 #include <rdr/HexOutStream.h>
 
@@ -85,7 +82,7 @@
             TCharArray keyname = rdr::HexOutStream::binToHexStr(&order[i], 1);
             try {
               TCharArray hostname = key.getString(keyname.buf);
-              if (strcmp(name, CStr(hostname.buf)) == 0) {
+              if (stricmp(name, CStr(hostname.buf)) == 0) {
                 keycode = order[i];
                 found = true;
                 break;
@@ -109,8 +106,6 @@
           orderlen = 0;
         }
 
-        printf("keycode=%d\n", (int)keycode);
-
         orderlen++;
         int i, j=orderlen-1;
         for (i=0; i<orderlen-1; i++) {
@@ -124,8 +119,6 @@
           order[i] = order[i-1];
         order[0] = keycode;
 
-        printf("selected %d\n", (int)keycode);
-
         TCharArray keyname = rdr::HexOutStream::binToHexStr((char*)&keycode, 1);
         key.setString(keyname.buf, TStr(name));
         key.setBinary(_T("Order"), order, orderlen);
diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx
index 0985f5b..93e033a 100644
--- a/vncviewer/OptionsDialog.cxx
+++ b/vncviewer/OptionsDialog.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -16,20 +16,16 @@
  * USA.
  */
 
-#define WIN32_LEAN_AND_MEAN
-#if (_WIN32_WINNT < 0x0400)
-#define _WIN32_WINNT 0x0400
-#endif
-#include <windows.h>
-#include <commdlg.h>
-
 #include <vncviewer/OptionsDialog.h>
-#include <vncviewer/CView.h>
+#include <vncviewer/CConn.h>
 #include <vncviewer/resource.h>
 #include <rfb_win32/Registry.h>
-#include <rfb/LogWriter.h>
+#include <rfb_win32/MsgBox.h>
+#include <rfb_win32/OSVersion.h>
 #include <rfb/encodings.h>
 #include <rfb/CConnection.h>
+#include <commdlg.h>
+#include <rfb/LogWriter.h>
 
 using namespace rfb;
 using namespace rfb::win32;
@@ -38,22 +34,22 @@
 
 
 struct OptionsInfo {
-  CView* view;
-  CViewOptions options;
+  CConn* view;
+  CConnOptions options;
 };
 
 
 OptionsDialog rfb::win32::OptionsDialog::global;
 
 
-class VNCviewerOptions : public PropSheet {
+class ViewerOptions : public PropSheet {
 public:
-  VNCviewerOptions(OptionsInfo& info_, std::list<PropSheetPage*> pages)
+  ViewerOptions(OptionsInfo& info_, std::list<PropSheetPage*> pages)
     : PropSheet(GetModuleHandle(0), 
     info_.view ? _T("VNC Viewer Options") : _T("VNC Viewer Defaults"), pages),
     info(info_), changed(false) {
   }
-  ~VNCviewerOptions() {
+  ~ViewerOptions() {
     if (changed) {
       if (info.view)
         // Apply the settings to the supplied session object
@@ -121,7 +117,7 @@
       dlg->options.preferredEncoding = encodingHextile;
     if (isItemChecked(IDC_ENCODING_RAW))
       dlg->options.preferredEncoding = encodingRaw;
-    ((VNCviewerOptions*)propSheet)->setChanged();
+    ((ViewerOptions*)propSheet)->setChanged();
     return true;
   }
   virtual bool onCommand(int id, int cmd) {
@@ -165,6 +161,7 @@
     enableItem(IDC_PROTOCOL_3_3, (!dlg->view) || (dlg->view->state() != CConnection::RFBSTATE_NORMAL));
     setItemChecked(IDC_PROTOCOL_3_3, dlg->options.protocol3_3);
     setItemChecked(IDC_ACCEPT_BELL, dlg->options.acceptBell);
+    setItemChecked(IDC_AUTO_RECONNECT, dlg->options.autoReconnect);
     setItemChecked(IDC_SHOW_TOOLBAR, dlg->options.showToolbar);
   }
   virtual bool onOk() {
@@ -174,8 +171,9 @@
     dlg->options.useDesktopResize = isItemChecked(IDC_DESKTOP_RESIZE);
     dlg->options.protocol3_3 = isItemChecked(IDC_PROTOCOL_3_3);
     dlg->options.acceptBell = isItemChecked(IDC_ACCEPT_BELL);
+    dlg->options.autoReconnect = isItemChecked(IDC_AUTO_RECONNECT);
     dlg->options.showToolbar = isItemChecked(IDC_SHOW_TOOLBAR);
-    ((VNCviewerOptions*)propSheet)->setChanged();
+    ((ViewerOptions*)propSheet)->setChanged();
     return true;
   }
 protected:
@@ -193,6 +191,8 @@
     setItemChecked(IDC_SEND_SYSKEYS, dlg->options.sendSysKeys);
     setItemChecked(IDC_CLIENT_CUTTEXT, dlg->options.clientCutText);
     setItemChecked(IDC_SERVER_CUTTEXT, dlg->options.serverCutText);
+    setItemChecked(IDC_DISABLE_WINKEYS, dlg->options.disableWinKeys && !osVersion.isPlatformWindows);
+    enableItem(IDC_DISABLE_WINKEYS, !osVersion.isPlatformWindows);
     setItemChecked(IDC_EMULATE3, dlg->options.emulate3);
     setItemChecked(IDC_POINTER_INTERVAL, dlg->options.pointerEventInterval != 0);
 
@@ -216,6 +216,7 @@
     dlg->options.sendSysKeys = isItemChecked(IDC_SEND_SYSKEYS);
     dlg->options.clientCutText = isItemChecked(IDC_CLIENT_CUTTEXT);
     dlg->options.serverCutText = isItemChecked(IDC_SERVER_CUTTEXT);
+    dlg->options.disableWinKeys = isItemChecked(IDC_DISABLE_WINKEYS);
     dlg->options.emulate3 = isItemChecked(IDC_EMULATE3);
     dlg->options.pointerEventInterval = 
       isItemChecked(IDC_POINTER_INTERVAL) ? 200 : 0;
@@ -229,14 +230,13 @@
     else
       dlg->options.setMenuKey(CStr(keyName.buf));
 
-    ((VNCviewerOptions*)propSheet)->setChanged();
+    ((ViewerOptions*)propSheet)->setChanged();
     return true;
   }
 protected:
   OptionsInfo* dlg;
 };
 
-
 class DefaultsPage : public PropSheetPage {
 public:
   DefaultsPage(OptionsInfo* dlg_)
@@ -247,10 +247,9 @@
     enableItem(IDC_SAVE_CONFIG, dlg->options.configFileName.buf);
   }
   virtual bool onCommand(int id, int cmd) {
-    HWND hwnd = dlg->view ? dlg->view->getHandle() : 0;
     switch (id) {
     case IDC_LOAD_DEFAULTS:
-      dlg->options = CViewOptions();
+      dlg->options = CConnOptions();
       break;
     case IDC_SAVE_DEFAULTS:
       propSheet->commitPages();
@@ -262,7 +261,7 @@
     case IDC_SAVE_CONFIG:
       propSheet->commitPages();
       dlg->options.writeToFile(dlg->options.configFileName.buf);
-      MsgBox(hwnd, _T("Options saved successfully"),
+      MsgBox(handle, _T("Options saved successfully"),
              MB_OK | MB_ICONINFORMATION);
       return 0;
     case IDC_SAVE_CONFIG_AS:
@@ -281,7 +280,7 @@
 #else
       ofn.lStructSize = sizeof(ofn);
 #endif
-      ofn.hwndOwner = hwnd;
+      ofn.hwndOwner = handle;
       ofn.lpstrFilter = _T("VNC Connection Options\000*.vnc\000");
       ofn.lpstrFile = newFilename;
       currentDir[0] = 0;
@@ -298,7 +297,7 @@
 
       // Save the Options
       dlg->options.writeToFile(CStr(newFilename));
-      MsgBox(hwnd, _T("Options saved successfully"),
+      MsgBox(handle, _T("Options saved successfully"),
              MB_OK | MB_ICONINFORMATION);
       return 0;
     };
@@ -313,7 +312,7 @@
 OptionsDialog::OptionsDialog() : visible(false) {
 }
 
-bool OptionsDialog::showDialog(CView* view, bool capture) {
+bool OptionsDialog::showDialog(CConn* view, bool capture) {
   if (visible) return false;
   visible = true;
 
@@ -331,8 +330,9 @@
   DefaultsPage defPage(&info); if (view) pages.push_back(&defPage);
 
   // Show the property sheet
-  VNCviewerOptions dialog(info, pages);
-  dialog.showPropSheet(view ? view->getHandle() : 0, false, false, capture);
+  ViewerOptions dialog(info, pages);
+  dialog.showPropSheet(view && view->getWindow() ? view->getWindow()->getHandle() : 0,
+                       false, false, capture);
 
   visible = false;
   return dialog.changed;
diff --git a/vncviewer/OptionsDialog.h b/vncviewer/OptionsDialog.h
index eec9b96..fcddc71 100644
--- a/vncviewer/OptionsDialog.h
+++ b/vncviewer/OptionsDialog.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -23,19 +23,18 @@
 #ifndef __RFB_WIN32_OPTIONS_DIALOG_H__
 #define __RFB_WIN32_OPTIONS_DIALOG_H__
 
-#include <vncviewer/CViewOptions.h>
 #include <rfb_win32/Dialog.h>
 
 namespace rfb {
 
   namespace win32 {
 
-    class CView;
+    class CConn;
 
     class OptionsDialog {
     public:
       OptionsDialog();
-      virtual bool showDialog(CView* cfg, bool capture=false);
+      virtual bool showDialog(CConn* cfg, bool capture=false);
 
       static OptionsDialog global;
     protected:
diff --git a/vncviewer/UserPasswdDialog.cxx b/vncviewer/UserPasswdDialog.cxx
index 8ab4ba4..2eea0ea 100644
--- a/vncviewer/UserPasswdDialog.cxx
+++ b/vncviewer/UserPasswdDialog.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -18,12 +18,14 @@
 
 #include <vncviewer/UserPasswdDialog.h>
 #include <vncviewer/resource.h>
+#include <rfb/Exception.h>
 
 using namespace rfb;
 using namespace rfb::win32;
 
 
-UserPasswdDialog::UserPasswdDialog() : Dialog(GetModuleHandle(0)), showUsername(false) {
+UserPasswdDialog::UserPasswdDialog() : Dialog(GetModuleHandle(0)),
+  showUsername(false), showPassword(false) {
 }
 
 
@@ -36,18 +38,18 @@
 }
 
 void UserPasswdDialog::initDialog() {
-  if (username.buf) {
+  if (username.buf)
     setItemString(IDC_USERNAME, username.buf);
-    tstrFree(username.takeBuf());
-  }
-  if (password.buf) {
+  if (password.buf)
     setItemString(IDC_PASSWORD, password.buf);
-    tstrFree(password.takeBuf());
-  }
   if (!showUsername) {
     setItemString(IDC_USERNAME, _T(""));
     enableItem(IDC_USERNAME, false);
   }
+  if (!showPassword) {
+    setItemString(IDC_PASSWORD, _T(""));
+    enableItem(IDC_PASSWORD, false);
+  }
   if (description.buf) {
     TCharArray title(128);
     GetWindowText(handle, title.buf, 128);
@@ -59,26 +61,25 @@
 }
 
 bool UserPasswdDialog::onOk() {
-	username.buf = getItemString(IDC_USERNAME);
-	password.buf = getItemString(IDC_PASSWORD);
+	username.replaceBuf(getItemString(IDC_USERNAME));
+	password.replaceBuf(getItemString(IDC_PASSWORD));
   return true;
 }
 
 
-bool UserPasswdDialog::getUserPasswd(char** user, char** passwd) {
-  bool result = false;
+void UserPasswdDialog::getUserPasswd(char** user, char** passwd) {
   showUsername = user != 0;
+  showPassword = passwd != 0;
   if (user && *user)
-    username.buf = tstrDup(*user);
+    username.replaceBuf(tstrDup(*user));
   if (passwd && *passwd)
-    password.buf = tstrDup(*passwd);
-  if (showDialog()) {
-    if (user)
-      *user = strDup(username.buf);
+    password.replaceBuf(tstrDup(*passwd));
+
+  if (!showDialog())
+    throw rfb::AuthCancelledException();
+
+  if (user)
+    *user = strDup(username.buf);
+  if (passwd)
     *passwd = strDup(password.buf);
-    result = true;
-  }
-  tstrFree(username.takeBuf());
-  tstrFree(password.takeBuf());
-  return result;
 }
diff --git a/vncviewer/UserPasswdDialog.h b/vncviewer/UserPasswdDialog.h
index 998a49f..bf006f4 100644
--- a/vncviewer/UserPasswdDialog.h
+++ b/vncviewer/UserPasswdDialog.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -19,6 +19,10 @@
 // -=- UserPasswdDialog.h
 
 // Username and password dialog for VNC Viewer 4.0
+// Note that the password and username fields are only freed
+// when the dialog instance is deleted - it is important to
+// ensure that the instance is deleted as early as possible, to
+// avoid the password being retained in memory for too long.
 
 #ifndef __RFB_WIN32_USERPASSWD_DIALOG_H__
 #define __RFB_WIN32_USERPASSWD_DIALOG_H__
@@ -38,12 +42,12 @@
       virtual bool showDialog();
       virtual void initDialog();
       virtual bool onOk();
-      virtual bool getUserPasswd(char** user, char** passwd);
+      virtual void getUserPasswd(char** user, char** passwd);
       void setCSecurity(const CSecurity* cs);
     protected:
       TCharArray username;
-      TCharArray password;
-      bool showUsername;
+      TPlainPasswd password;
+      bool showUsername, showPassword;
       TCharArray description;
     };
 
diff --git a/vncviewer/buildTime.cxx b/vncviewer/buildTime.cxx
index bab2e13..9f37b38 100644
--- a/vncviewer/buildTime.cxx
+++ b/vncviewer/buildTime.cxx
@@ -1 +1,18 @@
-const char* buildTime = "Built on " __DATE__ " at " __TIME__;
\ No newline at end of file
+/* Copyright (C) 2005 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.
+ */
+const char* buildTime = "Built on " __DATE__ " at " __TIME__;
diff --git a/vncviewer/cview.cxx b/vncviewer/cview.cxx
deleted file mode 100644
index 03c68e2..0000000
--- a/vncviewer/cview.cxx
+++ /dev/null
@@ -1,1742 +0,0 @@
-/* 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.
- */
-#define WIN32_LEAN_AND_MEAN
-#if (_WIN32_WINNT < 0x0400)
-#define _WIN32_WINNT 0x0400
-#endif
-#include <windows.h>
-#include <winsock2.h>
-#include <tchar.h>
-#include <commctrl.h>
-
-#include <network/TcpSocket.h>
-
-#include <vncviewer/CView.h>
-#include <vncviewer/UserPasswdDialog.h>
-#include <vncviewer/resource.h>
-
-#include <rfb/encodings.h>
-#include <rfb/secTypes.h>
-#include <rfb/CSecurityNone.h>
-#include <rfb/CSecurityVncAuth.h>
-#include <rfb/CMsgWriter.h>
-#include <rfb/Configuration.h>
-#include <rfb/LogWriter.h>
-
-#include <rfb_win32/WMShatter.h>
-
-using namespace rfb;
-using namespace rfb::win32;
-using namespace rdr;
-
-// - Statics & consts
-
-static LogWriter vlog("CView");
-
-const int IDM_FULLSCREEN = ID_FULLSCREEN;
-const int IDM_SEND_MENU_KEY = ID_SEND_MENU_KEY;
-const int IDM_SEND_CAD = ID_SEND_CAD;
-const int IDM_SEND_CTLESC = ID_SEND_CTLESC;
-const int IDM_ABOUT = ID_ABOUT;
-const int IDM_OPTIONS = ID_OPTIONS;
-const int IDM_INFO = ID_INFO;
-const int IDM_NEWCONN = ID_NEW_CONNECTION;
-const int IDM_REQUEST_REFRESH = ID_REQUEST_REFRESH;
-const int IDM_CTRL_KEY = ID_CTRL_KEY;
-const int IDM_ALT_KEY = ID_ALT_KEY;
-const int IDM_FILE_TRANSFER = ID_FILE_TRANSFER;
-const int IDM_CONN_SAVE_AS = ID_CONN_SAVE_AS;
-
-const int TIMER_BUMPSCROLL = 1;
-const int TIMER_POINTER_INTERVAL = 2;
-const int TIMER_POINTER_3BUTTON = 3;
-
-const int HOTKEY_ALTTAB = 0;
-
-
-IntParameter debugDelay("DebugDelay","Milliseconds to display inverted "
-                        "pixel data - a debugging feature", 0);
-
-
-//
-// -=- CViewClass
-
-//
-// Window class used as the basis for all CView instances
-//
-
-class CViewClass {
-public:
-  CViewClass();
-  ~CViewClass();
-  ATOM classAtom;
-  HINSTANCE instance;
-};
-
-LRESULT CALLBACK CViewProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) {
-  LRESULT result;
-
-  // *** vlog.debug("CViewMsg %x->(%x, %x, %x)", wnd, msg, wParam, lParam);
-
-  if (msg == WM_CREATE)
-    SetWindowLong(wnd, GWL_USERDATA, (long)((CREATESTRUCT*)lParam)->lpCreateParams);
-  else if (msg == WM_DESTROY)
-    SetWindowLong(wnd, GWL_USERDATA, 0);
-  CView* _this = (CView*) GetWindowLong(wnd, GWL_USERDATA);
-  if (!_this) {
-    vlog.info("null _this in %x, message %u", wnd, msg);
-    return rfb::win32::SafeDefWindowProc(wnd, msg, wParam, lParam);
-  }
-
-  try {
-    result = _this->processMessage(msg, wParam, lParam);
-  } catch (rdr::Exception& e) {
-    vlog.error("untrapped: %s", e.str());
-  }
-
-  return result;
-};
-
-HCURSOR dotCursor = (HCURSOR)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDC_DOT_CURSOR), IMAGE_CURSOR, 0, 0, LR_SHARED);
-HCURSOR arrowCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED); 
-
-CViewClass::CViewClass() : classAtom(0) {
-  WNDCLASS wndClass;
-  wndClass.style = 0;
-  wndClass.lpfnWndProc = CViewProc;
-  wndClass.cbClsExtra = 0;
-  wndClass.cbWndExtra = 0;
-  wndClass.hInstance = instance = GetModuleHandle(0);
-  wndClass.hIcon = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 0, 0, LR_SHARED);
-  if (!wndClass.hIcon)
-    printf("unable to load icon:%ld", GetLastError());
-  wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
-  wndClass.hbrBackground = NULL;
-  wndClass.lpszMenuName = 0;
-  wndClass.lpszClassName = _T("rfb::win32::CViewClass");
-  classAtom = RegisterClass(&wndClass);
-  if (!classAtom) {
-    throw rdr::SystemException("unable to register CView window class", GetLastError());
-  }
-}
-
-CViewClass::~CViewClass() {
-  if (classAtom) {
-    UnregisterClass((const TCHAR*)classAtom, instance);
-  }
-}
-
-CViewClass baseClass;
-
-//
-// -=- FrameClass
-
-//
-// Window class used to display the rfb data
-//
-
-class FrameClass {
-public:
-  FrameClass();
-  ~FrameClass();
-  ATOM classAtom;
-  HINSTANCE instance;
-};
-
-LRESULT CALLBACK FrameProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
-  LRESULT result;
-
-  if (msg == WM_CREATE)
-    SetWindowLong(hwnd, GWL_USERDATA, (long)((CREATESTRUCT*)lParam)->lpCreateParams);
-  else if (msg == WM_DESTROY)
-    SetWindowLong(hwnd, GWL_USERDATA, 0);
-  CView* _this = (CView*) GetWindowLong(hwnd, GWL_USERDATA);
-  if (!_this) {
-    vlog.info("null _this in %x, message %u", hwnd, msg);
-    return DefWindowProc(hwnd, msg, wParam, lParam);
-  }
-
-  try {
-    result = _this->processFrameMessage(msg, wParam, lParam);
-  } catch (rdr::Exception& e) {
-    vlog.error("untrapped: %s", e.str());
-  }
-
-  return result;
-}
-
-FrameClass::FrameClass() : classAtom(0) {
-  WNDCLASS wndClass;
-  wndClass.style = 0;
-  wndClass.lpfnWndProc = FrameProc;
-  wndClass.cbClsExtra = 0;
-  wndClass.cbWndExtra = 0;
-  wndClass.hInstance = instance = GetModuleHandle(0);
-  wndClass.hIcon = 0;
-  wndClass.hCursor = NULL;
-  wndClass.hbrBackground = 0;
-  wndClass.lpszMenuName = 0;
-  wndClass.lpszClassName = _T("FrameClass");
-  classAtom = RegisterClass(&wndClass);
-  if (!classAtom) {
-    throw rdr::SystemException("unable to register frame window class",
-                               GetLastError());
-  }
-}
-
-FrameClass::~FrameClass() {
-  if (classAtom) {
-    UnregisterClass((const TCHAR*)classAtom, instance);
-  }
-}
-
-FrameClass frameClass;
-
-//
-// -=- CView instance implementation
-//
-
-RegKey CView::userConfigKey;
-
-
-CView::CView() 
-  : quit_on_destroy(false), buffer(0), sock(0), readyToRead(false),
-    client_size(0, 0, 16, 16), window_size(0, 0, 32, 32),
-    cursorVisible(false), cursorAvailable(false), cursorInBuffer(false),
-    systemCursorVisible(true), trackingMouseLeave(false),
-    hwnd(0), frameHwnd(0), requestUpdate(false), has_focus(false), 
-    palette_changed(false), sameMachine(false), encodingChange(false), 
-    formatChange(false), lastUsedEncoding_(encodingRaw), fullScreenActive(false),
-    bumpScroll(false), manager(0), toolbar(true) {
-
-  // Create the main window
-  const TCHAR* name = _T("VNC Viewer 4.0b");
-  hwnd = CreateWindow((const TCHAR*)baseClass.classAtom, name, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
-    0, 0, 10, 10, 0, 0, baseClass.instance, this);
-  if (!hwnd) {
-    throw rdr::SystemException("unable to create WMNotifier window instance", GetLastError());
-  }
-  vlog.debug("created window \"%s\" (%x)", (const char*)CStr(name), hwnd);
-
-  // Create the viewer toolbar
-  tb.create(getHandle());
-  vlog.debug("created toolbar window \"%s\" (%x)", "ViewerToolBar", tb.getHandle());
-
-  // Create the frame window
-  frameHwnd = CreateWindowEx(WS_EX_CLIENTEDGE, (const TCHAR*)frameClass.classAtom,
-    0, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
-    CW_USEDEFAULT, CW_USEDEFAULT, getHandle(), 0, frameClass.instance, this);
-  if (!frameHwnd) {
-    throw rdr::SystemException("unable to create rfb frame window instance", GetLastError());
-  }
-  vlog.debug("created window \"%s\" (%x)", "Frame Window", frameHwnd);
-
-  // Initialise the CPointer pointer handler
-  ptr.setHWND(getFrameHandle());
-  ptr.setIntervalTimerId(TIMER_POINTER_INTERVAL);
-  ptr.set3ButtonTimerId(TIMER_POINTER_3BUTTON);
-
-  // Initialise the bumpscroll timer
-  bumpScrollTimer.setHWND(getHandle());
-  bumpScrollTimer.setId(TIMER_BUMPSCROLL);
-
-  // Grab AltTab
-  setAltTabGrab(options.sendSysKeys);
-
-  // Hook the clipboard
-  clipboard.setNotifier(this);
-
-  // Create the backing buffer
-  buffer = new win32::DIBSectionBuffer(getFrameHandle());
-}
-
-CView::~CView() {
-  vlog.debug("~CView");
-  showSystemCursor();
-  if (hwnd) {
-    setVisible(false);
-    DestroyWindow(hwnd);
-    hwnd = 0;
-  }
-  delete buffer;
-  vlog.debug("~CView done");
-}
-
-bool CView::initialise(network::Socket* s) {
-  // Update the window menu
-  HMENU wndmenu = GetSystemMenu(hwnd, FALSE);
-  AppendMenu(wndmenu, MF_SEPARATOR, 0, 0);
-  AppendMenu(wndmenu, MF_STRING, IDM_FULLSCREEN, _T("&Full screen"));
-  AppendMenu(wndmenu, (options.showToolbar ? MF_STRING | MF_CHECKED : MF_STRING), 
-    IDM_SHOW_TOOLBAR, _T("Show tool&bar"));
-  AppendMenu(wndmenu, MF_SEPARATOR, 0, 0);
-  AppendMenu(wndmenu, MF_STRING, IDM_CTRL_KEY, _T("Ctr&l"));
-  AppendMenu(wndmenu, MF_STRING, IDM_ALT_KEY, _T("Al&t"));
-  AppendMenu(wndmenu, MF_STRING, IDM_SEND_CAD, _T("Send Ctrl-Alt-&Del"));
-  AppendMenu(wndmenu, MF_STRING, IDM_SEND_CTLESC, _T("Send Ctrl-&Esc"));
-  AppendMenu(wndmenu, MF_STRING, IDM_REQUEST_REFRESH, _T("Refres&h Screen"));
-  AppendMenu(wndmenu, MF_SEPARATOR, 0, 0);
-  if (manager) AppendMenu(wndmenu, MF_STRING, IDM_NEWCONN, _T("Ne&w Connection..."));
-  AppendMenu(wndmenu, MF_STRING, IDM_OPTIONS, _T("&Options..."));
-  AppendMenu(wndmenu, MF_STRING, IDM_INFO, _T("Connection &Info..."));
-  AppendMenu(wndmenu, MF_STRING, IDM_ABOUT, _T("&About..."));
-
-  // Set the server's name for MRU purposes
-  CharArray endpoint(s->getPeerEndpoint());
-  setServerName(endpoint.buf);
-  if (!options.host.buf)
-    options.setHost(endpoint.buf);
-
-  // Initialise the underlying CConnection
-  setStreams(&s->inStream(), &s->outStream());
-
-  // Enable processing of window messages while blocked on I/O
-  s->inStream().setBlockCallback(this);
-
-  // Initialise the viewer options
-  applyOptions(options);
-
-  // - Set which auth schemes we support
-  addSecType(secTypeNone);
-  addSecType(secTypeVncAuth);
-
-  initialiseProtocol();
-  WSAAsyncSelect(s->getFd(), getHandle(), WM_USER, FD_READ | FD_CLOSE);
-  sock = s;
-
-  m_fileTransfer.initialize(&s->inStream(), &s->outStream());
-
-  // Show toolbar if needed
-  toolbar = options.showToolbar;
-  if (options.showToolbar) tb.show();
-  else tb.hide();
-
-  return true;
-}
-
-
-void
-CView::applyOptions(CViewOptions& opt) {
-  // *** CHANGE THIS TO USE CViewOptions::operator= ***
-
-  // - Take the username, password, config filename, and host spec
-  options.setUserName(opt.userName.buf);
-  options.setPassword(opt.password.buf);
-  options.setHost(opt.host.buf);
-  options.setConfigFileName(opt.configFileName.buf);
-  options.setMonitor(opt.monitor.buf);
-
-  // - Set optional features in ConnParams
-  encodingChange |= ((options.useLocalCursor != opt.useLocalCursor) ||
-    (options.useDesktopResize != opt.useDesktopResize));
-  cp.supportsLocalCursor = options.useLocalCursor = opt.useLocalCursor;
-  cp.supportsDesktopResize = options.useDesktopResize = opt.useDesktopResize;
-
-  encodingChange |= ((options.customCompressLevel != opt.customCompressLevel) ||
-		     (options.compressLevel != opt.compressLevel) ||
-		     (options.noJpeg != opt.noJpeg) ||
-		     (options.qualityLevel != opt.qualityLevel));
-  cp.customCompressLevel = options.customCompressLevel = opt.customCompressLevel;
-  cp.compressLevel = options.compressLevel = opt.compressLevel;
-  cp.noJpeg = options.noJpeg = opt.noJpeg;
-  cp.qualityLevel = options.qualityLevel = opt.qualityLevel;
-
-  if (cursorAvailable)
-    hideLocalCursor();
-  cursorAvailable = cursorAvailable && options.useLocalCursor;
-
-  // - Switch full-screen mode on/off
-  options.fullScreen = opt.fullScreen;
-  setFullscreen(options.fullScreen);
-
-  // - Handle format/encoding options
-  encodingChange |= (options.preferredEncoding != opt.preferredEncoding);
-  options.preferredEncoding = opt.preferredEncoding;
-
-  formatChange |= (options.fullColour != opt.fullColour);
-  options.fullColour = opt.fullColour;
-
-  if (!options.fullColour)
-    formatChange |= (options.lowColourLevel != opt.lowColourLevel);
-  options.lowColourLevel = opt.lowColourLevel;
-
-  options.autoSelect = opt.autoSelect;
-
-  // - Sharing
-  options.shared = opt.shared;
-  setShared(options.shared);
-
-  // - Inputs
-  options.sendPtrEvents = opt.sendPtrEvents;
-  options.sendKeyEvents = opt.sendKeyEvents;
-  options.sendSysKeys = opt.sendSysKeys;
-  setAltTabGrab(options.sendSysKeys);
-  options.clientCutText = opt.clientCutText;
-  options.serverCutText = opt.serverCutText;
-  options.emulate3 = opt.emulate3;
-  ptr.enableEmulate3(opt.emulate3);
-  options.pointerEventInterval = opt.pointerEventInterval;
-  ptr.enableInterval(opt.pointerEventInterval);
-  options.menuKey = opt.menuKey;
-
-  // - Protocol version override
-  options.protocol3_3 = opt.protocol3_3;
-  setProtocol3_3(options.protocol3_3);
-
-  // - Bell
-  options.acceptBell = opt.acceptBell;
-
-  // - Show/hide toolbar
-  options.showToolbar = opt.showToolbar;
-}
-
-void
-CView::setFullscreen(bool fs) {
-  // Set the menu fullscreen option tick
-  CheckMenuItem(GetSystemMenu(getHandle(), FALSE), IDM_FULLSCREEN,
-    (options.fullScreen ? MF_CHECKED : 0) | MF_BYCOMMAND);
-
-  // If the fullscreen mode is active then disable the menu point 
-  // "Show toolbar", otherwise enable the menu point.
-  EnableMenuItem(GetSystemMenu(getHandle(), FALSE), IDM_SHOW_TOOLBAR,
-    (options.fullScreen ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND);
-
-  // If the window is not visible then we ignore the request.
-  // setVisible() will call us to correct the full-screen state when
-  // the window is visible, to keep things consistent.
-  if (!IsWindowVisible(getHandle()))
-    return;
-
-  if (fs && !fullScreenActive) {
-    fullScreenActive = bumpScroll = true;
-
-    // Un-minimize the window if required
-    if (GetWindowLong(getHandle(), GWL_STYLE) & WS_MINIMIZE)
-      ShowWindow(getHandle(), SW_RESTORE);
-
-    // Save the non-fullscreen window position
-    RECT wrect;
-    GetWindowRect(getHandle(), &wrect);
-    fullScreenOldRect = Rect(wrect.left, wrect.top, wrect.right, wrect.bottom);
-
-    // Find the size of the display the window is on
-    MonitorInfo mi(getHandle());
-
-    // Set the window full-screen
-    DWORD flags = GetWindowLong(getHandle(), GWL_STYLE);
-    fullScreenOldFlags = flags;
-    flags = flags & ~(WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZE | WS_MINIMIZE);
-    vlog.debug("flags=%x", flags);
-
-    if (toolbar) tb.hide();
-    SetWindowLong(getFrameHandle(), GWL_EXSTYLE, 0);
-    SetWindowLong(getHandle(), GWL_STYLE, flags);
-    SetWindowPos(getHandle(), HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top,
-      mi.rcMonitor.right-mi.rcMonitor.left,
-      mi.rcMonitor.bottom-mi.rcMonitor.top,
-      SWP_FRAMECHANGED);
-  } else if (!fs && fullScreenActive) {
-    fullScreenActive = bumpScroll = false;
-
-    // Set the window non-fullscreen
-    if (toolbar) tb.show();
-    SetWindowLong(getFrameHandle(), GWL_EXSTYLE, WS_EX_CLIENTEDGE);
-    SetWindowLong(getHandle(), GWL_STYLE, fullScreenOldFlags);
-    SetWindowPos(getHandle(), HWND_NOTOPMOST,
-      fullScreenOldRect.tl.x, fullScreenOldRect.tl.y,
-      fullScreenOldRect.width(), fullScreenOldRect.height(),
-      SWP_FRAMECHANGED);
-  }
-
-  // Adjust the viewport offset to cope with change in size between FS
-  // and previous window state.
-  setViewportOffset(scrolloffset);
-}
-
-
-bool CView::setViewportOffset(const Point& tl) {
-/* ***
-  Point np = Point(max(0, min(maxscrolloffset.x, tl.x)),
-    max(0, min(maxscrolloffset.y, tl.y)));
-    */
-  Point np = Point(max(0, min(tl.x, buffer->width()-client_size.width())),
-    max(0, min(tl.y, buffer->height()-client_size.height())));
-  Point delta = np.translate(scrolloffset.negate());
-  if (!np.equals(scrolloffset)) {
-    scrolloffset = np;
-    ScrollWindowEx(getFrameHandle(), -delta.x, -delta.y, 0, 0, 0, 0, SW_INVALIDATE);
-    UpdateWindow(getFrameHandle());
-    return true;
-  }
-  return false;
-}
-
-
-bool CView::processBumpScroll(const Point& pos)
-{
-  if (!bumpScroll) return false;
-  int bumpScrollPixels = 20;
-  bumpScrollDelta = Point();
-
-  if (pos.x == client_size.width()-1)
-    bumpScrollDelta.x = bumpScrollPixels;
-  else if (pos.x == 0)
-    bumpScrollDelta.x = -bumpScrollPixels;
-  if (pos.y == client_size.height()-1)
-    bumpScrollDelta.y = bumpScrollPixels;
-  else if (pos.y == 0)
-    bumpScrollDelta.y = -bumpScrollPixels;
-
-  if (bumpScrollDelta.x || bumpScrollDelta.y) {
-    if (bumpScrollTimer.isActive()) return true;
-    if (setViewportOffset(scrolloffset.translate(bumpScrollDelta))) {
-      bumpScrollTimer.start(25);
-      return true;
-    }
-  }
-
-  bumpScrollTimer.stop();
-  return false;
-}
-
-
-LRESULT
-CView::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
-  switch (msg) {
-
-    // -=- Process standard window messages
-
-  case WM_NOTIFY:
-    if (wParam = (ID_TOOLBAR)) tb.processWM_NOTIFY(wParam, lParam);
-    break;
-
-  case WM_DISPLAYCHANGE:
-    // Display has changed - use new pixel format
-    calculateFullColourPF();
-    break;
-
-    // -=- Window position
-
-    // Prevent the window from being resized to be too large if in normal mode.
-    // If maximized or fullscreen the allow oversized windows.
-
-  case WM_WINDOWPOSCHANGING:
-    {
-      WINDOWPOS* wpos = (WINDOWPOS*)lParam;
-      if (wpos->flags &  SWP_NOSIZE)
-        break;
-
-      // Work out how big the window should ideally be
-      DWORD frame_current_style = GetWindowLong(getFrameHandle(), GWL_STYLE);
-      DWORD frame_style = frame_current_style & ~(WS_VSCROLL | WS_HSCROLL);
-      DWORD frame_ex_style = GetWindowLong(getFrameHandle(), GWL_EXSTYLE);
-
-      RECT r;
-      SetRect(&r, 0, 0, buffer->width(), buffer->height());
-      AdjustWindowRectEx(&r, frame_style, FALSE, frame_ex_style);
-      Rect reqd_size = Rect(r.left, r.top, r.right, r.bottom);
-      if (frame_current_style & WS_VSCROLL)
-        reqd_size.br.x += GetSystemMetrics(SM_CXVSCROLL);
-      if (frame_current_style & WS_HSCROLL)
-        reqd_size.br.y += GetSystemMetrics(SM_CXHSCROLL);
-      r.left = reqd_size.tl.x; r.right  = reqd_size.br.x;
-      r.top  = reqd_size.tl.y; r.bottom = reqd_size.br.y;
-      if (tb.isVisible()) r.bottom += tb.getHeight();
-      AdjustWindowRect(&r, GetWindowLong(getHandle(), GWL_STYLE), FALSE);
-      reqd_size = Rect(r.left, r.top, r.right, r.bottom);
-      RECT current;
-      GetWindowRect(getHandle(), &current);
-
-      // Ensure that the window isn't resized too large
-      // If the window is maximized or full-screen then any size is allowed
-      if (!(GetWindowLong(getHandle(), GWL_STYLE) & WS_MAXIMIZE) && !fullScreenActive) {
-        if (wpos->cx > reqd_size.width()) {
-          wpos->cx = reqd_size.width();
-          wpos->x = current.left;
-        }
-        if (wpos->cy > reqd_size.height()) {
-          wpos->cy = reqd_size.height();
-          wpos->y = current.top;
-        }
-      }
-
-    }
-    break;
-
-    // Resize child windows and update window size info we have cached.
-
-  case WM_SIZE:
-    {
-      Point old_offset = bufferToClient(Point(0, 0));
-
-      // Resize the child windows
-      RECT r;
-      GetClientRect(getHandle(), &r);
-      if (tb.isVisible()) {
-        MoveWindow(getFrameHandle(), 0, tb.getHeight(), r.right,
-          r.bottom - tb.getHeight(), TRUE);
-      } else {
-        MoveWindow(getFrameHandle(), 0, 0, r.right, r.bottom, TRUE);
-      }
-      tb.autoSize();
- 
-      // Update the cached sizing information
-      GetWindowRect(getFrameHandle(), &r);
-      window_size = Rect(r.left, r.top, r.right, r.bottom);
-      GetClientRect(getFrameHandle(), &r);
-      client_size = Rect(r.left, r.top, r.right, r.bottom);
-
-      // Determine whether scrollbars are required
-      calculateScrollBars();
-         
-      // Redraw if required
-      if (!old_offset.equals(bufferToClient(Point(0, 0))))
-        InvalidateRect(getFrameHandle(), 0, TRUE);
-    }
-    break;
-
-    // -=- Bump-scrolling
-
-  case WM_TIMER:
-    switch (wParam) {
-    case TIMER_BUMPSCROLL:
-      if (!setViewportOffset(scrolloffset.translate(bumpScrollDelta)))
-        bumpScrollTimer.stop();
-      break;
-    case TIMER_POINTER_INTERVAL:
-    case TIMER_POINTER_3BUTTON:
-      try {
-        ptr.handleTimer(writer(), wParam);
-      } catch (rdr::Exception& e) {
-        close(e.str());
-      }
-      break;
-    }
-    break;
-
-    // -=- Track whether or not the window has focus
-
-  case WM_SETFOCUS:
-    has_focus = true;
-    // Re-register AltTab hotkey
-    setAltTabGrab(options.sendSysKeys);
-    break;
-  case WM_KILLFOCUS:
-    has_focus = false;
-    cursorOutsideBuffer();
-    // Unregister AltTab hotkey
-    setAltTabGrab(false);
-    // Restore the remote keys to consistent states
-    try {
-      kbd.releaseAllKeys(writer());
-    } catch (rdr::Exception& e) {
-      close(e.str());
-    }
-    break;
-
-    // -=- Handle the extra window menu items
-
-    // Process the items added to the system menu
-  case WM_SYSCOMMAND:
-
-    // - First check whether it's one of our messages
-    switch (wParam) {
-    case IDM_FULLSCREEN:
-      options.fullScreen = !options.fullScreen;
-      setFullscreen(options.fullScreen);
-      return 0;
-    case IDM_SHOW_TOOLBAR:
-      toolbar = !toolbar;
-      CheckMenuItem(GetSystemMenu(getHandle(), FALSE), IDM_SHOW_TOOLBAR,
-        (toolbar ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
-      if (toolbar) tb.show();
-      else tb.hide();
-      return 0;
-    case IDM_CTRL_KEY:
-      writeKeyEvent(VK_CONTROL, 0, !kbd.keyPressed(VK_CONTROL));
-      return 0;
-    case IDM_ALT_KEY:
-      writeKeyEvent(VK_MENU, 0, !kbd.keyPressed(VK_MENU));
-      return 0;
-    case IDM_SEND_MENU_KEY:
-      writeKeyEvent(options.menuKey, 0, true);
-      writeKeyEvent(options.menuKey, 0, false);
-      return 0;
-    case IDM_SEND_CAD:
-      writeKeyEvent(VK_CONTROL, 0, true);
-      writeKeyEvent(VK_MENU, 0, true);
-      writeKeyEvent(VK_DELETE, 0, true);
-      writeKeyEvent(VK_DELETE, 0, false);
-      writeKeyEvent(VK_MENU, 0, false);
-      writeKeyEvent(VK_CONTROL, 0, false);
-      return 0;
-    case IDM_SEND_CTLESC:
-      writeKeyEvent(VK_CONTROL, 0, true);
-      writeKeyEvent(VK_ESCAPE, 0, true);
-      writeKeyEvent(VK_CONTROL, 0, false);
-      writeKeyEvent(VK_ESCAPE, 0, false);
-      return 0;
-    case IDM_REQUEST_REFRESH:
-      try {
-        writer()->writeFramebufferUpdateRequest(Rect(0,0,cp.width,cp.height), false);
-        requestUpdate = false;
-      } catch (rdr::Exception& e) {
-        close(e.str());
-      }
-      return 0;
-    case IDM_NEWCONN:
-      manager->addClient(0);
-      return 0;
-    case IDM_OPTIONS:
-      // Update the monitor device name in the CViewOptions instance
-      {
-        MonitorInfo mi(getHandle());
-        options.setMonitor(mi.szDevice);
-        optionsDialog.showDialog(this);
-        return 0;
-      }
-    case IDM_INFO:
-      infoDialog.showDialog(this);
-      return 0;
-    case IDM_ABOUT:
-      AboutDialog::instance.showDialog();
-      return 0;
-    case IDM_FILE_TRANSFER:
-      m_fileTransfer.show(getHandle());
-      return 0;
-    case IDM_CONN_SAVE_AS:
-      return 0;
-    case ID_CLOSE:
-      PostQuitMessage(0);
-      return 0;
-    };
-
-    // - Not one of our messages, so process it as a system message
-    switch (wParam & 0xfff0) {
-
-      // When restored, ensure that full-screen mode is re-enabled if required.
-    case SC_RESTORE:
-      rfb::win32::SafeDefWindowProc(getHandle(), msg, wParam, lParam);
-      setFullscreen(options.fullScreen);
-      return 0;
-
-      // If we are maximized or minimized then that cancels full-screen mode.
-    case SC_MINIMIZE:
-    case SC_MAXIMIZE:
-      setFullscreen(false);
-      break;
-
-      // If the system menu is shown then make sure it's up to date
-    case SC_KEYMENU:
-    case SC_MOUSEMENU:
-      updateF8Menu(false);
-      break;
-
-    };
-    break;
-
-    // Treat all menu commands as system menu commands
-  case WM_COMMAND:
-    SendMessage(getHandle(), WM_SYSCOMMAND, wParam, lParam);
-    return 0;
-
-  case WM_MENUCHAR:
-    vlog.debug("menuchar");
-    break;
-
-    // -=- Handle keyboard input
-
-  case WM_HOTKEY:
-    if (wParam == HOTKEY_ALTTAB) {
-      writeKeyEvent(VK_TAB, 0, true);
-      writeKeyEvent(VK_TAB, 0, false);
-      return 0;
-    }
-    break;
-
-  case WM_SYSKEYDOWN:
-    // Translate Alt-Space and Alt-F4 to WM_SYSCHAR and WM_CLOSE,
-    // since we are not using TranslateMessage(). 
-    if (!options.sendSysKeys) {
-      switch (wParam) {
-      case VK_SPACE:
-	writeKeyEvent(VK_MENU, 0, false);
-	SendMessage(getHandle(), WM_SYSCHAR, wParam, lParam);
-	return 0; 
-      case VK_F4:
-	SendMessage(getHandle(), WM_CLOSE, wParam, lParam);
-	return 0; 
-      }
-    }
-
-  case WM_SYSKEYUP:
-    // When we have registered for AltTab as a hotkey, SYSKEYUPs for
-    // Tabs are sent (but no SYSKEYDOWNs). AltTab is handled by
-    // WM_HOTKEY, though.
-    if (wParam == VK_TAB) return 0; 
-
-  case WM_KEYUP:
-  case WM_KEYDOWN:
-    // Hook the MenuKey to pop-up the window menu
-    if (options.menuKey && (wParam == options.menuKey)) {
-
-      bool ctrlDown = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0;
-      bool altDown = (GetAsyncKeyState(VK_MENU) & 0x8000) != 0;
-      bool shiftDown = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0;
-      if (!(ctrlDown || altDown || shiftDown)) {
-
-        // If MenuKey is being released then pop-up the menu
-        if ((msg == WM_KEYDOWN)) {
-          // Make sure it's up to date
-          updateF8Menu(true);
-
-          // Show it under the pointer
-          POINT pt;
-          GetCursorPos(&pt);
-          cursorInBuffer = false;
-          TrackPopupMenu(GetSystemMenu(getHandle(), FALSE),
-            TPM_CENTERALIGN | TPM_VCENTERALIGN, pt.x, pt.y, 0, getHandle(), 0);
-        }
-
-	// Ignore the MenuKey keypress for both press & release events
-	return 0;
-      }
-    }
-
-    writeKeyEvent(wParam, lParam, (msg == WM_KEYDOWN) || (msg == WM_SYSKEYDOWN));
-    return 0;
-
-    // -=- Handle the window closing
-
-  case WM_CLOSE:
-    vlog.debug("WM_CLOSE %x", getHandle());
-    if (quit_on_destroy) {
-      vlog.debug("posting WM_QUIT");
-      PostQuitMessage(0);
-    } else {
-      vlog.debug("not posting WM_QUIT");
-    }
-    break;
-
-    // -=- Process incoming socket data
-
-  case WM_USER:
-    readyToRead = true;
-    break;
-
-  }
-
-  return rfb::win32::SafeDefWindowProc(getHandle(), msg, wParam, lParam);
-}
-
-LRESULT CView::processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
-  switch (msg) {
-
-    // -=- Palette management
-
-  case WM_PALETTECHANGED:
-    vlog.debug("WM_PALETTECHANGED");
-    if ((HWND)wParam == getFrameHandle()) {
-      vlog.debug("ignoring");
-      break;
-    }
-  case WM_QUERYNEWPALETTE:
-    vlog.debug("re-selecting palette");
-    {
-      WindowDC wdc(getFrameHandle());
-      PaletteSelector pSel(wdc, windowPalette.getHandle());
-      if (pSel.isRedrawRequired()) {
-        InvalidateRect(getFrameHandle(), 0, FALSE);
-        UpdateWindow(getFrameHandle());
-      }
-    }
-    return TRUE;
-
-    // Paint the remote frame buffer
-
-  case WM_PAINT:
-    {
-      PAINTSTRUCT ps;
-      HDC paintDC = BeginPaint(getFrameHandle(), &ps);
-      if (!paintDC)
-        throw SystemException("unable to BeginPaint", GetLastError());
-      Rect pr = Rect(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
-
-      if (!pr.is_empty()) {
-
-        // Draw using the correct palette
-        PaletteSelector pSel(paintDC, windowPalette.getHandle());
-
-        if (buffer->bitmap) {
-          // Update the bitmap's palette
-          if (palette_changed) {
-            palette_changed = false;
-            buffer->refreshPalette();
-          }
-
-          // Get device context
-          BitmapDC bitmapDC(paintDC, buffer->bitmap);
-
-          // Blit the border if required
-          Rect bufpos = bufferToClient(buffer->getRect());
-          if (!pr.enclosed_by(bufpos)) {
-            vlog.debug("draw border");
-            HBRUSH black = (HBRUSH) GetStockObject(BLACK_BRUSH);
-            RECT r;
-            SetRect(&r, 0, 0, bufpos.tl.x, client_size.height()); FillRect(paintDC, &r, black);
-            SetRect(&r, bufpos.tl.x, 0, bufpos.br.x, bufpos.tl.y); FillRect(paintDC, &r, black);
-            SetRect(&r, bufpos.br.x, 0, client_size.width(), client_size.height()); FillRect(paintDC, &r, black);
-            SetRect(&r, bufpos.tl.x, bufpos.br.y, bufpos.br.x, client_size.height()); FillRect(paintDC, &r, black);
-          }
-
-          // Do the blit
-          Point buf_pos = clientToBuffer(pr.tl);
-          if (!BitBlt(paintDC, pr.tl.x, pr.tl.y, pr.width(), pr.height(),
-            bitmapDC, buf_pos.x, buf_pos.y, SRCCOPY))
-            throw SystemException("unable to BitBlt to window", GetLastError());
-
-        } else {
-          // Blit a load of black
-          if (!BitBlt(paintDC, pr.tl.x, pr.tl.y, pr.width(), pr.height(),
-            0, 0, 0, BLACKNESS))
-            throw SystemException("unable to BitBlt to blank window", GetLastError());
-        }
-      }
-
-      EndPaint(getFrameHandle(), &ps);
-
-      // - Request the next update from the server, if required
-      requestNewUpdate();
-    }
-    return 0;
-
-    // Process the frame scroll messages
-
-  case WM_VSCROLL:
-  case WM_HSCROLL: 
-    {
-      Point delta;
-      int newpos = (msg == WM_VSCROLL) ? scrolloffset.y : scrolloffset.x;
-
-      switch (LOWORD(wParam)) {
-      case SB_PAGEUP: newpos -= 50; break;
-      case SB_PAGEDOWN: newpos += 50; break;
-      case SB_LINEUP: newpos -= 5; break;
-      case SB_LINEDOWN: newpos += 5; break;
-      case SB_THUMBTRACK:
-      case SB_THUMBPOSITION: newpos = HIWORD(wParam); break;
-      default: vlog.info("received unknown scroll message");
-      };
-
-      if (msg == WM_HSCROLL)
-        setViewportOffset(Point(newpos, scrolloffset.y));
-      else
-        setViewportOffset(Point(scrolloffset.x, newpos));
-  
-      SCROLLINFO si;
-      si.cbSize = sizeof(si); 
-      si.fMask  = SIF_POS; 
-      si.nPos   = newpos; 
-      SetScrollInfo(getFrameHandle(), (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ, &si, TRUE); 
-    }
-    break;
-
-    // -=- Cursor shape/visibility handling
-
-  case WM_SETCURSOR:
-    if (LOWORD(lParam) != HTCLIENT)
-      break;
-    SetCursor(cursorInBuffer ? dotCursor : arrowCursor);
-    return TRUE;
-
-  case WM_MOUSELEAVE:
-    trackingMouseLeave = false;
-    cursorOutsideBuffer();
-    return 0;
-
-    // -=- Mouse input handling
-
-  case WM_MOUSEMOVE:
-  case WM_LBUTTONUP:
-  case WM_MBUTTONUP:
-  case WM_RBUTTONUP:
-  case WM_LBUTTONDOWN:
-  case WM_MBUTTONDOWN:
-  case WM_RBUTTONDOWN:
-  case WM_MOUSEWHEEL:
-    if (has_focus)
-    {
-      if (!trackingMouseLeave) {
-        TRACKMOUSEEVENT tme;
-        tme.cbSize = sizeof(TRACKMOUSEEVENT);
-        tme.dwFlags = TME_LEAVE;
-        tme.hwndTrack = getFrameHandle();
-        _TrackMouseEvent(&tme);
-        trackingMouseLeave = true;
-      }
-      int mask = 0;
-      if (LOWORD(wParam) & MK_LBUTTON) mask |= 1;
-      if (LOWORD(wParam) & MK_MBUTTON) mask |= 2;
-      if (LOWORD(wParam) & MK_RBUTTON) mask |= 4;
-
-      if (msg == WM_MOUSEWHEEL) {
-        int delta = (short)HIWORD(wParam);
-        int repeats = (abs(delta)+119) / 120;
-        int wheelMask = (delta > 0) ? 8 : 16;
-        vlog.debug("repeats %d, mask %d\n",repeats,wheelMask);
-        for (int i=0; i<repeats; i++) {
-          writePointerEvent(oldpos.x, oldpos.y, mask | wheelMask);
-          writePointerEvent(oldpos.x, oldpos.y, mask);
-        }
-      } else {
-        Point clientPos = Point(LOWORD(lParam), HIWORD(lParam));
-        Point p = clientToBuffer(clientPos);
-
-        // If the mouse is not within the server buffer area, do nothing
-        cursorInBuffer = buffer->getRect().contains(p);
-        if (!cursorInBuffer) {
-          cursorOutsideBuffer();
-          break;
-        }
-
-        // If we're locally rendering the cursor then redraw it
-        if (cursorAvailable) {
-          // - Render the cursor!
-          if (!p.equals(cursorPos)) {
-            hideLocalCursor();
-            cursorPos = p;
-            showLocalCursor();
-            if (cursorVisible)
-              hideSystemCursor();
-          }
-        }
-
-        // If we are doing bump-scrolling then try that first...
-        if (processBumpScroll(clientPos))
-          break;
-
-        // Send a pointer event to the server
-        writePointerEvent(p.x, p.y, mask);
-        oldpos = p;
-      }
-    } else {
-      cursorOutsideBuffer();
-    }
-    break;
-  }
-
-  return rfb::win32::SafeDefWindowProc(getFrameHandle(), msg, wParam, lParam);
-}
-
-void CView::blockCallback() {
-  // - An InStream has blocked on I/O while processing an RFB message
-  //   We re-enable socket event notifications, so we'll know when more
-  //   data is available, then we sit and dispatch window events until
-  //   the notification arrives.
-  readyToRead = false;
-  WSAAsyncSelect(sock->getFd(), getHandle(), WM_USER, FD_READ | FD_CLOSE);
-  MSG msg;
-  while (true) {
-    if (readyToRead) {
-      // - Network event notification.  Return control to I/O routine.
-      WSAAsyncSelect(sock->getFd(), getHandle(), WM_USER, 0);
-      return;
-    }
-
-    DWORD result = GetMessage(&msg, NULL, 0, 0);
-    if (result == 0) {
-      vlog.debug("WM_QUIT");
-      throw QuitMessage(msg.wParam);
-    } else if (result < 0) {
-      throw rdr::SystemException("GetMessage error", GetLastError());
-    }
-
-    // IMPORTANT: We mustn't call TranslateMessage() here, because instead we
-    // call ToAscii() in CKeyboard::keyEvent().  ToAscii() stores dead key
-    // state from one call to the next, which would be messed up by calls to
-    // TranslateMessage() (actually it looks like TranslateMessage() calls
-    // ToAscii() internally).
-    DispatchMessage(&msg);
-  }
-}
-
-
-void
-CView::hideLocalCursor() {
-  // - Blit the cursor backing store over the cursor
-  // *** ALWAYS call this BEFORE changing buffer PF!!!
-  if (cursorVisible) {
-    cursorVisible = false;
-    buffer->imageRect(cursorBackingRect, cursorBacking.data);
-    invalidateBufferRect(cursorBackingRect);
-  }
-}
-
-void
-CView::showLocalCursor() {
-  if (cursorAvailable && !cursorVisible && cursorInBuffer) {
-    if (!cp.pf().equal(cursor.getPF()) ||
-      cursor.getRect().is_empty()) {
-      vlog.info("attempting to render invalid local cursor");
-      cursorAvailable = false;
-      showSystemCursor();
-      return;
-    }
-    cursorVisible = true;
-    
-    cursorBackingRect = cursor.getRect().translate(cursorPos).translate(cursor.hotspot.negate());
-    cursorBackingRect = cursorBackingRect.intersect(buffer->getRect());
-    buffer->getImage(cursorBacking.data, cursorBackingRect);
-
-    renderLocalCursor();
-
-    invalidateBufferRect(cursorBackingRect);
-  }
-}
-
-void CView::cursorOutsideBuffer()
-{
-  cursorInBuffer = false;
-  hideLocalCursor();
-  showSystemCursor();
-}
-
-void
-CView::renderLocalCursor()
-{
-  Rect r = cursor.getRect();
-  r = r.translate(cursorPos).translate(cursor.hotspot.negate());
-  buffer->maskRect(r, cursor.data, cursor.mask.buf);
-}
-
-void
-CView::hideSystemCursor() {
-  if (systemCursorVisible) {
-    vlog.debug("hide system cursor");
-    systemCursorVisible = false;
-    ShowCursor(FALSE);
-  }
-}
-
-void
-CView::showSystemCursor() {
-  if (!systemCursorVisible) {
-    vlog.debug("show system cursor");
-    systemCursorVisible = true;
-    ShowCursor(TRUE);
-  }
-}
-
-void
-CView::setAltTabGrab(bool grab) {
-  BOOL hotKeyResult;
-  static bool grabstate = false;
-
-  // Do not call RegisterHotKey/UnregisterHotKey if not necessary
-  if (grabstate == grab)
-    return;
-
-  grabstate = grab;
-    
-  // Only works for NT/2k/XP
-  if (grab) {
-    hotKeyResult = RegisterHotKey(hwnd, HOTKEY_ALTTAB, MOD_ALT, VK_TAB);
-    if (!hotKeyResult)
-      vlog.debug("RegisterHotkey failed with error %d", GetLastError());
-  } else {
-    hotKeyResult = UnregisterHotKey(hwnd, HOTKEY_ALTTAB);
-  }
-}
-
-bool
-CView::invalidateBufferRect(const Rect& crect) {
-  Rect rect = bufferToClient(crect);
-  if (rect.intersect(client_size).is_empty()) return false;
-  RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
-  InvalidateRect(getFrameHandle(), &invalid, FALSE);
-  return true;
-}
-
-
-void
-CView::notifyClipboardChanged(const char* text, int len) {
-  if (!options.clientCutText) return;
-  if (state() != RFBSTATE_NORMAL) return;
-  try {
-    writer()->writeClientCutText(text, len);
-  } catch (rdr::Exception& e) {
-    close(e.str());
-  }
-}
-
-
-CSecurity* CView::getCSecurity(int secType)
-{
-  switch (secType) {
-  case secTypeNone:
-    return new CSecurityNone();
-  case secTypeVncAuth:
-    return new CSecurityVncAuth(this);
-  default:
-    throw Exception("Unsupported secType?");
-  }
-}
-
-
-void
-CView::setColourMapEntries(int first, int count, U16* rgbs) {
-  vlog.debug("setColourMapEntries: first=%d, count=%d", first, count);
-  int i;
-  for (i=0;i<count;i++) {
-    buffer->setColour(i+first, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]);
-  }
-  // *** change to 0, 256?
-  refreshWindowPalette(first, count);
-  palette_changed = true;
-  InvalidateRect(getHandle(), 0, FALSE);
-}
-
-void
-CView::bell() {
-  if (options.acceptBell)
-    MessageBeep(-1);
-}
-
-
-void
-CView::setDesktopSize(int w, int h) {
-  vlog.debug("setDesktopSize %dx%d", w, h);
-
-  // If the locally-rendered cursor is visible then remove it
-  hideLocalCursor();
-
-  // Resize the backing buffer
-  buffer->setSize(w, h);
-
-  // If the window is not maximised or full-screen then resize it
-  if (!(GetWindowLong(getHandle(), GWL_STYLE) & WS_MAXIMIZE) && !fullScreenActive) {
-    // Resize the window to the required size
-    RECT r = {0, 0, w, h};
-    AdjustWindowRectEx(&r, GetWindowLong(getFrameHandle(), GWL_STYLE), FALSE,
-      GetWindowLong(getFrameHandle(), GWL_EXSTYLE));
-    if (tb.isVisible()) r.bottom += tb.getHeight();
-    AdjustWindowRect(&r, GetWindowLong(getHandle(), GWL_STYLE), FALSE);
-    SetWindowPos(getHandle(), 0, 0, 0, r.right-r.left, r.bottom-r.top,
-      SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
-
-    // Move the window to the desired monitor
-    if (options.monitor.buf)
-      moveToMonitor(getHandle(), options.monitor.buf);
-
-    // Clip to the system work area
-    centerWindow(getHandle(), 0, true);
-  } else {
-    // Ensure the screen contents are consistent
-    InvalidateRect(getFrameHandle(), 0, FALSE);
-  }
-
-  // Tell the underlying CConnection
-  CConnection::setDesktopSize(w, h);
-
-  // Enable/disable scrollbars as appropriate
-  calculateScrollBars();
-}
-
-void
-CView::setCursor(const Point& hotspot, const Point& size, void* data, void* mask) {
-  if (!options.useLocalCursor) return;
-  hideLocalCursor();
-
-  cursor.hotspot = hotspot;
-
-  cursor.setSize(size.x, size.y);
-  cursor.setPF(cp.pf());
-  cursor.imageRect(cursor.getRect(), data);
-  memcpy(cursor.mask.buf, mask, cursor.maskLen());
-  cursor.crop();
-
-  cursorBacking.setSize(size.x, size.y);
-  cursorBacking.setPF(cp.pf());
-
-  cursorAvailable = true;
-
-  showLocalCursor();
-}
-
-PixelFormat
-CView::getNativePF() const {
-  vlog.debug("getNativePF()");
-  return WindowDC(getHandle()).getPF();
-}
-
-void
-CView::setVisible(bool visible) {
-  ShowWindow(getHandle(), visible ? SW_SHOW : SW_HIDE);
-  if (visible) {
-    // When the window becomes visible, make it active
-    SetForegroundWindow(getHandle());
-    SetActiveWindow(getHandle());
-    // If the window should be full-screen, then do so
-    setFullscreen(options.fullScreen);
-  } else {
-    // Disable full-screen mode
-    setFullscreen(false);
-  }
-}
-
-void
-CView::close(const char* reason) {
-  setVisible(false);
-  if (reason) {
-    vlog.info("closing - %s", reason);
-    MsgBox(NULL, TStr(reason), MB_ICONINFORMATION | MB_OK);
-  }
-  SendMessage(getHandle(), WM_CLOSE, 0, 0);
-}
-
-
-void
-CView::framebufferUpdateEnd() {
-  if (debugDelay != 0) {
-    vlog.debug("debug delay %d",(int)debugDelay);
-    UpdateWindow(getHandle());
-    Sleep(debugDelay);
-    std::list<rfb::Rect>::iterator i;
-    for (i = debugRects.begin(); i != debugRects.end(); i++) {
-      invertRect(*i);
-    }
-    debugRects.clear();
-  }
-  if (options.autoSelect)
-    autoSelectFormatAndEncoding();
-
-  // Always request the next update
-  requestUpdate = true;
-
-  // Check that at least part of the window has changed
-  if (!GetUpdateRect(getHandle(), 0, FALSE)) {
-    if (!(GetWindowLong(getHandle(), GWL_STYLE) & WS_MINIMIZE))
-      requestNewUpdate();
-  }
-
-  showLocalCursor();
-}
-
-
-// Note: The method below is duplicated in vncviewer_unix/CConn.cxx!
-
-// autoSelectFormatAndEncoding() chooses the format and encoding appropriate
-// to the connection speed:
-//
-//   Above 16Mbps (timing for at least a second), switch to hextile
-//   Otherwise, switch to ZRLE
-//
-//   Above 256Kbps, use full colour mode
-//
-void 
-CView::autoSelectFormatAndEncoding() {
-  int kbitsPerSecond = sock->inStream().kbitsPerSecond();
-  unsigned int newEncoding = options.preferredEncoding;
-  bool newFullColour = options.fullColour;
-  unsigned int timeWaited = sock->inStream().timeWaited();
-
-  // Select best encoding
-  if (kbitsPerSecond > 16000 && timeWaited >= 10000) {
-    newEncoding = encodingHextile;
-  } else {
-    newEncoding = encodingZRLE;
-  }
-
-  if (newEncoding != options.preferredEncoding) {
-    vlog.info("Throughput %d kbit/s - changing to %s encoding",
-              kbitsPerSecond, encodingName(newEncoding));
-    options.preferredEncoding = newEncoding;
-    encodingChange = true;
-  }
-
-  if (kbitsPerSecond == 0) {
-    return;
-  }
-
-  if (cp.beforeVersion(3, 8)) {
-    // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with
-    // cursors "asynchronously". If this happens in the middle of a
-    // pixel format change, the server will encode the cursor with
-    // the old format, but the client will try to decode it
-    // according to the new format. This will lead to a
-    // crash. Therefore, we do not allow automatic format change for
-    // old servers.
-    return;
-  }
-  
-  // Select best color level
-  newFullColour = (kbitsPerSecond > 256);
-  if (newFullColour != options.fullColour) {
-    vlog.info("Throughput %d kbit/s - full color is now %s", 
-	      kbitsPerSecond,
-	      newFullColour ? "enabled" : "disabled");
-    options.fullColour = newFullColour;
-    formatChange = true;
-  } 
-}
-
-void
-CView::requestNewUpdate() {
-  if (!requestUpdate) return;
-
-  if (formatChange) {
-    // Hide the rendered cursor, if any, to prevent
-    // the backing buffer being used in the wrong format
-    hideLocalCursor();
-
-    // Select the required pixel format
-    if (options.fullColour) {
-      buffer->setPF(fullColourPF);
-    } else {
-      switch (options.lowColourLevel) {
-      case 0:
-        buffer->setPF(PixelFormat(8,3,0,1,1,1,1,2,1,0));
-        break;
-      case 1:
-        buffer->setPF(PixelFormat(8,6,0,1,3,3,3,4,2,0));
-        break;
-      case 2:
-        buffer->setPF(PixelFormat(8,8,0,0,0,0,0,0,0,0));
-        break;
-      }
-    }
-
-    // Print the current pixel format
-    char str[256];
-    buffer->getPF().print(str, 256);
-    vlog.info("Using pixel format %s",str);
-
-    // Save the connection pixel format and tell server to use it
-    cp.setPF(buffer->getPF());
-    writer()->writeSetPixelFormat(cp.pf());
-
-    // Correct the local window's palette
-    if (!getNativePF().trueColour)
-      refreshWindowPalette(0, 1 << cp.pf().depth);
-  }
-
-  if (encodingChange) {
-    vlog.info("Using %s encoding",encodingName(options.preferredEncoding));
-    writer()->writeSetEncodings(options.preferredEncoding, true);
-  }
-
-  writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height),
-                                          !formatChange);
-
-  encodingChange = formatChange = requestUpdate = false;
-}
-
-
-void
-CView::writeKeyEvent(rdr::U8 vkey, rdr::U32 flags, bool down) {
-  if (!options.sendKeyEvents) return;
-  try {
-    kbd.keyEvent(writer(), vkey, flags, down);
-  } catch (rdr::Exception& e) {
-    close(e.str());
-  }
-}
-
-void
-CView::writePointerEvent(int x, int y, int buttonMask) {
-  if (!options.sendPtrEvents) return;
-  try {
-    ptr.pointerEvent(writer(), x, y, buttonMask);
-  } catch (rdr::Exception& e) {
-    close(e.str());
-  }
-}
-
-
-void
-CView::refreshWindowPalette(int start, int count) {
-  vlog.debug("refreshWindowPalette(%d, %d)", start, count);
-
-  Colour colours[256];
-  if (count > 256) {
-    vlog.debug("%d palette entries", count);
-    throw rdr::Exception("too many palette entries");
-  }
-
-  // Copy the palette from the DIBSectionBuffer
-  ColourMap* cm = buffer->getColourMap();
-  if (!cm) return;
-  for (int i=0; i<count; i++) {
-    int r, g, b;
-    cm->lookup(i, &r, &g, &b);
-    colours[i].r = r;
-    colours[i].g = g;
-    colours[i].b = b;
-  }
-
-  // Set the window palette
-  windowPalette.setEntries(start, count, colours);
-
-  // Cause the window to be redrawn
-  InvalidateRect(getHandle(), 0, 0);
-}
-
-
-void CView::calculateScrollBars() {
-  // Calculate the required size of window
-  DWORD current_style = GetWindowLong(getFrameHandle(), GWL_STYLE);
-  DWORD style = current_style & ~(WS_VSCROLL | WS_HSCROLL);
-  DWORD ex_style = GetWindowLong(getFrameHandle(), GWL_EXSTYLE);
-  DWORD old_style;
-  RECT r;
-  SetRect(&r, 0, 0, buffer->width(), buffer->height());
-  AdjustWindowRectEx(&r, style, FALSE, ex_style);
-  Rect reqd_size = Rect(r.left, r.top, r.right, r.bottom);
-
-  if (!bumpScroll) {
-    // We only enable scrollbars if bump-scrolling is not active.
-    // Effectively, this means if full-screen is not active,
-    // but I think it's better to make these things explicit.
-    // Work out whether scroll bars are required
-    do {
-      old_style = style;
-
-      if (!(style & WS_HSCROLL) && (reqd_size.width() > window_size.width())) {
-        style |= WS_HSCROLL;
-        reqd_size.br.y += GetSystemMetrics(SM_CXHSCROLL);
-      }
-      if (!(style & WS_VSCROLL) && (reqd_size.height() > window_size.height())) {
-        style |= WS_VSCROLL;
-        reqd_size.br.x += GetSystemMetrics(SM_CXVSCROLL);
-      }
-    } while (style != old_style);
-  }
-  
-  // Tell Windows to update the window style & cached settings
-  if (style != current_style) {
-    SetWindowLong(getFrameHandle(), GWL_STYLE, style);
-    SetWindowPos(getFrameHandle(), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
-  }
-
-  // Update the scroll settings
-  SCROLLINFO si;
-  if (style & WS_VSCROLL) {
-    si.cbSize = sizeof(si);
-    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
-    si.nMin   = 0;
-    si.nMax   = buffer->height();
-    si.nPage  = buffer->height() - (reqd_size.height() - window_size.height());
-    maxscrolloffset.y = max(0, si.nMax-si.nPage);
-    scrolloffset.y = min(maxscrolloffset.y, scrolloffset.y);
-    si.nPos   = scrolloffset.y;
-    SetScrollInfo(getFrameHandle(), SB_VERT, &si, TRUE);
-  }
-  if (style & WS_HSCROLL) {
-    si.cbSize = sizeof(si);
-    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
-    si.nMin   = 0;
-    si.nMax   = buffer->width();
-    si.nPage  = buffer->width() - (reqd_size.width() - window_size.width());
-    maxscrolloffset.x = max(0, si.nMax-si.nPage);
-    scrolloffset.x = min(maxscrolloffset.x, scrolloffset.x);
-    si.nPos   = scrolloffset.x;
-    SetScrollInfo(getFrameHandle(), SB_HORZ, &si, TRUE);
-  }
-
-  // Update the cached client size
-  GetClientRect(getFrameHandle(), &r);
-  client_size = Rect(r.left, r.top, r.right, r.bottom);
-}
-
-
-void
-CView::calculateFullColourPF() {
-  // If the server is palette based then use palette locally
-  // Also, don't bother doing bgr222
-  if (!serverDefaultPF.trueColour || (serverDefaultPF.depth < 6)) {
-    fullColourPF = serverDefaultPF;
-    options.fullColour = true;
-  } else {
-    // If server is trueColour, use lowest depth PF
-    PixelFormat native = getNativePF();
-    if ((serverDefaultPF.bpp < native.bpp) ||
-      ((serverDefaultPF.bpp == native.bpp) &&
-      (serverDefaultPF.depth < native.depth)))
-      fullColourPF = serverDefaultPF;
-    else
-      fullColourPF = getNativePF();
-  }
-  formatChange = true;
-}
-
-
-void
-CView::updateF8Menu(bool hideSystemCommands) {
-  HMENU menu = GetSystemMenu(getHandle(), FALSE);
-
-  if (hideSystemCommands) {  
-    // Gray out menu items that might cause a World Of Pain
-    HMENU menu = GetSystemMenu(getHandle(), FALSE);
-    EnableMenuItem(menu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
-    EnableMenuItem(menu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
-    EnableMenuItem(menu, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
-    EnableMenuItem(menu, SC_MINIMIZE, MF_BYCOMMAND | MF_ENABLED);
-    EnableMenuItem(menu, SC_MAXIMIZE, MF_BYCOMMAND | MF_ENABLED);
-  }
-
-  // Update the modifier key menu items
-  UINT ctrlCheckFlags = kbd.keyPressed(VK_CONTROL) ? MF_CHECKED : MF_UNCHECKED;
-  UINT altCheckFlags = kbd.keyPressed(VK_MENU) ? MF_CHECKED : MF_UNCHECKED;
-  CheckMenuItem(menu, IDM_CTRL_KEY, MF_BYCOMMAND | ctrlCheckFlags);
-  CheckMenuItem(menu, IDM_ALT_KEY, MF_BYCOMMAND | altCheckFlags);
-
-  // Ensure that the Send <MenuKey> menu item has the correct text
-  if (options.menuKey) {
-    TCharArray menuKeyStr(options.menuKeyName());
-    TCharArray tmp(_tcslen(menuKeyStr.buf) + 6);
-    _stprintf(tmp.buf, _T("Send %s"), menuKeyStr.buf);
-    if (!ModifyMenu(menu, IDM_SEND_MENU_KEY, MF_BYCOMMAND | MF_STRING, IDM_SEND_MENU_KEY, tmp.buf))
-      InsertMenu(menu, IDM_SEND_CAD, MF_BYCOMMAND | MF_STRING, IDM_SEND_MENU_KEY, tmp.buf);
-  } else {
-    RemoveMenu(menu, IDM_SEND_MENU_KEY, MF_BYCOMMAND);
-  }
-}
-
-
-void
-CView::setName(const char* name) {
-  vlog.debug("setName %s", name);
-  ::SetWindowText(getHandle(), TStr(name));
-  CConnection::setName(name);
-}
-
-
-void CView::serverInit() {
-  CConnection::serverInit();
-
-  // If using AutoSelect with old servers, start in FullColor
-  // mode. See comment in autoSelectFormatAndEncoding. 
-  if (cp.beforeVersion(3, 8) && options.autoSelect) {
-    options.fullColour = true;
-  }
-
-  // Save the server's current format
-  serverDefaultPF = cp.pf();
-
-  // Calculate the full-colour format to use
-  calculateFullColourPF();
-
-  // Request the initial update
-  vlog.info("requesting initial update");
-  formatChange = encodingChange = requestUpdate = true;
-  requestNewUpdate();
-
-  // Show the window
-  setVisible(true);
-}
-
-void
-CView::serverCutText(const char* str, int len) {
-  if (!options.serverCutText) return;
-  CharArray t(len+1);
-  memcpy(t.buf, str, len);
-  t.buf[len] = 0;
-  clipboard.setClipText(t.buf);
-}
-
-
-void CView::beginRect(const Rect& r, unsigned int encoding) {
-  sock->inStream().startTiming();
-}
-
-void CView::endRect(const Rect& r, unsigned int encoding) {
-  sock->inStream().stopTiming();
-  lastUsedEncoding_ = encoding;
-  if (debugDelay != 0) {
-    invertRect(r);
-    debugRects.push_back(r);
-  }
-}
-
-void CView::fillRect(const Rect& r, Pixel pix) {
-  if (cursorBackingRect.overlaps(r)) hideLocalCursor();
-  buffer->fillRect(r, pix);
-  invalidateBufferRect(r);
-}
-void CView::imageRect(const Rect& r, void* pixels) {
-  if (cursorBackingRect.overlaps(r)) hideLocalCursor();
-  buffer->imageRect(r, pixels);
-  invalidateBufferRect(r);
-}
-void CView::copyRect(const Rect& r, int srcX, int srcY) {
-  if (cursorBackingRect.overlaps(r) ||
-      cursorBackingRect.overlaps(Rect(srcX, srcY, srcX+r.width(), srcY+r.height())))
-    hideLocalCursor();
-  buffer->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY));
-  invalidateBufferRect(r);
-}
-
-void CView::invertRect(const Rect& r) {
-  int stride;
-  rdr::U8* p = buffer->getPixelsRW(r, &stride);
-  for (int y = 0; y < r.height(); y++) {
-    for (int x = 0; x < r.width(); x++) {
-      switch (buffer->getPF().bpp) {
-      case 8:  ((rdr::U8* )p)[x+y*stride] ^= 0xff;       break;
-      case 16: ((rdr::U16*)p)[x+y*stride] ^= 0xffff;     break;
-      case 32: ((rdr::U32*)p)[x+y*stride] ^= 0xffffffff; break;
-      }
-    }
-  }
-  invalidateBufferRect(r);
-}
-
-bool CView::getUserPasswd(char** user, char** password) {
-  if (!user && options.passwordFile.buf[0]) {
-    FILE* fp = fopen(options.passwordFile.buf, "rb");
-    if (!fp) return false;
-    char data[256];
-    int datalen = fread(data, 1, 256, fp);
-    fclose(fp);
-    if (datalen != 8) return false;
-    vncAuthUnobfuscatePasswd(data);
-    *password = strDup(data);
-    memset(data, 0, strlen(data));
-    return true;
-  }
-
-  if (user && options.userName.buf)
-    *user = strDup(options.userName.buf);
-  if (password && options.password.buf)
-    *password = strDup(options.password.buf);
-  if ((user && !*user) || (password && !*password)) {
-    // Missing username or password - prompt the user
-    UserPasswdDialog userPasswdDialog;
-    userPasswdDialog.setCSecurity(getCurrentCSecurity());
-    if (!userPasswdDialog.getUserPasswd(user, password))
-      return false;
-  }
-  if (user) options.setUserName(*user);
-  if (password) options.setPassword(*password);
-  return true;
-}
-
-bool CView::processFTMsg(int type)
-{
-  return m_fileTransfer.processFTMsg(type);
-}
\ No newline at end of file
diff --git a/vncviewer/cview.h b/vncviewer/cview.h
deleted file mode 100644
index 0dc0066..0000000
--- a/vncviewer/cview.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/* 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.
- */
-
-// -=- CView.h
-
-// An instance of the CView class is created for each VNC Viewer connection.
-
-#ifndef __RFB_WIN32_CVIEW_H__
-#define __RFB_WIN32_CVIEW_H__
-
-#include <network/Socket.h>
-
-#include <rfb/CConnection.h>
-#include <rfb/Cursor.h>
-#include <rfb/UserPasswdGetter.h>
-
-#include <rfb_win32/Clipboard.h>
-#include <rfb_win32/DIBSectionBuffer.h>
-#include <rfb_win32/Win32Util.h>
-#include <rfb_win32/Registry.h>
-#include <rfb_win32/AboutDialog.h>
-#include <rfb_win32/CKeyboard.h>
-#include <rfb_win32/CPointer.h>
-
-#include <vncviewer/InfoDialog.h>
-#include <vncviewer/OptionsDialog.h>
-#include <vncviewer/ViewerToolBar.h>
-#include <vncviewer/CViewOptions.h>
-#include <vncviewer/CViewManager.h>
-#include <vncviewer/FileTransfer.h>
-#include <list>
-
-
-namespace rfb {
-
-  namespace win32 {
-
-    class CView : public CConnection,
-                  public UserPasswdGetter,
-                  rfb::win32::Clipboard::Notifier,
-                  rdr::FdInStreamBlockCallback
-    {
-    public:
-      CView();
-      virtual ~CView();
-
-      bool initialise(network::Socket* s);
-
-      void setManager(CViewManager* m) {manager = m;}
-
-      void applyOptions(CViewOptions& opt);
-      const CViewOptions& getOptions() const {return options;};
-
-      // -=- Window Message handling
-
-      virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);
-      virtual LRESULT processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam);
-
-      // -=- Socket blocking handling
-      //     blockCallback will throw QuitMessage(result) when
-      //     it processes a WM_QUIT message.
-      //     The caller may catch that to cope gracefully with
-      //     a request to quit.
-
-      class QuitMessage : public rdr::Exception {
-      public:
-        QuitMessage(WPARAM wp) : rdr::Exception("QuitMessage") {}
-        WPARAM wParam;
-      };
-      virtual void blockCallback();
-
-      // -=- Window interface
-
-      void postQuitOnDestroy(bool qod) {quit_on_destroy = qod;}
-      PixelFormat getNativePF() const;
-      void setVisible(bool visible);
-      void close(const char* reason=0);
-      HWND getHandle() const {return hwnd;}
-      HWND getFrameHandle() const {return frameHwnd;}
-
-      void notifyClipboardChanged(const char* text, int len);
-
-      // -=- Coordinate conversions
-
-      inline Point bufferToClient(const Point& p) {
-        Point pos = p;
-        if (client_size.width() > buffer->width())
-          pos.x += (client_size.width() - buffer->width()) / 2;
-        else if (client_size.width() < buffer->width())
-          pos.x -= scrolloffset.x;
-        if (client_size.height() > buffer->height())
-          pos.y += (client_size.height() - buffer->height()) / 2;
-        else if (client_size.height() < buffer->height())
-          pos.y -= scrolloffset.y;
-        return pos;
-      }
-      inline Rect bufferToClient(const Rect& r) {
-        return Rect(bufferToClient(r.tl), bufferToClient(r.br));
-      }
-
-      inline Point clientToBuffer(const Point& p) {
-        Point pos = p;
-        if (client_size.width() > buffer->width())
-          pos.x -= (client_size.width() - buffer->width()) / 2;
-        else if (client_size.width() < buffer->width())
-          pos.x += scrolloffset.x;
-        if (client_size.height() > buffer->height())
-          pos.y -= (client_size.height() - buffer->height()) / 2;
-        else if (client_size.height() < buffer->height())
-          pos.y += scrolloffset.y;
-        return pos;
-      }
-      inline Rect clientToBuffer(const Rect& r) {
-        return Rect(clientToBuffer(r.tl), clientToBuffer(r.br));
-      }
-
-      void setFullscreen(bool fs);
-
-      bool setViewportOffset(const Point& tl);
-
-      bool processBumpScroll(const Point& cursorPos);
-      void setBumpScroll(bool on);
-
-      int lastUsedEncoding() const { return lastUsedEncoding_; }
-
-      // -=- CConnection interface overrides
-
-      virtual CSecurity* getCSecurity(int secType);
-
-      virtual void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
-      virtual void bell();
-
-      virtual void framebufferUpdateEnd();
-
-      virtual void setDesktopSize(int w, int h);
-      virtual void setCursor(const Point& hotspot, const Point& size, void* data, void* mask);
-      virtual void setName(const char* name);
-      virtual void serverInit();
-
-      virtual void serverCutText(const char* str, int len);
-
-      virtual void beginRect(const Rect& r, unsigned int encoding);
-      virtual void endRect(const Rect& r, unsigned int encoding);
-
-      virtual void fillRect(const Rect& r, Pixel pix);
-      virtual void imageRect(const Rect& r, void* pixels);
-      virtual void copyRect(const Rect& r, int srcX, int srcY);
-
-      void invertRect(const Rect& r);
-
-      // VNCviewer dialog objects
-
-      OptionsDialog optionsDialog;
-
-      friend class InfoDialog;
-      InfoDialog infoDialog;
-
-      // UserPasswdGetter overrides, used to support a pre-supplied VNC password
-      virtual bool getUserPasswd(char** user, char** password);
-
-      // Global user-config registry key
-      static RegKey userConfigKey;
-
-      bool processFTMsg(int type);
-
-    protected:
-
-      // Locally-rendered VNC cursor
-      void hideLocalCursor();
-      void showLocalCursor();
-      void renderLocalCursor();
-
-      // The system-rendered cursor
-      void hideSystemCursor();
-      void showSystemCursor();
-
-      // Grab AltTab?
-      void setAltTabGrab(bool grab);
-
-      // cursorOutsideBuffer() is called whenever we detect that the mouse has
-      // moved outside the desktop.  It restores the system arrow cursor.
-      void cursorOutsideBuffer();
-
-      // Returns true if part of the supplied rect is visible, false otherwise
-      bool invalidateBufferRect(const Rect& crect);
-
-      // Auto-encoding selector
-      void autoSelectFormatAndEncoding();
-
-      // Request an update with appropriate setPixelFormat and setEncodings calls
-      void requestNewUpdate();
-
-      // Update the window palette if the display is palette-based.
-      // Colours are pulled from the DIBSectionBuffer's ColourMap.
-      // Only the specified range of indexes is dealt with.
-      // After the update, the entire window is redrawn.
-      void refreshWindowPalette(int start, int count);
-
-      // Determine whether or not we need to enable/disable scrollbars and set the
-      // window style accordingly
-      void calculateScrollBars();
-
-      // Recalculate the most suitable full-colour pixel format
-      void calculateFullColourPF();
-
-      // Enable/disable/check/uncheck the F8 menu items as appropriate.
-      void updateF8Menu(bool hideSystemCommands);
-
-      // VNCviewer options
-
-      CViewOptions options;
-
-      // Input handling
-      void writeKeyEvent(rdr::U8 vkey, rdr::U32 flags, bool down);
-      void writePointerEvent(int x, int y, int buttonMask);
-      rfb::win32::CKeyboard kbd;
-      rfb::win32::CPointer ptr;
-      Point oldpos;
-
-      // Clipboard handling
-      rfb::win32::Clipboard clipboard;
-
-      // Pixel format and encoding
-      PixelFormat serverDefaultPF;
-      PixelFormat fullColourPF;
-      bool sameMachine;
-      bool encodingChange;
-      bool formatChange;
-      int lastUsedEncoding_;
-
-      // Networking and RFB protocol
-      network::Socket* sock;
-      bool readyToRead;
-      bool requestUpdate;
-
-      // Palette handling
-      LogicalPalette windowPalette;
-      bool palette_changed;
-
-      // - Full-screen mode
-      Rect fullScreenOldRect;
-      DWORD fullScreenOldFlags;
-      bool fullScreenActive;
-
-      // Bump-scrolling (used in full-screen mode)
-      bool bumpScroll;
-      Point bumpScrollDelta;
-      IntervalTimer bumpScrollTimer;
-
-      // Cursor handling
-      Cursor cursor;
-      bool systemCursorVisible;  // Should system-cursor be drawn?
-      bool trackingMouseLeave;
-      bool cursorInBuffer;    // Is cursor position within server buffer? (ONLY for LocalCursor)
-      bool cursorVisible;     // Is cursor currently rendered?
-      bool cursorAvailable;   // Is cursor available for rendering?
-      Point cursorPos;
-      ManagedPixelBuffer cursorBacking;
-      Rect cursorBackingRect;
-
-      // ** Debugging/logging
-      /*
-      int update_rect_count;
-      int update_pixel_count;
-      Rect update_extent;
-      */
-      std::list<Rect> debugRects;
-
-      // ToolBar handling
-      ViewerToolBar tb;
-      bool toolbar;
-
-      // Local window state
-      win32::DIBSectionBuffer* buffer;
-      bool has_focus;
-      bool quit_on_destroy;
-      Rect window_size;
-      Rect client_size;
-      Point scrolloffset;
-      Point maxscrolloffset;
-      HWND hwnd;
-      HWND frameHwnd;
-
-      // Handle back to CViewManager instance, if any
-      CViewManager* manager;
-
-      FileTransfer m_fileTransfer;
-
-    };
-
-  };
-
-};
-
-#endif
-
-
diff --git a/vncviewer/msvcwarning.h b/vncviewer/msvcwarning.h
deleted file mode 100644
index 53a0678..0000000
--- a/vncviewer/msvcwarning.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* 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 : 4800 ) // forcing bool 'true' or 'false'
-#pragma warning( disable : 4786 ) // debug identifier truncated
diff --git a/vncviewer/resource.h b/vncviewer/resource.h
index 59eee86..b3c7c8c 100644
--- a/vncviewer/resource.h
+++ b/vncviewer/resource.h
@@ -16,8 +16,9 @@
 #define IDR_TRAY                        112
 #define IDD_CONNECTION_INFO             113
 #define IDD_DEFAULTS                    116
-#define IDD_FILETRANSFER_DLG            120
-#define IDB_TOOLBAR                     121
+#define IDB_BITMAP                      120
+#define IDD_FILETRANSFER_DLG            121
+#define IDB_TOOLBAR                     122
 #define IDD_FTDIRNAME_DLG               123
 #define IDD_FTCONFIRM_DLG               124
 #define IDI_FTUP                        125
@@ -77,14 +78,10 @@
 #define IDC_MENU_KEY                    1051
 #define IDC_REQUESTED_ENCODING          1052
 #define IDC_LAST_ENCODING               1053
-#define IDC_ENCODING_TIGHT              1054
-#define IDC_FTLOCALPATH                 1054
-#define IDC_CUSTOM_COMPRESSLEVEL        1055
-#define IDC_FTREMOTEPATH                1055
-#define IDC_COMPRESSLEVEL               1056
-#define IDC_FTREMOTELIST                1056
-#define IDC_ALLOW_JPEG                  1057
-#define IDC_FTLOCALRELOAD               1057
+#define IDC_SECURITY_LEVEL              1054
+#define IDC_INFO_ENCRYPTION             1055
+#define IDC_AUTO_RECONNECT              1056
+#define IDC_DISABLE_WINKEYS             1057
 #define IDC_QUALITYLEVEL                1058
 #define IDC_FTLOCALUP                   1058
 #define IDC_SEND_SYSKEYS                1059
@@ -115,6 +112,15 @@
 #define IDC_FTTEXT                      1084
 #define IDC_FTBROWSEPATH                1085
 #define IDC_FTBROWSETREE                1086
+#define IDC_TYPE                        1088
+#define IDC_ENCODING_TIGHT              1089
+#define IDC_FTLOCALPATH                 1090
+#define IDC_CUSTOM_COMPRESSLEVEL        1091
+#define IDC_FTREMOTEPATH                1092
+#define IDC_COMPRESSLEVEL               1093
+#define IDC_FTREMOTELIST                1094
+#define IDC_ALLOW_JPEG                  1095
+#define IDC_FTLOCALRELOAD               1096
 #define ID_TOOLBAR                      40002
 #define ID_CLOSE                        40003
 #define ID_OPTIONS                      40004
@@ -143,7 +149,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        134
 #define _APS_NEXT_COMMAND_VALUE         40028
-#define _APS_NEXT_CONTROL_VALUE         1087
+#define _APS_NEXT_CONTROL_VALUE         1097
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/vncviewer/vncviewer.bmp b/vncviewer/vncviewer.bmp
new file mode 100644
index 0000000..4ea9c37
--- /dev/null
+++ b/vncviewer/vncviewer.bmp
Binary files differ
diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx
index f0c9f20..3a5214a 100644
--- a/vncviewer/vncviewer.cxx
+++ b/vncviewer/vncviewer.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 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
@@ -25,21 +25,18 @@
 #include <list>
 
 #include <vncviewer/resource.h>
-#include <vncviewer/CViewManager.h>
-#include <vncviewer/CView.h>
+#include <vncviewer/CConn.h>
+#include <vncviewer/CConnThread.h>
 #include <vncviewer/OptionsDialog.h>
-
+#include <vncviewer/ListenServer.h>
+#include <vncviewer/ListenTrayIcon.h>
+#include <network/TcpSocket.h>
 #include <rfb/Logger_stdio.h>
 #include <rfb/Logger_file.h>
 #include <rfb/LogWriter.h>
 #include <rfb/Exception.h>
-
 #include <rfb_win32/RegConfig.h>
-#include <rfb_win32/TrayIcon.h>
-#include <rfb_win32/Win32Util.h>
-#include <rfb_win32/AboutDialog.h>
-
-#include <network/TcpSocket.h>
+#include <rfb_win32/MsgBox.h>
 
 #ifdef _DIALOG_CAPTURE
 #include <extra/LoadBMP.h>
@@ -80,72 +77,6 @@
 
 
 //
-// -=- VNCviewer Tray Icon
-//
-
-class CViewTrayIcon : public TrayIcon {
-public:
-  CViewTrayIcon(CViewManager& mgr) : manager(mgr) {
-    setIcon(IDI_ICON);
-    setToolTip(_T("VNC Viewer"));
-  }
-  virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
-    switch(msg) {
-
-    case WM_USER:
-      switch (lParam) {
-      case WM_LBUTTONDBLCLK:
-        SendMessage(getHandle(), WM_COMMAND, ID_NEW_CONNECTION, 0);
-        break;
-      case WM_RBUTTONUP:
-        HMENU menu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_TRAY));
-        HMENU trayMenu = GetSubMenu(menu, 0);
-
-        // First item is New Connection, the default
-        SetMenuDefaultItem(trayMenu, ID_NEW_CONNECTION, FALSE);
-
-        // SetForegroundWindow is required, otherwise Windows ignores the
-        // TrackPopupMenu because the window isn't the foreground one, on
-        // some older Windows versions...
-        SetForegroundWindow(getHandle());
-
-        // Display the menu
-        POINT pos;
-        GetCursorPos(&pos);
-        TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, getHandle(), 0);
-        break;
-			} 
-			return 0;
-
-    case WM_COMMAND:
-      switch (LOWORD(wParam)) {
-      case ID_NEW_CONNECTION:
-        manager.addClient(0);
-        break;
-      case ID_OPTIONS:
-        OptionsDialog::global.showDialog(0);
-        break;
-      case ID_ABOUT:
-        AboutDialog::instance.showDialog();
-        break;
-      case ID_CLOSE:
-        SendMessage(getHandle(), WM_CLOSE, 0, 0);
-        break;
-      }
-      return 0;
-
-    case WM_CLOSE:
-      PostQuitMessage(0);
-      return 0;
-    }
-
-    return TrayIcon::processMessage(msg, wParam, lParam);
-  }
-protected:
-  CViewManager& manager;
-};
-
-//
 // -=- processParams
 //     Read in the command-line parameters and interpret them.
 //
@@ -166,7 +97,7 @@
   printf("usage: vncviewer <options> <hostname>[:<display>]\n");
   printf("Command-line options:\n");
   printf("  -help                                - Provide usage information.\n");
-  printf("  -config <file>                       - Load connection settings from VNCViewer 3.3 settings file\n");
+  printf("  -config <file>                       - Load connection settings from VNC Viewer 3.3 settings file\n");
   printf("  -console                             - Run with a console window visible.\n");
   printf("  <setting>=<value>                    - Set the named configuration parameter.\n");
   printf("    (Parameter values specified on the command-line override those specified by other configuration methods.)\n");
@@ -176,6 +107,9 @@
   Logger::listLoggers();
   printf("\nParameters:\n");
   Configuration::listParams();
+  printf("Press Enter/Return key to continue\n");
+  char c = getchar();
+  exit(1);
 }
 
 
@@ -224,6 +158,8 @@
           sprintf(tmp.buf, fmt, argv[i]);
           MsgBox(0, TStr(tmp.buf), MB_ICONSTOP | MB_OK);
           exit(1);
+        } else if (strContains(argv[i], '\\')) {
+          configFiles.push_back(strDup(argv[i]));
         } else {
           hosts.push_back(strDup(argv[i]));
         }
@@ -241,7 +177,6 @@
 //
 
 int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, char* cmdLine, int cmdShow) {
-
   try {
 
     // - Initialise the available loggers
@@ -270,7 +205,7 @@
 
 #ifdef _DIALOG_CAPTURE
     if (captureDialogs) {
-      CView::userConfigKey.openKey(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCViewer4"));
+      CConn::userConfigKey.openKey(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCViewer4"));
       OptionsDialog::global.showDialog(0, true);
       return 0;
     }
@@ -285,35 +220,27 @@
     // - Connect to the clients
     if (!configFiles.empty() || !hosts.empty() || acceptIncoming) {
       // - Configure the registry configuration reader
-      win32::RegistryReader reg_reader;
-      reg_reader.setKey(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCViewer4"));
+      win32::RegConfigThread config;
+      config.start(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCViewer4"));
 
       // - Tell the rest of VNC Viewer where to write config data to
-      CView::userConfigKey.openKey(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCViewer4"));
-
-      // - Start the Socket subsystem for TCP
-      TcpSocket::initTcpSockets();
-
-      // Create the client connection manager
-      CViewManager view_manager;
+      CConn::userConfigKey.createKey(HKEY_CURRENT_USER, _T("Software\\TightVNC\\VNCViewer4"));
 
       if (acceptIncoming) {
         int port = 5500;
 
         // Listening viewer
-        if (hosts.size() > 1) {
+        if (hosts.size() > 1)
           programUsage();
-          exit(2);
-        }
-        if (!hosts.empty()) {
+        if (!hosts.empty())
           port = atoi(hosts.front());  
-        }
 
-        vlog.debug("opening listener");
+        // Show the tray icon & menu
+        ListenTrayIcon tray;
 
-        CViewTrayIcon tray(view_manager);
-
-        view_manager.addDefaultTCPListener(port);
+        // Listen for reverse connections
+        network::TcpListener sock(port);
+        ListenServer listener(&sock);
 
         // Run the view manager
         // Also processes the tray icon if necessary
@@ -322,13 +249,11 @@
           TranslateMessage(&msg);
           DispatchMessage(&msg);
         }
-
-        vlog.debug("quitting viewer");
       } else {
         // Read each config file in turn
         while (!configFiles.empty()) {
           char* filename = configFiles.front();
-          view_manager.addClient(filename, true);
+          Thread* connThread = new CConnThread(filename, true);
           strFree(filename);
           configFiles.pop_front();
         }
@@ -336,14 +261,14 @@
         // Connect to each client in turn
         while (!hosts.empty()) {
           char* hostinfo = hosts.front();
-          view_manager.addClient(hostinfo);
+          Thread* connThread = new CConnThread(hostinfo);
           strFree(hostinfo);
           hosts.pop_front();
         }
 
         // Run the view manager
         MSG msg;
-        while (GetMessage(&msg, NULL, 0, 0) > 0) {
+        while (CConnThread::getMessage(&msg, NULL, 0, 0) > 0) {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
         }
diff --git a/vncviewer/vncviewer.dsp b/vncviewer/vncviewer.dsp
index 071b3e4..3c96f00 100644
--- a/vncviewer/vncviewer.dsp
+++ b/vncviewer/vncviewer.dsp
@@ -44,7 +44,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /FI"msvcwarning.h" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /FI"rdr/msvcwarning.h" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "_MBCS" /YX /FD /c
 # ADD BASE RSC /l 0x809 /d "NDEBUG"
 # ADD RSC /l 0x809 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -73,7 +73,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_WINDOWS" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"rdr/msvcwarning.h" /D "_DEBUG" /D "_WINDOWS" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
 # ADD BASE RSC /l 0x809 /d "_DEBUG"
 # ADD RSC /l 0x809 /d "_DEBUG"
 BSC32=bscmake.exe
@@ -103,7 +103,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_WINDOWS" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_WINDOWS" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"rdr/msvcwarning.h" /D "_WINDOWS" /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
@@ -134,19 +134,27 @@
 # End Source File
 # Begin Source File
 
+SOURCE=.\CConn.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CConnOptions.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CConnThread.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConnectingDialog.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\ConnectionDialog.cxx
 # End Source File
 # Begin Source File
 
-SOURCE=.\cview.cxx
-# End Source File
-# Begin Source File
-
-SOURCE=.\CViewManager.cxx
-# End Source File
-# Begin Source File
-
-SOURCE=.\CViewOptions.cxx
+SOURCE=.\DesktopWindow.cxx
 # End Source File
 # Begin Source File
 
@@ -206,6 +214,18 @@
 # PROP Default_Filter "h;hpp;hxx;hm;inl"
 # Begin Source File
 
+SOURCE=.\CConn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CConnOptions.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CConnThread.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\ConnectingDialog.h
 # End Source File
 # Begin Source File
@@ -214,15 +234,7 @@
 # End Source File
 # Begin Source File
 
-SOURCE=.\cview.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\CViewManager.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\CViewOptions.h
+SOURCE=.\DesktopWindow.h
 # End Source File
 # Begin Source File
 
@@ -258,6 +270,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE=.\ListenServer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ListenTrayIcon.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\MRU.h
 # End Source File
 # Begin Source File
@@ -302,6 +322,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=.\vncviewer.bmp
+# End Source File
+# Begin Source File
+
 SOURCE=.\vncviewer.exe.manifest
 # End Source File
 # Begin Source File
