Provide a better R/W base PixelBuffer class

Clearly separates the read API from the write API
and also from actual implementation.
diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h
index 59d71c7..e2cc3e9 100644
--- a/common/rfb/PixelBuffer.h
+++ b/common/rfb/PixelBuffer.h
@@ -66,7 +66,6 @@
     //   The pointer is to the top-left pixel of the specified Rect.
     //   The buffer stride (in pixels) is returned.
     virtual const rdr::U8* getBuffer(const Rect& r, int* stride) = 0;
-    virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
 
     // Get pixel data for a given part of the buffer
     //   Data is copied into the supplied buffer, with the specified
@@ -89,20 +88,31 @@
     int width_, height_;
   };
 
-  // FullFramePixelBuffer
-
-  class FullFramePixelBuffer : public PixelBuffer {
+  // ModifiablePixelBuffer
+  class ModifiablePixelBuffer : public PixelBuffer {
   public:
-    FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
-                         rdr::U8* data, int stride);
-    virtual ~FullFramePixelBuffer();
+    ModifiablePixelBuffer(const PixelFormat& pf, int width, int height);
+    virtual ~ModifiablePixelBuffer();
 
-  public:
-    // Get a pointer to specified pixel data
+    ///////////////////////////////////////////////
+    // Access to pixel data
+    //
+
+    // Get a writeable pointer into the buffer
+    //   Like getBuffer(), the pointer is to the top-left pixel of the
+    //   specified Rect and the stride in pixels is returned.
+    virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
+    // Commit the modified contents
+    //   Ensures that the changes to the specified Rect is properly
+    //   stored away and any temporary buffers are freed. The Rect given
+    //   here needs to match the Rect given to the earlier call to
+    //   getBufferRW().
+    virtual void commitBufferRW(const Rect& r) = 0;
+
+    // Default trivial handling of read-only access
     virtual const rdr::U8* getBuffer(const Rect& r, int* stride) {
       return getBufferRW(r, stride);
     }
-    virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
 
     ///////////////////////////////////////////////
     // Basic rendering operations
@@ -128,6 +138,22 @@
     void maskRect(const Rect& r, Pixel pixel, const void* mask_);
 
   protected:
+    ModifiablePixelBuffer();
+  };
+
+  // FullFramePixelBuffer
+
+  class FullFramePixelBuffer : public ModifiablePixelBuffer {
+  public:
+    FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
+                         rdr::U8* data_, int stride);
+    virtual ~FullFramePixelBuffer();
+
+  public:
+    virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
+    virtual void commitBufferRW(const Rect& r);
+
+  protected:
     FullFramePixelBuffer();
 
     rdr::U8* data;