Extend JavaPixelBuffer to make further use of Graphics2D ops
diff --git a/java/com/tigervnc/vncviewer/JavaPixelBuffer.java b/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
index 4febec1..016b8cf 100644
--- a/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
+++ b/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
@@ -24,6 +24,7 @@
 import java.nio.*;
 
 import com.tigervnc.rfb.*;
+import com.tigervnc.rfb.Point;
 
 public class JavaPixelBuffer extends PlatformPixelBuffer 
 {
@@ -36,6 +37,23 @@
     image.setAccelerationPriority(1);
   }
 
+  public WritableRaster getBufferRW(Rect r)
+  {
+    synchronized(image) {
+      return ((BufferedImage)image)
+        .getSubimage(r.tl.x, r.tl.y, r.width(), r.height()).getRaster();
+    }
+  }
+
+  public Raster getBuffer(Rect r)
+  {
+    Rectangle rect =
+      new Rectangle(r.tl.x, r.tl.y, r.width(), r.height());
+    synchronized(image) {
+      return ((BufferedImage)image).getData(rect);
+    }
+  }
+
   public void fillRect(Rect r, byte[] pix)
   {
     ColorModel cm = format.getColorModel();
@@ -43,7 +61,7 @@
       ByteBuffer.wrap(pix).order(format.getByteOrder()).asIntBuffer().get(0);
     Color c = new Color(cm.getRGB(pixel));
     synchronized(image) {
-      Graphics2D g2 = ((BufferedImage)image).createGraphics();
+      Graphics2D g2 = (Graphics2D)image.getGraphics();
       g2.setColor(c);
       g2.fillRect(r.tl.x, r.tl.y, r.width(), r.height());
       g2.dispose();
@@ -52,6 +70,20 @@
     commitBufferRW(r);
   }
 
+  public void copyRect(Rect rect, Point move_by_delta)
+  {
+    synchronized(image) {
+      Graphics2D g2 = (Graphics2D)image.getGraphics();
+      g2.copyArea(rect.tl.x - move_by_delta.x,
+                  rect.tl.y - move_by_delta.y,
+                  rect.width(), rect.height(),
+                  move_by_delta.x, move_by_delta.y);
+      g2.dispose();
+    }
+
+    commitBufferRW(rect);
+  }
+
   private static PixelFormat getPreferredPF()
   {
     GraphicsEnvironment ge =