Push encoder and decoder handling down into the connection objects

This keeps the reader and writer objects clean and simple protocol
decoders/encoders.
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 452f724..0000c1e 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -37,6 +37,7 @@
 #include <rfb/ServerCore.h>
 #include <rfb/ComparingUpdateTracker.h>
 #include <rfb/KeyRemapper.h>
+#include <rfb/Encoder.h>
 #define XK_MISCELLANY
 #define XK_XKB_KEYS
 #include <rfb/keysymdef.h>
@@ -81,6 +82,8 @@
   peerEndpoint.buf = sock->getPeerEndpoint();
   VNCServerST::connectionsLog.write(1,"accepted: %s", peerEndpoint.buf);
 
+  memset(encoders, 0, sizeof(encoders));
+
   // Configure the socket
   setSocketTimeouts();
   lastEventTime = time(0);
@@ -106,6 +109,9 @@
   // Remove this client from the server
   server->clients.remove(this);
 
+  for (int i = 0; i <= encodingMax; i++)
+    delete encoders[i];
+
   delete [] fenceData;
 }
 
@@ -1060,18 +1066,30 @@
   }
 
   if (!ui.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) {
+    std::vector<Rect> rects;
+    std::vector<Rect>::const_iterator i;
+    int encoding;
+
+    // Make sure the encoder has the latest settings
+    encoding = cp.currentEncoding();
+
+    if (!encoders[encoding])
+      encoders[encoding] = Encoder::createEncoder(encoding, writer());
+
+    encoders[encoding]->setCompressLevel(cp.compressLevel);
+    encoders[encoding]->setQualityLevel(cp.qualityLevel);
+    encoders[encoding]->setFineQualityLevel(cp.fineQualityLevel,
+                                            cp.subsampling);
+
     // Compute the number of rectangles. Tight encoder makes the things more
     // complicated as compared to the original VNC4.
-    writer()->setupCurrentEncoder();
     int nRects = (ui.copied.numRects() +
                   (drawRenderedCursor ? 1 : 0));
 
-    std::vector<Rect> rects;
-    std::vector<Rect>::const_iterator i;
     ui.changed.get_rects(&rects);
     for (i = rects.begin(); i != rects.end(); i++) {
       if (i->width() && i->height()) {
-        int nUpdateRects = writer()->getNumRects(*i);
+        int nUpdateRects = encoders[encoding]->getNumRects(*i);
         if (nUpdateRects == 0 && cp.currentEncoding() == encodingTight) {
           // With Tight encoding and LastRect support, the client does not
           // care about the number of rectangles in the update - it will
@@ -1088,17 +1106,33 @@
     
     writer()->writeFramebufferUpdateStart(nRects);
 
-    writer()->writeRects(ui, &image_getter);
-    updates.clear();
+    ui.copied.get_rects(&rects);
+    for (i = rects.begin(); i != rects.end(); i++)
+      writer()->writeCopyRect(*i, i->tl.x - ui.copy_delta.x,
+                              i->tl.y - ui.copy_delta.y);
 
-    if (drawRenderedCursor)
-      writeRenderedCursorRect();
+    ui.changed.get_rects(&rects);
+    for (i = rects.begin(); i != rects.end(); i++)
+      encoders[encoding]->writeRect(*i, &image_getter);
+
+    if (drawRenderedCursor) {
+      image_getter.setPixelBuffer(&server->renderedCursor);
+      image_getter.setOffset(server->renderedCursorTL);
+
+      encoders[encoding]->writeRect(renderedCursorRect, &image_getter);
+
+      image_getter.setPixelBuffer(server->pb);
+      image_getter.setOffset(Point(0,0));
+
+      drawRenderedCursor = false;
+    }
 
     writer()->writeFramebufferUpdateEnd();
 
     writeRTTPing();
 
     requested.clear();
+    updates.clear();
   }
 
 out:
@@ -1106,22 +1140,6 @@
 }
 
 
-// writeRenderedCursorRect() writes a single rectangle drawing the rendered
-// cursor on the client.
-
-void VNCSConnectionST::writeRenderedCursorRect()
-{
-  image_getter.setPixelBuffer(&server->renderedCursor);
-  image_getter.setOffset(server->renderedCursorTL);
-
-  writer()->writeRect(renderedCursorRect, &image_getter);
-
-  image_getter.setPixelBuffer(server->pb);
-  image_getter.setOffset(Point(0,0));
-
-  drawRenderedCursor = false;
-}
-
 void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
 {
   if (!authenticated())