Delegate decoder object management to a separate class

Done in preparation for multi-core decoding. Keeps the complexity
out of the other classes. This also moves ownership of the
framebuffer in to CConnection. It's the CConnection object that is
aware of the threads and how to synchronise with them. Therefore
the ownership of the framebuffer must also be there to make sure
it isn't deleted whilst threads are working.
diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx
index 785d305..49b8a82 100644
--- a/common/rfb/CConnection.cxx
+++ b/common/rfb/CConnection.cxx
@@ -40,13 +40,15 @@
 CConnection::CConnection()
   : csecurity(0), is(0), os(0), reader_(0), writer_(0),
     shared(false),
-    state_(RFBSTATE_UNINITIALISED), useProtocol3_3(false)
+    state_(RFBSTATE_UNINITIALISED), useProtocol3_3(false),
+    framebuffer(NULL), decoder(this)
 {
   security = new SecurityClient();
 }
 
 CConnection::~CConnection()
 {
+  setFramebuffer(NULL);
   if (csecurity) csecurity->destroy();
   delete reader_;
   reader_ = 0;
@@ -60,6 +62,45 @@
   os = os_;
 }
 
+void CConnection::setFramebuffer(ModifiablePixelBuffer* fb)
+{
+  if ((framebuffer != NULL) && (fb != NULL)) {
+    Rect rect;
+
+    const rdr::U8* data;
+    int stride;
+
+    const rdr::U8 black[4] = { 0, 0, 0, 0 };
+
+    // Copy still valid area
+
+    rect.setXYWH(0, 0,
+                 __rfbmin(fb->width(), framebuffer->width()),
+                 __rfbmin(fb->height(), framebuffer->height()));
+    data = framebuffer->getBuffer(framebuffer->getRect(), &stride);
+    fb->imageRect(rect, data, stride);
+
+    // Black out any new areas
+
+    if (fb->width() > framebuffer->width()) {
+      rect.setXYWH(framebuffer->width(), 0,
+                   fb->width() - fb->width(),
+                   fb->height());
+      fb->fillRect(rect, black);
+    }
+
+    if (fb->height() > framebuffer->height()) {
+      rect.setXYWH(0, framebuffer->height(),
+                   fb->width(),
+                   fb->height() - framebuffer->height());
+      fb->fillRect(rect, black);
+    }
+  }
+
+  delete framebuffer;
+  framebuffer = fb;
+}
+
 void CConnection::initialiseProtocol()
 {
   state_ = RFBSTATE_PROTOCOL_VERSION;
@@ -260,6 +301,11 @@
   writer_->writeClientInit(shared);
 }
 
+void CConnection::dataRect(const Rect& r, int encoding)
+{
+  decoder.decodeRect(r, encoding, framebuffer);
+}
+
 void CConnection::authSuccess()
 {
 }