Handle CopyRect like any other encoding

Avoids having to special case things. Keeps the code simpler.
diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
index da68a27..590aea7 100644
--- a/common/rfb/CMakeLists.txt
+++ b/common/rfb/CMakeLists.txt
@@ -13,6 +13,7 @@
   ComparingUpdateTracker.cxx
   Configuration.cxx
   ConnParams.cxx
+  CopyRectDecoder.cxx
   Cursor.cxx
   Decoder.cxx
   d3des.c
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx
index 8466c68..b39fd09 100644
--- a/common/rfb/CMsgReader.cxx
+++ b/common/rfb/CMsgReader.cxx
@@ -198,35 +198,23 @@
 
   handler->beginRect(r, encoding);
 
-  if (encoding == encodingCopyRect) {
-    readCopyRect(r);
-  } else {
+  if (!Decoder::supported(encoding)) {
+    fprintf(stderr, "Unknown rect encoding %d\n", encoding);
+    throw Exception("Unknown rect encoding");
+  }
 
-    if (!Decoder::supported(encoding)) {
+  if (!decoders[encoding]) {
+    decoders[encoding] = Decoder::createDecoder(encoding, this);
+    if (!decoders[encoding]) {
       fprintf(stderr, "Unknown rect encoding %d\n", encoding);
       throw Exception("Unknown rect encoding");
     }
-
-    if (!decoders[encoding]) {
-      decoders[encoding] = Decoder::createDecoder(encoding, this);
-      if (!decoders[encoding]) {
-        fprintf(stderr, "Unknown rect encoding %d\n", encoding);
-        throw Exception("Unknown rect encoding");
-      }
-    }
-    decoders[encoding]->readRect(r, handler);
   }
+  decoders[encoding]->readRect(r, handler);
 
   handler->endRect(r, encoding);
 }
 
-void CMsgReader::readCopyRect(const Rect& r)
-{
-  int srcX = is->readU16();
-  int srcY = is->readU16();
-  handler->copyRect(r, srcX, srcY);
-}
-
 void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
 {
   int data_len = width * height * (handler->cp.pf().bpp/8);
diff --git a/common/rfb/CMsgReader.h b/common/rfb/CMsgReader.h
index 650f164..1284667 100644
--- a/common/rfb/CMsgReader.h
+++ b/common/rfb/CMsgReader.h
@@ -62,7 +62,6 @@
     void readFramebufferUpdate();
 
     void readRect(const Rect& r, int encoding);
-    void readCopyRect(const Rect& r);
 
     void readSetCursor(int width, int height, const Point& hotspot);
     void readSetDesktopName(int x, int y, int w, int h);
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index 3d51060..6536eaf 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -113,9 +113,11 @@
   // Remaining encodings
   for (int i = encodingMax; i >= 0; i--) {
     switch (i) {
+    case encodingCopyRect:
     case encodingTight:
     case encodingZRLE:
     case encodingHextile:
+      /* These have already been sent earlier */
       break;
     default:
       if ((i != preferredEncoding) && Decoder::supported(i))
diff --git a/common/rfb/CopyRectDecoder.cxx b/common/rfb/CopyRectDecoder.cxx
new file mode 100644
index 0000000..4c83583
--- /dev/null
+++ b/common/rfb/CopyRectDecoder.cxx
@@ -0,0 +1,39 @@
+/* Copyright 2014 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 <rdr/InStream.h>
+#include <rfb/CMsgReader.h>
+#include <rfb/CMsgHandler.h>
+#include <rfb/PixelBuffer.h>
+#include <rfb/CopyRectDecoder.h>
+
+using namespace rfb;
+
+CopyRectDecoder::CopyRectDecoder(CMsgReader* reader) : Decoder(reader)
+{
+}
+
+CopyRectDecoder::~CopyRectDecoder()
+{
+}
+
+void CopyRectDecoder::readRect(const Rect& r, CMsgHandler* handler)
+{
+  int srcX = reader->getInStream()->readU16();
+  int srcY = reader->getInStream()->readU16();
+  handler->copyRect(r, srcX, srcY);
+}
diff --git a/common/rfb/CopyRectDecoder.h b/common/rfb/CopyRectDecoder.h
new file mode 100644
index 0000000..e265ee4
--- /dev/null
+++ b/common/rfb/CopyRectDecoder.h
@@ -0,0 +1,32 @@
+/* Copyright 2014 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 __RFB_COPYRECTDECODER_H__
+#define __RFB_COPYRECTDECODER_H__
+
+#include <rfb/Decoder.h>
+
+namespace rfb {
+
+  class CopyRectDecoder : public Decoder {
+  public:
+    CopyRectDecoder(CMsgReader* reader);
+    virtual ~CopyRectDecoder();
+    virtual void readRect(const Rect& r, CMsgHandler* handler);
+  };
+}
+#endif
diff --git a/common/rfb/Decoder.cxx b/common/rfb/Decoder.cxx
index 9982c93..f774f28 100644
--- a/common/rfb/Decoder.cxx
+++ b/common/rfb/Decoder.cxx
@@ -20,6 +20,7 @@
 #include <rfb/encodings.h>
 #include <rfb/Decoder.h>
 #include <rfb/RawDecoder.h>
+#include <rfb/CopyRectDecoder.h>
 #include <rfb/RREDecoder.h>
 #include <rfb/HextileDecoder.h>
 #include <rfb/ZRLEDecoder.h>
@@ -39,6 +40,7 @@
 {
   switch (encoding) {
   case encodingRaw:
+  case encodingCopyRect:
   case encodingRRE:
   case encodingHextile:
   case encodingZRLE:
@@ -54,6 +56,8 @@
   switch (encoding) {
   case encodingRaw:
     return new RawDecoder(reader);
+  case encodingCopyRect:
+    return new CopyRectDecoder(reader);
   case encodingRRE:
     return new RREDecoder(reader);
   case encodingHextile: