diff --git a/vncviewer/CMakeLists.txt b/vncviewer/CMakeLists.txt
index e1bda9d..4315710 100644
--- a/vncviewer/CMakeLists.txt
+++ b/vncviewer/CMakeLists.txt
@@ -5,6 +5,7 @@
   CConn.cxx
   DesktopWindow.cxx
   UserDialog.cxx
+  Viewport.cxx
   parameters.cxx
   keysym2ucs.c
   vncviewer.cxx)
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 189b521..deae16e 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -21,35 +21,13 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <FL/fl_draw.H>
-
-#include <rfb/CMsgWriter.h>
 #include <rfb/LogWriter.h>
 
-// FLTK can pull in the X11 headers on some systems
-#ifndef XK_VoidSymbol
-#define XK_MISCELLANY
-#define XK_XKB_KEYS
-#include <rfb/keysymdef.h>
-#endif
-
 #include "DesktopWindow.h"
-#include "CConn.h"
 #include "i18n.h"
-#include "parameters.h"
-#include "keysym2ucs.h"
-
-// FLTK STR #2599 must be fixed for proper dead keys support
-#ifndef HAVE_FLTK_DEAD_KEYS
-#define event_compose_symbol event_text
-#endif
 
 using namespace rfb;
 
-#ifdef __APPLE__
-extern "C" const char *osx_event_string(void);
-#endif
-
 extern void exit_vncviewer();
 
 static rfb::LogWriter vlog("DesktopWindow");
@@ -57,56 +35,34 @@
 DesktopWindow::DesktopWindow(int w, int h, const char *name,
                              const rfb::PixelFormat& serverPF,
                              CConn* cc_)
-  : Fl_Window(w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
-    lastPointerPos(0, 0), lastButtonMask(0)
+  : Fl_Window(w, h)
 {
+  viewport = new Viewport(w, h, serverPF, cc_);
+
   callback(handleClose, this);
 
   setName(name);
 
-  frameBuffer = new ManagedPixelBuffer(getPreferredPF(), w, h);
-  assert(frameBuffer);
-
-  setServerPF(serverPF);
-
   show();
 }
 
 
 DesktopWindow::~DesktopWindow()
 {
-  // Unregister all timeouts in case they get a change tro trigger
-  // again later when this object is already gone.
-  Fl::remove_timeout(handleUpdateTimeout, this);
-  Fl::remove_timeout(handleColourMap, this);
-  Fl::remove_timeout(handlePointerTimeout, this);
-
-  delete frameBuffer;
-
-  if (pixelTrans)
-    delete pixelTrans;
+  // FLTK automatically deletes all child widgets, so we shouldn't touch
+  // them ourselves here
 }
 
 
 void DesktopWindow::setServerPF(const rfb::PixelFormat& pf)
 {
-  if (pixelTrans)
-    delete pixelTrans;
-  pixelTrans = NULL;
-
-  if (pf.equal(getPreferredPF()))
-    return;
-
-  pixelTrans = new PixelTransformer();
-  pixelTrans->init(pf, &colourMap, getPreferredPF());
+  viewport->setServerPF(pf);
 }
 
 
 const rfb::PixelFormat &DesktopWindow::getPreferredPF()
 {
-  static PixelFormat prefPF(32, 24, false, true, 255, 255, 255, 0, 8, 16);
-
-  return prefPF;
+  return viewport->getPreferredPF();
 }
 
 
@@ -128,18 +84,11 @@
   copy_label(windowNameStr.buf);
 }
 
-// setColourMapEntries() changes some of the entries in the colourmap.
-// Unfortunately these messages are often sent one at a time, so we delay the
-// settings taking effect by 100ms.  This is because recalculating the internal
-// translation table can be expensive.
+
 void DesktopWindow::setColourMapEntries(int firstColour, int nColours,
                                         rdr::U16* rgbs)
 {
-  for (int i = 0; i < nColours; i++)
-    colourMap.set(firstColour+i, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]);
-
-  if (!Fl::has_timeout(handleColourMap, this))
-    Fl::add_timeout(0.100, handleColourMap, this);
+  viewport->setColourMapEntries(firstColour, nColours, rgbs);
 }
 
 
@@ -148,370 +97,11 @@
 
 void DesktopWindow::updateWindow()
 {
-  Rect r;
-
-  Fl::remove_timeout(handleUpdateTimeout, this);
-
-  r = damage.get_bounding_rect();
-  Fl_Window::damage(FL_DAMAGE_USER1, r.tl.x, r.tl.y, r.width(), r.height());
-
-  damage.clear();
+  viewport->updateWindow();
 }
 
 
-void DesktopWindow::draw()
-{
-  int X, Y, W, H;
-
-  int pixel_bytes, stride_bytes;
-  const uchar *buf_start;
-
-  // Check what actually needs updating
-  fl_clip_box(0, 0, w(), h(), X, Y, W, H);
-  if ((W == 0) || (H == 0))
-    return;
-
-  pixel_bytes = frameBuffer->getPF().bpp/8;
-  stride_bytes = pixel_bytes * frameBuffer->getStride();
-  buf_start = frameBuffer->data +
-              pixel_bytes * X +
-              stride_bytes * Y;
-
-  // FIXME: Check how efficient this thing really is
-  fl_draw_image(buf_start, X, Y, W, H, pixel_bytes, stride_bytes);
-}
-
-
-int DesktopWindow::handle(int event)
-{
-  int buttonMask, wheelMask;
-  DownMap::const_iterator iter;
-
-  switch (event) {
-  case FL_PUSH:
-  case FL_RELEASE:
-  case FL_DRAG:
-  case FL_MOVE:
-  case FL_MOUSEWHEEL:
-    buttonMask = 0;
-    if (Fl::event_button1())
-      buttonMask |= 1;
-    if (Fl::event_button2())
-      buttonMask |= 2;
-    if (Fl::event_button3())
-      buttonMask |= 4;
-
-    if (event == FL_MOUSEWHEEL) {
-      if (Fl::event_dy() < 0)
-        wheelMask = 8;
-      else
-        wheelMask = 16;
-
-      // A quick press of the wheel "button", followed by a immediate
-      // release below
-      handlePointerEvent(Point(Fl::event_x(), Fl::event_y()),
-                         buttonMask | wheelMask);
-    } 
-
-    handlePointerEvent(Point(Fl::event_x(), Fl::event_y()), buttonMask);
-    return 1;
-
-  case FL_FOCUS:
-    // Yes, we would like some focus please!
-    return 1;
-
-  case FL_UNFOCUS:
-    // Release all keys that were pressed as that generally makes most
-    // sense (e.g. Alt+Tab where we only see the Alt press)
-    for (iter = downKeySym.begin();iter != downKeySym.end();++iter)
-      cc->writer()->keyEvent(iter->second, false);
-    downKeySym.clear();
-    return 1;
-
-  case FL_KEYDOWN:
-    handleKeyEvent(Fl::event_key(), Fl::event_compose_symbol(), true);
-    return 1;
-
-  case FL_KEYUP:
-    handleKeyEvent(Fl::event_key(), Fl::event_compose_symbol(), false);
-    return 1;
-  }
-
-  return Fl_Window::handle(event);
-}
-
-
-void DesktopWindow::handleUpdateTimeout(void *data)
-{
-  DesktopWindow *self = (DesktopWindow *)data;
-
-  assert(self);
-
-  self->updateWindow();
-}
-
-
-void DesktopWindow::handleColourMap(void *data)
-{
-  DesktopWindow *self = (DesktopWindow *)data;
-
-  assert(self);
-
-  if (self->pixelTrans != NULL)
-    self->pixelTrans->setColourMapEntries(0, 0);
-
-  self->Fl_Window::damage(FL_DAMAGE_ALL);
-}
-
 void DesktopWindow::handleClose(Fl_Widget *wnd, void *data)
 {
   exit_vncviewer();
 }
-
-
-void DesktopWindow::handlePointerEvent(const rfb::Point& pos, int buttonMask)
-{
-  if (!viewOnly) {
-    if (pointerEventInterval == 0 || buttonMask != lastButtonMask) {
-      cc->writer()->pointerEvent(pos, buttonMask);
-    } else {
-      if (!Fl::has_timeout(handlePointerTimeout, this))
-        Fl::add_timeout((double)pointerEventInterval/1000.0,
-                        handlePointerTimeout, this);
-    }
-    lastPointerPos = pos;
-    lastButtonMask = buttonMask;
-  }
-}
-
-
-void DesktopWindow::handlePointerTimeout(void *data)
-{
-  DesktopWindow *self = (DesktopWindow *)data;
-
-  assert(self);
-
-  self->cc->writer()->pointerEvent(self->lastPointerPos, self->lastButtonMask);
-}
-
-
-rdr::U32 DesktopWindow::translateKeyEvent(int keyCode, const char *keyText)
-{
-  unsigned ucs;
-
-  // First check for function keys
-  if ((keyCode > FL_F) && (keyCode <= FL_F_Last))
-    return XK_F1 + (keyCode - FL_F - 1);
-
-  // Numpad numbers
-  if ((keyCode >= (FL_KP + '0')) && (keyCode <= (FL_KP + '9')))
-    return XK_KP_0 + (keyCode - (FL_KP + '0'));
-
-  // Then other special keys
-  switch (keyCode) {
-  case FL_BackSpace:
-    return XK_BackSpace;
-  case FL_Tab:
-    return XK_Tab;
-  case FL_Enter:
-    return XK_Return;
-  case FL_Pause:
-    return XK_Pause;
-  case FL_Scroll_Lock:
-    return XK_Scroll_Lock;
-  case FL_Escape:
-    return XK_Escape;
-  case FL_Home:
-    return XK_Home;
-  case FL_Left:
-    return XK_Left;
-  case FL_Up:
-    return XK_Up;
-  case FL_Right:
-    return XK_Right;
-  case FL_Down:
-    return XK_Down;
-  case FL_Page_Up:
-    return XK_Page_Up;
-  case FL_Page_Down:
-    return XK_Page_Down;
-  case FL_End:
-    return XK_End;
-  case FL_Print:
-    return XK_Print;
-  case FL_Insert:
-    return XK_Insert;
-  case FL_Menu:
-    return XK_Menu;
-  case FL_Help:
-    return XK_Help;
-  case FL_Num_Lock:
-    return XK_Num_Lock;
-  case FL_Shift_L:
-    return XK_Shift_L;
-  case FL_Shift_R:
-    return XK_Shift_R;
-  case FL_Control_L:
-    return XK_Control_L;
-  case FL_Control_R:
-    return XK_Control_R;
-  case FL_Caps_Lock:
-    return XK_Caps_Lock;
-  case FL_Meta_L:
-    return XK_Super_L;
-  case FL_Meta_R:
-    return XK_Super_R;
-  case FL_Alt_L:
-    return XK_Alt_L;
-  case FL_Alt_R:
-    return XK_Alt_R;
-  case FL_Delete:
-    return XK_Delete;
-  case FL_KP_Enter:
-    return XK_KP_Enter;
-  case FL_KP + '=':
-    return XK_KP_Equal;
-  case FL_KP + '*':
-    return XK_KP_Multiply;
-  case FL_KP + '+':
-    return XK_KP_Add;
-  case FL_KP + ',':
-    return XK_KP_Separator;
-  case FL_KP + '-':
-    return XK_KP_Subtract;
-  case FL_KP + '.':
-    return XK_KP_Decimal;
-  case FL_KP + '/':
-    return XK_KP_Divide;
-  case XK_ISO_Level3_Shift:
-    // FLTK tends to let this one leak through on X11...
-    return XK_ISO_Level3_Shift;
-  }
-
-  // Ctrl and Cmd tend to fudge input handling, so we need to cheat here
-  if (Fl::event_state() & (FL_COMMAND | FL_CTRL)) {
-#ifdef WIN32
-    BYTE keystate[256];
-    WCHAR wbuf[8];
-    int ret;
-
-    static char buf[32];
-
-    switch (fl_msg.message) {
-    case WM_KEYDOWN:
-    case WM_SYSKEYDOWN:
-      // Most buttons end up here when Ctrl is pressed. Here we can pretend
-      // that Ctrl isn't pressed, and do a character lookup.
-      GetKeyboardState(keystate);
-      keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
-
-      ret = ToUnicode(fl_msg.wParam, 0, keystate, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), 0);
-      if (ret != 0) {
-        // -1 means one dead character
-        ret = abs(ret);
-        wbuf[ret] = 0x0000;
-
-        if (fl_utf8fromwc(buf, sizeof(buf), wbuf, ret) >= sizeof(buf)) {
-          vlog.error(_("Out of buffer space whilst converting key event"));
-          return XK_VoidSymbol;
-        }
-
-        keyText = buf;
-      }
-      break;
-    case WM_CHAR:
-    case WM_SYSCHAR:
-      // Windows doesn't seem to have any sanity when it comes to control
-      // characters. We assume that Ctrl-A through Ctrl-Z range maps to
-      // the VK_A through VK_Z keys, and just let the rest fall through.
-      if ((fl_msg.wParam < 0x01) || (fl_msg.wParam > 0x1a))
-        break;
-
-      // Pretend that Ctrl isn't pressed, and do a character lookup.
-      GetKeyboardState(keystate);
-      keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
-
-      // Ctrl-A is 0x01 and VK_A is 0x41, so add 0x40 for the conversion
-      ret = ToUnicode(fl_msg.wParam + 0x40, 0, keystate, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), 0);
-      if (ret != 0) {
-        // -1 means one dead character
-        ret = abs(ret);
-        wbuf[ret] = 0x0000;
-
-        if (fl_utf8fromwc(buf, sizeof(buf), wbuf, ret) >= sizeof(buf)) {
-          vlog.error(_("Out of buffer space whilst converting key event"));
-          return XK_VoidSymbol;
-        }
-
-        keyText = buf;
-      }
-      break;
-    default:
-      // Not sure how we ended up here. Do nothing...
-      break;
-    }
-#elif defined(__APPLE__)
-    keyText = osx_event_string();
-#else
-    char buf[16];
-    KeySym sym;
-
-    XLookupString((XKeyEvent*)fl_xevent, buf, sizeof(buf), &sym, NULL);
-
-    return sym;
-#endif
-  }
-
-  // Unknown special key?
-  if (keyText[0] == '\0') {
-    vlog.error(_("Unknown FLTK key code %d (0x%04x)"), keyCode, keyCode);
-    return XK_VoidSymbol;
-  }
-
-  // Look up the symbol the key produces and translate that from Unicode
-  // to a X11 keysym.
-  if (fl_utf_nb_char((const unsigned char*)keyText, strlen(keyText)) != 1) {
-    vlog.error(_("Multiple characters given for key code %d (0x%04x): '%s'"),
-               keyCode, keyCode, keyText);
-    return XK_VoidSymbol;
-  }
-
-  ucs = fl_utf8decode(keyText, NULL, NULL);
-  return ucs2keysym(ucs);
-}
-
-
-void DesktopWindow::handleKeyEvent(int keyCode, const char *keyText, bool down)
-{
-  rdr::U32 keySym;
-
-  if (viewOnly)
-    return;
-
-  // Because of the way keyboards work, we cannot expect to have the same
-  // symbol on release as when pressed. This breaks the VNC protocol however,
-  // so we need to keep track of what keysym a key _code_ generated on press
-  // and send the same on release.
-  if (!down) {
-    DownMap::iterator iter;
-
-    iter = downKeySym.find(keyCode);
-    if (iter == downKeySym.end()) {
-      vlog.error(_("Unexpected release of FLTK key code %d (0x%04x)"), keyCode, keyCode);
-      return;
-    }
-
-    cc->writer()->keyEvent(iter->second, false);
-
-    downKeySym.erase(iter);
-
-    return;
-  }
-
-  keySym = translateKeyEvent(keyCode, keyText);
-  if (keySym == XK_VoidSymbol)
-    return;
-
-  downKeySym[keyCode] = keySym;
-  cc->writer()->keyEvent(keySym, down);
-}
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index bf54c21..39fb9e7 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -26,10 +26,8 @@
 #include <FL/Fl_Window.H>
 
 #include <rfb/Rect.h>
-#include <rfb/Region.h>
-#include <rfb/Timer.h>
-#include <rfb/PixelBuffer.h>
-#include <rfb/PixelTransformer.h>
+
+#include "Viewport.h"
 
 class CConn;
 
@@ -58,68 +56,20 @@
   void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
 
   void fillRect(const rfb::Rect& r, rfb::Pixel pix) {
-    if (pixelTrans) {
-      rfb::Pixel pix2;
-      pixelTrans->translatePixels(&pix, &pix2, 1);
-      pix = pix2;
-    }
-
-    frameBuffer->fillRect(r, pix);
-    damageRect(r);
+    viewport->fillRect(r, pix);
   }
   void imageRect(const rfb::Rect& r, void* pixels) {
-    if (pixelTrans)
-      pixelTrans->translateRect(pixels, r.width(),
-                                rfb::Rect(0, 0, r.width(), r.height()),
-                                frameBuffer->data, frameBuffer->getStride(),
-                                r.tl);
-    else
-      frameBuffer->imageRect(r, pixels);
-    damageRect(r);
+    viewport->imageRect(r, pixels);
   }
   void copyRect(const rfb::Rect& r, int srcX, int srcY) {
-    frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
-    damageRect(r);
+    viewport->copyRect(r, srcX, srcY);
   }
 
-  // Fl_Window callback methods
-  void draw();
-  int handle(int event);
-
 private:
-
-  void damageRect(const rfb::Rect& r) {
-    damage.assign_union(rfb::Region(r));
-    if (!Fl::has_timeout(handleUpdateTimeout, this))
-      Fl::add_timeout(0.100, handleUpdateTimeout, this);
-  };
-
-  static void handleUpdateTimeout(void *data);
-  static void handleColourMap(void *data);
-
   static void handleClose(Fl_Widget *wnd, void *data);
 
-  void handlePointerEvent(const rfb::Point& pos, int buttonMask);
-  static void handlePointerTimeout(void *data);
-
-  rdr::U32 translateKeyEvent(int keyCode, const char *keyText);
-  void handleKeyEvent(int keyCode, const char *keyText, bool down);
-
 private:
-  CConn* cc;
-
-  rfb::ManagedPixelBuffer* frameBuffer;
-
-  rfb::PixelTransformer *pixelTrans;
-  rfb::SimpleColourMap colourMap;
-
-  rfb::Region damage;
-
-  rfb::Point lastPointerPos;
-  int lastButtonMask;
-
-  typedef std::map<int, rdr::U32> DownMap;
-  DownMap downKeySym;
+  Viewport *viewport;
 };
 
 #endif
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
new file mode 100644
index 0000000..6525b7c
--- /dev/null
+++ b/vncviewer/Viewport.cxx
@@ -0,0 +1,489 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * 
+ * 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 <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <FL/fl_draw.H>
+
+#include <rfb/CMsgWriter.h>
+#include <rfb/LogWriter.h>
+
+// FLTK can pull in the X11 headers on some systems
+#ifndef XK_VoidSymbol
+#define XK_MISCELLANY
+#define XK_XKB_KEYS
+#include <rfb/keysymdef.h>
+#endif
+
+#include "Viewport.h"
+#include "CConn.h"
+#include "i18n.h"
+#include "parameters.h"
+#include "keysym2ucs.h"
+
+// FLTK STR #2599 must be fixed for proper dead keys support
+#ifndef HAVE_FLTK_DEAD_KEYS
+#define event_compose_symbol event_text
+#endif
+
+using namespace rfb;
+
+#ifdef __APPLE__
+extern "C" const char *osx_event_string(void);
+#endif
+
+extern void exit_vncviewer();
+
+static rfb::LogWriter vlog("Viewport");
+
+Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
+  : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
+    lastPointerPos(0, 0), lastButtonMask(0)
+{
+  frameBuffer = new ManagedPixelBuffer(getPreferredPF(), w, h);
+  assert(frameBuffer);
+
+  setServerPF(serverPF);
+}
+
+
+Viewport::~Viewport()
+{
+  // Unregister all timeouts in case they get a change tro trigger
+  // again later when this object is already gone.
+  Fl::remove_timeout(handleUpdateTimeout, this);
+  Fl::remove_timeout(handleColourMap, this);
+  Fl::remove_timeout(handlePointerTimeout, this);
+
+  delete frameBuffer;
+
+  if (pixelTrans)
+    delete pixelTrans;
+}
+
+
+void Viewport::setServerPF(const rfb::PixelFormat& pf)
+{
+  if (pixelTrans)
+    delete pixelTrans;
+  pixelTrans = NULL;
+
+  if (pf.equal(getPreferredPF()))
+    return;
+
+  pixelTrans = new PixelTransformer();
+  pixelTrans->init(pf, &colourMap, getPreferredPF());
+}
+
+
+const rfb::PixelFormat &Viewport::getPreferredPF()
+{
+  static PixelFormat prefPF(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+
+  return prefPF;
+}
+
+
+// setColourMapEntries() changes some of the entries in the colourmap.
+// Unfortunately these messages are often sent one at a time, so we delay the
+// settings taking effect by 100ms.  This is because recalculating the internal
+// translation table can be expensive.
+void Viewport::setColourMapEntries(int firstColour, int nColours,
+                                   rdr::U16* rgbs)
+{
+  for (int i = 0; i < nColours; i++)
+    colourMap.set(firstColour+i, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]);
+
+  if (!Fl::has_timeout(handleColourMap, this))
+    Fl::add_timeout(0.100, handleColourMap, this);
+}
+
+
+// Copy the areas of the framebuffer that have been changed (damaged)
+// to the displayed window.
+
+void Viewport::updateWindow()
+{
+  Rect r;
+
+  Fl::remove_timeout(handleUpdateTimeout, this);
+
+  r = damage.get_bounding_rect();
+  Fl_Widget::damage(FL_DAMAGE_USER1, r.tl.x, r.tl.y, r.width(), r.height());
+
+  damage.clear();
+}
+
+
+void Viewport::draw()
+{
+  int X, Y, W, H;
+
+  int pixel_bytes, stride_bytes;
+  const uchar *buf_start;
+
+  // Check what actually needs updating
+  fl_clip_box(0, 0, w(), h(), X, Y, W, H);
+  if ((W == 0) || (H == 0))
+    return;
+
+  pixel_bytes = frameBuffer->getPF().bpp/8;
+  stride_bytes = pixel_bytes * frameBuffer->getStride();
+  buf_start = frameBuffer->data +
+              pixel_bytes * X +
+              stride_bytes * Y;
+
+  // FIXME: Check how efficient this thing really is
+  fl_draw_image(buf_start, X, Y, W, H, pixel_bytes, stride_bytes);
+}
+
+
+int Viewport::handle(int event)
+{
+  int buttonMask, wheelMask;
+  DownMap::const_iterator iter;
+
+  switch (event) {
+  case FL_ENTER:
+    // Yes, we would like some pointer events please!
+    return 1;
+  case FL_PUSH:
+  case FL_RELEASE:
+  case FL_DRAG:
+  case FL_MOVE:
+  case FL_MOUSEWHEEL:
+    buttonMask = 0;
+    if (Fl::event_button1())
+      buttonMask |= 1;
+    if (Fl::event_button2())
+      buttonMask |= 2;
+    if (Fl::event_button3())
+      buttonMask |= 4;
+
+    if (event == FL_MOUSEWHEEL) {
+      if (Fl::event_dy() < 0)
+        wheelMask = 8;
+      else
+        wheelMask = 16;
+
+      // A quick press of the wheel "button", followed by a immediate
+      // release below
+      handlePointerEvent(Point(Fl::event_x(), Fl::event_y()),
+                         buttonMask | wheelMask);
+    } 
+
+    handlePointerEvent(Point(Fl::event_x(), Fl::event_y()), buttonMask);
+    return 1;
+
+  case FL_FOCUS:
+    // Yes, we would like some focus please!
+    return 1;
+
+  case FL_UNFOCUS:
+    // Release all keys that were pressed as that generally makes most
+    // sense (e.g. Alt+Tab where we only see the Alt press)
+    for (iter = downKeySym.begin();iter != downKeySym.end();++iter)
+      cc->writer()->keyEvent(iter->second, false);
+    downKeySym.clear();
+    return 1;
+
+  case FL_KEYDOWN:
+    handleKeyEvent(Fl::event_key(), Fl::event_compose_symbol(), true);
+    return 1;
+
+  case FL_KEYUP:
+    handleKeyEvent(Fl::event_key(), Fl::event_compose_symbol(), false);
+    return 1;
+  }
+
+  return Fl_Widget::handle(event);
+}
+
+
+void Viewport::handleUpdateTimeout(void *data)
+{
+  Viewport *self = (Viewport *)data;
+
+  assert(self);
+
+  self->updateWindow();
+}
+
+
+void Viewport::handleColourMap(void *data)
+{
+  Viewport *self = (Viewport *)data;
+
+  assert(self);
+
+  if (self->pixelTrans != NULL)
+    self->pixelTrans->setColourMapEntries(0, 0);
+
+  self->Fl_Widget::damage(FL_DAMAGE_ALL);
+}
+
+
+void Viewport::handlePointerEvent(const rfb::Point& pos, int buttonMask)
+{
+  if (!viewOnly) {
+    if (pointerEventInterval == 0 || buttonMask != lastButtonMask) {
+      cc->writer()->pointerEvent(pos, buttonMask);
+    } else {
+      if (!Fl::has_timeout(handlePointerTimeout, this))
+        Fl::add_timeout((double)pointerEventInterval/1000.0,
+                        handlePointerTimeout, this);
+    }
+    lastPointerPos = pos;
+    lastButtonMask = buttonMask;
+  }
+}
+
+
+void Viewport::handlePointerTimeout(void *data)
+{
+  Viewport *self = (Viewport *)data;
+
+  assert(self);
+
+  self->cc->writer()->pointerEvent(self->lastPointerPos, self->lastButtonMask);
+}
+
+
+rdr::U32 Viewport::translateKeyEvent(int keyCode, const char *keyText)
+{
+  unsigned ucs;
+
+  // First check for function keys
+  if ((keyCode > FL_F) && (keyCode <= FL_F_Last))
+    return XK_F1 + (keyCode - FL_F - 1);
+
+  // Numpad numbers
+  if ((keyCode >= (FL_KP + '0')) && (keyCode <= (FL_KP + '9')))
+    return XK_KP_0 + (keyCode - (FL_KP + '0'));
+
+  // Then other special keys
+  switch (keyCode) {
+  case FL_BackSpace:
+    return XK_BackSpace;
+  case FL_Tab:
+    return XK_Tab;
+  case FL_Enter:
+    return XK_Return;
+  case FL_Pause:
+    return XK_Pause;
+  case FL_Scroll_Lock:
+    return XK_Scroll_Lock;
+  case FL_Escape:
+    return XK_Escape;
+  case FL_Home:
+    return XK_Home;
+  case FL_Left:
+    return XK_Left;
+  case FL_Up:
+    return XK_Up;
+  case FL_Right:
+    return XK_Right;
+  case FL_Down:
+    return XK_Down;
+  case FL_Page_Up:
+    return XK_Page_Up;
+  case FL_Page_Down:
+    return XK_Page_Down;
+  case FL_End:
+    return XK_End;
+  case FL_Print:
+    return XK_Print;
+  case FL_Insert:
+    return XK_Insert;
+  case FL_Menu:
+    return XK_Menu;
+  case FL_Help:
+    return XK_Help;
+  case FL_Num_Lock:
+    return XK_Num_Lock;
+  case FL_Shift_L:
+    return XK_Shift_L;
+  case FL_Shift_R:
+    return XK_Shift_R;
+  case FL_Control_L:
+    return XK_Control_L;
+  case FL_Control_R:
+    return XK_Control_R;
+  case FL_Caps_Lock:
+    return XK_Caps_Lock;
+  case FL_Meta_L:
+    return XK_Super_L;
+  case FL_Meta_R:
+    return XK_Super_R;
+  case FL_Alt_L:
+    return XK_Alt_L;
+  case FL_Alt_R:
+    return XK_Alt_R;
+  case FL_Delete:
+    return XK_Delete;
+  case FL_KP_Enter:
+    return XK_KP_Enter;
+  case FL_KP + '=':
+    return XK_KP_Equal;
+  case FL_KP + '*':
+    return XK_KP_Multiply;
+  case FL_KP + '+':
+    return XK_KP_Add;
+  case FL_KP + ',':
+    return XK_KP_Separator;
+  case FL_KP + '-':
+    return XK_KP_Subtract;
+  case FL_KP + '.':
+    return XK_KP_Decimal;
+  case FL_KP + '/':
+    return XK_KP_Divide;
+  case XK_ISO_Level3_Shift:
+    // FLTK tends to let this one leak through on X11...
+    return XK_ISO_Level3_Shift;
+  }
+
+  // Ctrl and Cmd tend to fudge input handling, so we need to cheat here
+  if (Fl::event_state() & (FL_COMMAND | FL_CTRL)) {
+#ifdef WIN32
+    BYTE keystate[256];
+    WCHAR wbuf[8];
+    int ret;
+
+    static char buf[32];
+
+    switch (fl_msg.message) {
+    case WM_KEYDOWN:
+    case WM_SYSKEYDOWN:
+      // Most buttons end up here when Ctrl is pressed. Here we can pretend
+      // that Ctrl isn't pressed, and do a character lookup.
+      GetKeyboardState(keystate);
+      keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
+
+      ret = ToUnicode(fl_msg.wParam, 0, keystate, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), 0);
+      if (ret != 0) {
+        // -1 means one dead character
+        ret = abs(ret);
+        wbuf[ret] = 0x0000;
+
+        if (fl_utf8fromwc(buf, sizeof(buf), wbuf, ret) >= sizeof(buf)) {
+          vlog.error(_("Out of buffer space whilst converting key event"));
+          return XK_VoidSymbol;
+        }
+
+        keyText = buf;
+      }
+      break;
+    case WM_CHAR:
+    case WM_SYSCHAR:
+      // Windows doesn't seem to have any sanity when it comes to control
+      // characters. We assume that Ctrl-A through Ctrl-Z range maps to
+      // the VK_A through VK_Z keys, and just let the rest fall through.
+      if ((fl_msg.wParam < 0x01) || (fl_msg.wParam > 0x1a))
+        break;
+
+      // Pretend that Ctrl isn't pressed, and do a character lookup.
+      GetKeyboardState(keystate);
+      keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
+
+      // Ctrl-A is 0x01 and VK_A is 0x41, so add 0x40 for the conversion
+      ret = ToUnicode(fl_msg.wParam + 0x40, 0, keystate, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), 0);
+      if (ret != 0) {
+        // -1 means one dead character
+        ret = abs(ret);
+        wbuf[ret] = 0x0000;
+
+        if (fl_utf8fromwc(buf, sizeof(buf), wbuf, ret) >= sizeof(buf)) {
+          vlog.error(_("Out of buffer space whilst converting key event"));
+          return XK_VoidSymbol;
+        }
+
+        keyText = buf;
+      }
+      break;
+    default:
+      // Not sure how we ended up here. Do nothing...
+      break;
+    }
+#elif defined(__APPLE__)
+    keyText = osx_event_string();
+#else
+    char buf[16];
+    KeySym sym;
+
+    XLookupString((XKeyEvent*)fl_xevent, buf, sizeof(buf), &sym, NULL);
+
+    return sym;
+#endif
+  }
+
+  // Unknown special key?
+  if (keyText[0] == '\0') {
+    vlog.error(_("Unknown FLTK key code %d (0x%04x)"), keyCode, keyCode);
+    return XK_VoidSymbol;
+  }
+
+  // Look up the symbol the key produces and translate that from Unicode
+  // to a X11 keysym.
+  if (fl_utf_nb_char((const unsigned char*)keyText, strlen(keyText)) != 1) {
+    vlog.error(_("Multiple characters given for key code %d (0x%04x): '%s'"),
+               keyCode, keyCode, keyText);
+    return XK_VoidSymbol;
+  }
+
+  ucs = fl_utf8decode(keyText, NULL, NULL);
+  return ucs2keysym(ucs);
+}
+
+
+void Viewport::handleKeyEvent(int keyCode, const char *keyText, bool down)
+{
+  rdr::U32 keySym;
+
+  if (viewOnly)
+    return;
+
+  // Because of the way keyboards work, we cannot expect to have the same
+  // symbol on release as when pressed. This breaks the VNC protocol however,
+  // so we need to keep track of what keysym a key _code_ generated on press
+  // and send the same on release.
+  if (!down) {
+    DownMap::iterator iter;
+
+    iter = downKeySym.find(keyCode);
+    if (iter == downKeySym.end()) {
+      vlog.error(_("Unexpected release of FLTK key code %d (0x%04x)"), keyCode, keyCode);
+      return;
+    }
+
+    cc->writer()->keyEvent(iter->second, false);
+
+    downKeySym.erase(iter);
+
+    return;
+  }
+
+  keySym = translateKeyEvent(keyCode, keyText);
+  if (keySym == XK_VoidSymbol)
+    return;
+
+  downKeySym[keyCode] = keySym;
+  cc->writer()->keyEvent(keySym, down);
+}
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
new file mode 100644
index 0000000..d8a584a
--- /dev/null
+++ b/vncviewer/Viewport.h
@@ -0,0 +1,118 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * 
+ * 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.
+ */
+
+#ifndef __VIEWPORT_H__
+#define __VIEWPORT_H__
+
+#include <map>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+
+#include <rfb/Rect.h>
+#include <rfb/Region.h>
+#include <rfb/Timer.h>
+#include <rfb/PixelBuffer.h>
+#include <rfb/PixelTransformer.h>
+
+class CConn;
+
+class Viewport : public Fl_Widget {
+public:
+
+  Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_);
+  ~Viewport();
+
+  // PixelFormat of incoming write operations
+  void setServerPF(const rfb::PixelFormat& pf);
+  // Most efficient format (from Viewport's point of view)
+  const rfb::PixelFormat &getPreferredPF();
+
+  // Flush updates to screen
+  void updateWindow();
+
+  // Methods forwarded from CConn
+  void setName(const char *name);
+
+  void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
+
+  void fillRect(const rfb::Rect& r, rfb::Pixel pix) {
+    if (pixelTrans) {
+      rfb::Pixel pix2;
+      pixelTrans->translatePixels(&pix, &pix2, 1);
+      pix = pix2;
+    }
+
+    frameBuffer->fillRect(r, pix);
+    damageRect(r);
+  }
+  void imageRect(const rfb::Rect& r, void* pixels) {
+    if (pixelTrans)
+      pixelTrans->translateRect(pixels, r.width(),
+                                rfb::Rect(0, 0, r.width(), r.height()),
+                                frameBuffer->data, frameBuffer->getStride(),
+                                r.tl);
+    else
+      frameBuffer->imageRect(r, pixels);
+    damageRect(r);
+  }
+  void copyRect(const rfb::Rect& r, int srcX, int srcY) {
+    frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
+    damageRect(r);
+  }
+
+  // Fl_Widget callback methods
+  void draw();
+  int handle(int event);
+
+private:
+
+  void damageRect(const rfb::Rect& r) {
+    damage.assign_union(rfb::Region(r));
+    if (!Fl::has_timeout(handleUpdateTimeout, this))
+      Fl::add_timeout(0.100, handleUpdateTimeout, this);
+  };
+
+  static void handleUpdateTimeout(void *data);
+  static void handleColourMap(void *data);
+
+  void handlePointerEvent(const rfb::Point& pos, int buttonMask);
+  static void handlePointerTimeout(void *data);
+
+  rdr::U32 translateKeyEvent(int keyCode, const char *keyText);
+  void handleKeyEvent(int keyCode, const char *keyText, bool down);
+
+private:
+  CConn* cc;
+
+  rfb::ManagedPixelBuffer* frameBuffer;
+
+  rfb::PixelTransformer *pixelTrans;
+  rfb::SimpleColourMap colourMap;
+
+  rfb::Region damage;
+
+  rfb::Point lastPointerPos;
+  int lastButtonMask;
+
+  typedef std::map<int, rdr::U32> DownMap;
+  DownMap downKeySym;
+};
+
+#endif
