diff --git a/java/com/tigervnc/rfb/CopyRectDecoder.java b/java/com/tigervnc/rfb/CopyRectDecoder.java
new file mode 100644
index 0000000..a4298fd
--- /dev/null
+++ b/java/com/tigervnc/rfb/CopyRectDecoder.java
@@ -0,0 +1,44 @@
+/* Copyright 2014 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright 2016 Brian P. Hinz
+ * 
+ * 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.
+ */
+
+package com.tigervnc.rfb;
+
+import com.tigervnc.rdr.*;
+
+public class CopyRectDecoder extends Decoder {
+
+  public CopyRectDecoder() { super(DecoderFlags.DecoderPlain); }
+
+  public void readRect(Rect r, InStream is,
+                       ConnParams cp, OutStream os)
+  {
+    os.copyBytes(is, 4);
+  }
+
+  public void decodeRect(Rect r, Object buffer,
+                         int buflen, ConnParams cp,
+                         ModifiablePixelBuffer pb)
+  {
+    MemInStream is = new MemInStream((byte[])buffer, 0, buflen);
+    int srcX = is.readU16();
+    int srcY = is.readU16();
+    pb.copyRect(r, new Point(r.tl.x-srcX, r.tl.y-srcY));
+  }
+
+}
diff --git a/java/com/tigervnc/rfb/Cursor.java b/java/com/tigervnc/rfb/Cursor.java
index 78aa0fb..05122ae 100644
--- a/java/com/tigervnc/rfb/Cursor.java
+++ b/java/com/tigervnc/rfb/Cursor.java
@@ -20,11 +20,18 @@
 
 public class Cursor extends ManagedPixelBuffer {
 
+  public Cursor(PixelFormat pf, int w, int h) {
+    super(pf, w, h);
+    hotspot = new Point(0, 0);
+  }
+
   public void setSize(int w, int h) {
+    int oldMaskLen = maskLen();
     super.setSize(w, h);
-    if (mask == null || mask.length < maskLen())
+    if (mask == null || maskLen() > oldMaskLen)
       mask = new byte[maskLen()];
   }
+
   public int maskLen() { return (width() + 7) / 8 * height(); }
 
   public Point hotspot;
diff --git a/java/com/tigervnc/rfb/DecodeManager.java b/java/com/tigervnc/rfb/DecodeManager.java
new file mode 100644
index 0000000..9e254ad
--- /dev/null
+++ b/java/com/tigervnc/rfb/DecodeManager.java
@@ -0,0 +1,386 @@
+/* Copyright 2015 Pierre Ossman for Cendio AB
+ * Copyright 2016 Brian P. Hinz
+ * 
+ * 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.
+ */
+
+package com.tigervnc.rfb;
+
+import java.lang.Runtime;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+
+import com.tigervnc.rdr.*;
+import com.tigervnc.rdr.Exception;
+
+import static com.tigervnc.rfb.Decoder.DecoderFlags.*;
+
+public class DecodeManager {
+
+  static LogWriter vlog = new LogWriter("DecodeManager");
+
+  public DecodeManager(CConnection conn) {
+    int cpuCount;
+
+    this.conn = conn; threadException = null;
+    decoders = new Decoder[Encodings.encodingMax+1];
+
+    queueMutex = new ReentrantLock();
+    producerCond = queueMutex.newCondition();
+    consumerCond = queueMutex.newCondition();
+
+    //cpuCount = 1;
+    cpuCount = Runtime.getRuntime().availableProcessors();
+    if (cpuCount == 0) {
+      vlog.error("Unable to determine the number of CPU cores on this system");
+      cpuCount = 1;
+    } else {
+      vlog.info("Detected "+cpuCount+" CPU core(s)");
+      // No point creating more threads than this, they'll just end up
+      // wasting CPU fighting for locks
+      if (cpuCount > 4)
+        cpuCount = 4;
+      // The overhead of threading is small, but not small enough to
+      // ignore on single CPU systems
+      if (cpuCount == 1)
+        vlog.info("Decoding data on main thread");
+      else
+        vlog.info("Creating "+cpuCount+" decoder thread(s)");
+    }
+
+    freeBuffers = new ArrayDeque<MemOutStream>(cpuCount*2);
+    workQueue = new ArrayDeque<QueueEntry>(cpuCount);
+    threads = new ArrayList<DecodeThread>(cpuCount);
+    while (cpuCount-- > 0) {
+      // Twice as many possible entries in the queue as there
+      // are worker threads to make sure they don't stall
+      try {
+      freeBuffers.addLast(new MemOutStream());
+      freeBuffers.addLast(new MemOutStream());
+
+      threads.add(new DecodeThread(this));
+      } catch (IllegalStateException e) { }
+    }
+
+  }
+
+  public void decodeRect(Rect r, int encoding,
+                         ModifiablePixelBuffer pb)
+  {
+    Decoder decoder;
+    MemOutStream bufferStream;
+
+    QueueEntry entry;
+
+    assert(pb != null);
+
+    if (!Decoder.supported(encoding)) {
+      vlog.error("Unknown encoding " + encoding);
+      throw new Exception("Unknown encoding");
+    }
+
+    if (decoders[encoding] == null) {
+      decoders[encoding] = Decoder.createDecoder(encoding);
+      if (decoders[encoding] == null) {
+        vlog.error("Unknown encoding " + encoding);
+        throw new Exception("Unknown encoding");
+      }
+    }
+
+    decoder = decoders[encoding];
+
+    // Fast path for single CPU machines to avoid the context
+    // switching overhead
+    if (threads.size() == 1) {
+      bufferStream = freeBuffers.getFirst();
+      bufferStream.clear();
+      decoder.readRect(r, conn.getInStream(), conn.cp, bufferStream);
+      decoder.decodeRect(r, (Object)bufferStream.data(), bufferStream.length(),
+                         conn.cp, pb);
+      return;
+    }
+
+    // Wait for an available memory buffer
+    queueMutex.lock();
+
+    while (freeBuffers.isEmpty())
+      try {
+      producerCond.await();
+      } catch (InterruptedException e) { }
+
+    // Don't pop the buffer in case we throw an exception
+    // whilst reading
+    bufferStream = freeBuffers.getFirst();
+
+    queueMutex.unlock();
+
+    // First check if any thread has encountered a problem
+    throwThreadException();
+
+    // Read the rect
+    bufferStream.clear();
+    decoder.readRect(r, conn.getInStream(), conn.cp, bufferStream);
+
+    // Then try to put it on the queue
+    entry = new QueueEntry();
+
+    entry.active = false;
+    entry.rect = r;
+    entry.encoding = encoding;
+    entry.decoder = decoder;
+    entry.cp = conn.cp;
+    entry.pb = pb;
+    entry.bufferStream = bufferStream;
+    entry.affectedRegion = new Region(r);
+
+    decoder.getAffectedRegion(r, bufferStream.data(),
+                              bufferStream.length(), conn.cp,
+                              entry.affectedRegion);
+
+    // The workers add buffers to the end so it's safe to assume
+    // the front is still the same buffer
+    freeBuffers.removeFirst();
+
+    queueMutex.lock();
+
+    workQueue.addLast(entry);
+
+    // We only put a single entry on the queue so waking a single
+    // thread is sufficient
+    consumerCond.signal();
+
+    queueMutex.unlock();
+  }
+
+  public void flush()
+  {
+    queueMutex.lock();
+
+    while (!workQueue.isEmpty())
+      try {
+      producerCond.await();
+      } catch (InterruptedException e) { }
+
+    queueMutex.unlock();
+
+    throwThreadException();
+  }
+
+  private void setThreadException(Exception e)
+  {
+    //os::AutoMutex a(queueMutex);
+    queueMutex.lock();
+
+    if (threadException == null)
+      return;
+
+    threadException =
+      new Exception("Exception on worker thread: "+e.getMessage());
+  }
+
+  private void throwThreadException()
+  {
+    //os::AutoMutex a(queueMutex);
+    queueMutex.lock();
+
+    if (threadException == null)
+      return;
+
+    Exception e = new Exception(threadException.getMessage());
+
+    threadException = null;
+
+    throw e;
+  }
+
+  private class QueueEntry {
+
+    public QueueEntry() {
+    }
+    public boolean active;
+    public Rect rect;
+    public int encoding;
+    public Decoder decoder;
+    public ConnParams cp;
+    public ModifiablePixelBuffer pb;
+    public MemOutStream bufferStream;
+    public Region affectedRegion;
+  }
+
+  private class DecodeThread implements Runnable {
+
+    public DecodeThread(DecodeManager manager)
+    {
+      this.manager = manager;
+
+      stopRequested = false;
+
+      (thread = new Thread(this)).start();
+    }
+
+    public void stop()
+    {
+      //os::AutoMutex a(manager.queueMutex);
+      manager.queueMutex.lock();
+
+      if (!thread.isAlive())
+        return;
+
+      stopRequested = true;
+
+      // We can't wake just this thread, so wake everyone
+      manager.consumerCond.signalAll();
+    }
+
+    public void run()
+    {
+      manager.queueMutex.lock();
+      while (!stopRequested) {
+        QueueEntry entry;
+
+        // Look for an available entry in the work queue
+        entry = findEntry();
+        if (entry == null) {
+          // Wait and try again
+          try {
+          manager.consumerCond.await();
+          } catch (InterruptedException e) { }
+          continue;
+        }
+
+        // This is ours now
+        entry.active = true;
+
+        manager.queueMutex.unlock();
+
+        // Do the actual decoding
+        try {
+          entry.decoder.decodeRect(entry.rect, entry.bufferStream.data(),
+                                   entry.bufferStream.length(),
+                                   entry.cp, entry.pb);
+        } catch (com.tigervnc.rdr.Exception e) {
+          manager.setThreadException(e);
+        } catch(java.lang.Exception e) {
+          assert(false);
+        }
+
+        manager.queueMutex.lock();
+
+        // Remove the entry from the queue and give back the memory buffer
+        manager.freeBuffers.add(entry.bufferStream);
+        manager.workQueue.remove(entry);
+        entry = null;
+
+        // Wake the main thread in case it is waiting for a memory buffer
+        manager.producerCond.signal();
+        // This rect might have been blocking multiple other rects, so
+        // wake up every worker thread
+        if (manager.workQueue.size() > 1)
+          manager.consumerCond.signalAll();
+      }
+
+      manager.queueMutex.unlock();
+    }
+
+    protected QueueEntry findEntry()
+    {
+      Iterator<QueueEntry> iter;
+      Region lockedRegion = new Region();
+
+      if (manager.workQueue.isEmpty())
+        return null;
+
+      if (!manager.workQueue.peek().active)
+        return manager.workQueue.peek();
+
+      for (iter = manager.workQueue.iterator(); iter.hasNext();) {
+        QueueEntry entry;
+
+        Iterator<QueueEntry> iter2;
+
+        entry = iter.next();
+
+        // Another thread working on this?
+        if (entry.active) {
+          lockedRegion.assign_union(entry.affectedRegion);
+          continue;
+        }
+
+        // If this is an ordered decoder then make sure this is the first
+        // rectangle in the queue for that decoder
+        if ((entry.decoder.flags & DecoderOrdered) != 0) {
+          for (iter2 = manager.workQueue.iterator(); iter2.hasNext() && iter2 != iter;) {
+            if (entry.encoding == (iter2.next()).encoding) {
+              lockedRegion.assign_union(entry.affectedRegion);
+              continue;
+            }
+          }
+        }
+
+        // For a partially ordered decoder we must ask the decoder for each
+        // pair of rectangles.
+        if ((entry.decoder.flags & DecoderPartiallyOrdered) != 0) {
+          for (iter2 = manager.workQueue.iterator(); iter2.hasNext() && iter2 != iter;) {
+            QueueEntry entry2 = iter2.next();
+            if (entry.encoding != entry2.encoding)
+              continue;
+            if (entry.decoder.doRectsConflict(entry.rect,
+                                              entry.bufferStream.data(),
+                                              entry.bufferStream.length(),
+                                              entry2.rect,
+                                              entry2.bufferStream.data(),
+                                              entry2.bufferStream.length(),
+                                              entry.cp))
+              lockedRegion.assign_union(entry.affectedRegion);
+              continue;
+          }
+        }
+
+        // Check overlap with earlier rectangles
+        if (!lockedRegion.intersect(entry.affectedRegion).is_empty()) {
+          lockedRegion.assign_union(entry.affectedRegion);
+          continue;
+        }
+
+        return entry;
+
+      }
+
+      return null;
+    }
+
+    private DecodeManager manager;
+    private boolean stopRequested;
+
+    private Thread thread;
+
+  }
+
+  private CConnection conn;
+  private Decoder[] decoders;
+
+  private ArrayDeque<MemOutStream> freeBuffers;
+  private ArrayDeque<QueueEntry> workQueue;
+
+  private ReentrantLock queueMutex;
+  private Condition producerCond;
+  private Condition consumerCond;
+
+  private List<DecodeThread> threads;
+  private com.tigervnc.rdr.Exception threadException;
+
+}
diff --git a/java/com/tigervnc/rfb/Decoder.java b/java/com/tigervnc/rfb/Decoder.java
index f0ece0a..6bbed85 100644
--- a/java/com/tigervnc/rfb/Decoder.java
+++ b/java/com/tigervnc/rfb/Decoder.java
@@ -18,34 +18,80 @@
 
 package com.tigervnc.rfb;
 
+import com.tigervnc.rdr.*;
+
 abstract public class Decoder {
 
-  abstract public void readRect(Rect r, CMsgHandler handler);
+  public static class DecoderFlags {
+    // A constant for decoders that don't need anything special
+    public static int DecoderPlain = 0;
+    // All rects for this decoder must be handled in order
+    public static int DecoderOrdered = 1 << 0;
+    // Only some of the rects must be handled in order,
+    // see doesRectsConflict()
+    public static int DecoderPartiallyOrdered = 1 << 1;
+  };
+
+  public Decoder(int flags)
+  {
+    this.flags = flags;
+  }
+
+  abstract public void readRect(Rect r, InStream is,
+                                ConnParams cp, OutStream os);
+
+  abstract public void decodeRect(Rect r, Object buffer,
+                                  int buflen, ConnParams cp,
+                                  ModifiablePixelBuffer pb);
+
+  public void getAffectedRegion(Rect rect, Object buffer,
+                                int buflen, ConnParams cp,
+                                Region region)
+  {
+    region.reset(rect);
+  }
+
+  public boolean doRectsConflict(Rect rectA, Object bufferA,
+                                 int buflenA, Rect rectB,
+                                 Object bufferB, int buflenB,
+                                 ConnParams cp)
+  {
+    return false;
+  }
 
   static public boolean supported(int encoding)
   {
-/*
-    return encoding <= Encodings.encodingMax && createFns[encoding];
-*/
-    return (encoding == Encodings.encodingRaw ||
-            encoding == Encodings.encodingRRE ||
-            encoding == Encodings.encodingHextile ||
-            encoding == Encodings.encodingTight ||
-            encoding == Encodings.encodingZRLE);
-  }
-  static public Decoder createDecoder(int encoding, CMsgReader reader) {
-/*
-    if (encoding <= Encodings.encodingMax && createFns[encoding])
-      return (createFns[encoding])(reader);
-    return 0;
-*/
     switch(encoding) {
-    case Encodings.encodingRaw:     return new RawDecoder(reader);
-    case Encodings.encodingRRE:     return new RREDecoder(reader);
-    case Encodings.encodingHextile: return new HextileDecoder(reader);
-    case Encodings.encodingTight:   return new TightDecoder(reader);
-    case Encodings.encodingZRLE:    return new ZRLEDecoder(reader);
+    case Encodings.encodingRaw:
+    case Encodings.encodingCopyRect:
+    case Encodings.encodingRRE:
+    case Encodings.encodingHextile:
+    case Encodings.encodingZRLE:
+    case Encodings.encodingTight:
+      return true;
+    default:
+      return false;
     }
-    return null;
   }
+
+  static public Decoder createDecoder(int encoding) {
+    switch(encoding) {
+    case Encodings.encodingRaw:
+      return new RawDecoder();
+    case Encodings.encodingCopyRect:
+      return new CopyRectDecoder();
+    case Encodings.encodingRRE:
+      return new RREDecoder();
+    case Encodings.encodingHextile:
+      return new HextileDecoder();
+    case Encodings.encodingZRLE:
+      return new ZRLEDecoder();
+    case Encodings.encodingTight:
+      return new TightDecoder();
+    default:
+      return null;
+    }
+  }
+
+  public final int flags;
 }
diff --git a/java/com/tigervnc/rfb/FullFramePixelBuffer.java b/java/com/tigervnc/rfb/FullFramePixelBuffer.java
new file mode 100644
index 0000000..1c3b095
--- /dev/null
+++ b/java/com/tigervnc/rfb/FullFramePixelBuffer.java
@@ -0,0 +1,54 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+package com.tigervnc.rfb;
+
+import java.awt.image.*;
+
+public class FullFramePixelBuffer extends ModifiablePixelBuffer {
+
+  public FullFramePixelBuffer(PixelFormat pf, int w, int h,
+                              WritableRaster data_) {
+    super(pf, w, h);
+    data = data_;
+  }
+
+  protected FullFramePixelBuffer() {}
+
+  public WritableRaster getBufferRW(Rect r)
+  {
+    return data.createWritableChild(r.tl.x, r.tl.y, r.width(), r.height(),
+                                    0, 0, null);
+  }
+
+  public void commitBufferRW(Rect r)
+  {
+  }
+
+  public Raster getBuffer(Rect r)
+  {
+    Raster src =
+      data.createChild(r.tl.x, r.tl.y, r.width(), r.height(), 0, 0, null);
+    WritableRaster dst =
+      data.createCompatibleWritableRaster(r.width(), r.height());
+    dst.setDataElements(0, 0, src);
+    return dst;
+  }
+
+  protected WritableRaster data;
+}
diff --git a/java/com/tigervnc/rfb/HextileDecoder.java b/java/com/tigervnc/rfb/HextileDecoder.java
index 94e91f7..b0744ca 100644
--- a/java/com/tigervnc/rfb/HextileDecoder.java
+++ b/java/com/tigervnc/rfb/HextileDecoder.java
@@ -18,22 +18,126 @@
 
 package com.tigervnc.rfb;
 
+import java.awt.image.*;
+import java.nio.*;
+import java.util.Arrays;
+
 import com.tigervnc.rdr.*;
 
 public class HextileDecoder extends Decoder {
 
-  public HextileDecoder(CMsgReader reader_) { reader = reader_; }
+  public static final int hextileRaw = (1 << 0);
+  public static final int hextileBgSpecified = (1 << 1);
+  public static final int hextileFgSpecified = (1 << 2);
+  public static final int hextileAnySubrects = (1 << 3);
+  public static final int hextileSubrectsColoured = (1 << 4);
 
-  public void readRect(Rect r, CMsgHandler handler) {
-    InStream is = reader.getInStream();
-    int bytesPerPixel = handler.cp.pf().bpp / 8;
-    boolean bigEndian = handler.cp.pf().bigEndian;
+  public HextileDecoder() { super(DecoderFlags.DecoderPlain); }
 
-    int[] buf = reader.getImageBuf(16 * 16 * 4);
-
+  public void readRect(Rect r, InStream is,
+                       ConnParams cp, OutStream os)
+  {
     Rect t = new Rect();
-    int bg = 0;
-    int fg = 0;
+    int bytesPerPixel;
+
+    bytesPerPixel = cp.pf().bpp/8;
+
+    for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {
+
+      t.br.y = Math.min(r.br.y, t.tl.y + 16);
+
+      for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 16) {
+        int tileType;
+
+        t.br.x = Math.min(r.br.x, t.tl.x + 16);
+
+        tileType = is.readU8() & 0xff;
+        os.writeU32(tileType);
+
+        if ((tileType & hextileRaw) != 0) {
+          os.copyBytes(is, t.area() * bytesPerPixel);
+          continue;
+        }
+
+        if ((tileType & hextileBgSpecified) != 0)
+          os.copyBytes(is, bytesPerPixel);
+
+        if ((tileType & hextileFgSpecified) != 0)
+          os.copyBytes(is, bytesPerPixel);
+
+        if ((tileType & hextileAnySubrects) != 0) {
+          int nSubrects;
+
+          nSubrects = is.readU8() & 0xff;
+          os.writeU32(nSubrects);
+
+          if ((tileType & hextileSubrectsColoured) != 0)
+            os.copyBytes(is, nSubrects * (bytesPerPixel + 2));
+          else
+            os.copyBytes(is, nSubrects * 2);
+        }
+      }
+    }
+  }
+
+  public void decodeRect(Rect r, Object buffer,
+                         int buflen, ConnParams cp,
+                         ModifiablePixelBuffer pb)
+  {
+    MemInStream is = new MemInStream((byte[])buffer, 0, buflen);
+    PixelFormat pf = cp.pf();
+    switch (pf.bpp) {
+    case 8:  hextileDecode8(r, is, pf, pb); break;
+    case 16: hextileDecode16(r, is, pf, pb); break;
+    case 32: hextileDecode32(r, is, pf, pb); break;
+    }
+  }
+
+  private void hextileDecode8(Rect r, InStream is,
+                              PixelFormat pf,
+                              ModifiablePixelBuffer pb)
+  {
+    HEXTILE_DECODE(r, is, pf, pb);
+  }
+
+  private void hextileDecode16(Rect r, InStream is,
+                               PixelFormat pf,
+                               ModifiablePixelBuffer pb)
+  {
+    HEXTILE_DECODE(r, is, pf, pb);
+  }
+
+  private void hextileDecode32(Rect r, InStream is,
+                               PixelFormat pf,
+                               ModifiablePixelBuffer pb)
+  {
+    HEXTILE_DECODE(r, is, pf, pb);
+  }
+
+  private static ByteBuffer READ_PIXEL(InStream is, PixelFormat pf) {
+    ByteBuffer b = ByteBuffer.allocate(4);
+    switch (pf.bpp) {
+    case 8:
+      b.putInt(is.readOpaque8());
+      return ByteBuffer.allocate(1).put(b.get(3));
+    case 16:
+      b.putInt(is.readOpaque16());
+      return ByteBuffer.allocate(2).put(b.array(), 2, 2);
+    case 32:
+    default:
+      b.putInt(is.readOpaque32());
+      return b;
+    }
+  }
+
+  private void HEXTILE_DECODE(Rect r, InStream is,
+                                     PixelFormat pf,
+                                     ModifiablePixelBuffer pb)
+  {
+    Rect t = new Rect();
+    ByteBuffer bg = ByteBuffer.allocate(pf.bpp/8);
+    ByteBuffer fg = ByteBuffer.allocate(pf.bpp/8);
+    ByteBuffer buf = ByteBuffer.allocate(16 * 16 * 4);
 
     for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {
 
@@ -43,59 +147,51 @@
 
         t.br.x = Math.min(r.br.x, t.tl.x + 16);
 
-        int tileType = is.readU8();
+        int tileType = is.readU32();
 
-        if ((tileType & Hextile.raw) != 0) {
-          is.readPixels(buf, t.area(), bytesPerPixel, bigEndian);
-          handler.imageRect(t, buf);
+        if ((tileType & hextileRaw) != 0) {
+          is.readBytes(buf, t.area() * (pf.bpp/8));
+          pb.imageRect(pf, t, buf.array());
           continue;
         }
 
-        if ((tileType & Hextile.bgSpecified) != 0)
-          bg = is.readPixel(bytesPerPixel, bigEndian);
+        if ((tileType & hextileBgSpecified) != 0)
+          bg = READ_PIXEL(is, pf);
 
         int len = t.area();
-        int ptr = 0;
-        while (len-- > 0) buf[ptr++] = bg;
+        ByteBuffer ptr = buf.duplicate();
+        while (len-- > 0) ptr.put(bg.array());
 
-        if ((tileType & Hextile.fgSpecified) != 0)
-          fg = is.readPixel(bytesPerPixel, bigEndian);
+        if ((tileType & hextileFgSpecified) != 0)
+          fg = READ_PIXEL(is, pf);
 
-        if ((tileType & Hextile.anySubrects) != 0) {
-          int nSubrects = is.readU8();
+        if ((tileType & hextileAnySubrects) != 0) {
+          int nSubrects = is.readU32();
 
           for (int i = 0; i < nSubrects; i++) {
 
-            if ((tileType & Hextile.subrectsColoured) != 0)
-              fg = is.readPixel(bytesPerPixel, bigEndian);
+            if ((tileType & hextileSubrectsColoured) != 0)
+              fg = READ_PIXEL(is, pf);
 
             int xy = is.readU8();
             int wh = is.readU8();
 
-/*
-            Rect s = new Rect();
-            s.tl.x = t.tl.x + ((xy >> 4) & 15);
-            s.tl.y = t.tl.y + (xy & 15);
-            s.br.x = s.tl.x + ((wh >> 4) & 15) + 1;
-            s.br.y = s.tl.y + (wh & 15) + 1;
-*/
             int x = ((xy >> 4) & 15);
             int y = (xy & 15);
             int w = ((wh >> 4) & 15) + 1;
             int h = (wh & 15) + 1;
-            ptr = y * t.width() + x;
-            int rowAdd = t.width() - w;
+            ptr = buf.duplicate();
+            ptr.position((y * t.width() + x)*pf.bpp/8);
+            int rowAdd = (t.width() - w)*pf.bpp/8;
             while (h-- > 0) {
               len = w;
-              while (len-- > 0) buf[ptr++] = fg;
-              ptr += rowAdd;
+              while (len-- > 0) ptr.put(fg.array());
+              ptr.position(ptr.position()+Math.min(rowAdd,ptr.remaining()));
             }
           }
         }
-        handler.imageRect(t, buf);
+        pb.imageRect(pf, t, buf.array());
       }
     }
   }
-
-  CMsgReader reader;
 }
diff --git a/java/com/tigervnc/rfb/JpegDecompressor.java b/java/com/tigervnc/rfb/JpegDecompressor.java
new file mode 100644
index 0000000..9137847
--- /dev/null
+++ b/java/com/tigervnc/rfb/JpegDecompressor.java
@@ -0,0 +1,53 @@
+/* Copyright (C) 2016 Brian P. Hinz
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+package com.tigervnc.rfb;
+
+import java.awt.image.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import javax.imageio.*;
+import javax.imageio.stream.*;
+
+public class JpegDecompressor {
+
+  public JpegDecompressor() {}
+
+  public void decompress(ByteBuffer jpegBuf, int jpegBufLen,
+    WritableRaster buf, Rect r, PixelFormat pf)
+  {
+
+    byte[] src = new byte[jpegBufLen];
+
+    jpegBuf.get(src);
+    try {
+      BufferedImage image =
+        ImageIO.read(new MemoryCacheImageInputStream(new ByteArrayInputStream(src)));
+      ColorModel cm = pf.getColorModel();
+      if (cm.isCompatibleRaster(image.getRaster()) &&
+          cm.isCompatibleSampleModel(image.getRaster().getSampleModel())) {
+        buf.setDataElements(0, 0, image.getRaster());
+      } else {
+        ColorConvertOp converter = pf.getColorConvertOp(cm.getColorSpace());
+        converter.filter(image.getRaster(), buf);
+      }
+      image.flush();
+    } catch (IOException e) {
+      throw new Exception(e.getMessage());
+    }
+  }
+}
diff --git a/java/com/tigervnc/rfb/ManagedPixelBuffer.java b/java/com/tigervnc/rfb/ManagedPixelBuffer.java
index f947af7..6e14b92 100644
--- a/java/com/tigervnc/rfb/ManagedPixelBuffer.java
+++ b/java/com/tigervnc/rfb/ManagedPixelBuffer.java
@@ -18,21 +18,37 @@
 
 package com.tigervnc.rfb;
 
-public class ManagedPixelBuffer extends PixelBuffer {
-  public void setSize(int w, int h) {
-    width_ = w;
-    height_ = h;
-    checkDataSize();
-  }
-  public void setPF(PixelFormat pf) {
-    super.setPF(pf);
+public class ManagedPixelBuffer extends FullFramePixelBuffer {
+
+  public ManagedPixelBuffer() {
+    datasize = 0;
     checkDataSize();
   }
 
-  public int dataLen() { return area(); }
+  public ManagedPixelBuffer(PixelFormat pf, int w, int h)
+  {
+    super(pf, w, h, null);
+    datasize = 0;
+    checkDataSize();
+  }
+
+  public void setPF(PixelFormat pf) {
+    format = pf; checkDataSize();
+  }
+
+  public void setSize(int w, int h) {
+    width_ = w; height_ = h; checkDataSize();
+  }
 
   final void checkDataSize() {
-    if (data == null || data.length < dataLen())
-      data = new int[dataLen()];
+    int new_datasize = width_ * height_;
+    if (datasize < new_datasize) {
+      vlog.debug("reallocating managed buffer ("+width_+"x"+height_+")");
+      if (format != null)
+        data = PixelFormat.getColorModel(format).createCompatibleWritableRaster(width_, height_);
+    }
   }
+
+  protected int datasize;
+  static LogWriter vlog = new LogWriter("ManagedPixelBuffer");
 }
diff --git a/java/com/tigervnc/rfb/ModifiablePixelBuffer.java b/java/com/tigervnc/rfb/ModifiablePixelBuffer.java
new file mode 100644
index 0000000..bcc559d
--- /dev/null
+++ b/java/com/tigervnc/rfb/ModifiablePixelBuffer.java
@@ -0,0 +1,267 @@
+/* Copyright 2016 Brian P. Hinz
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+// -=- Modifiable generic pixel buffer class
+
+package com.tigervnc.rfb;
+
+import java.awt.image.*;
+import java.awt.Color;
+import java.awt.color.ColorSpace;
+import java.lang.*;
+import java.nio.*;
+import java.util.*;
+
+import static java.awt.image.DataBuffer.*;
+
+public abstract class ModifiablePixelBuffer extends PixelBuffer
+{
+
+  public ModifiablePixelBuffer(PixelFormat pf, int w, int h)
+  {
+    super(pf, w, h);
+  }
+
+  protected ModifiablePixelBuffer()
+  {
+  }
+
+  ///////////////////////////////////////////////
+  // 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.
+  public abstract WritableRaster getBufferRW(Rect r);
+  // 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().
+  public abstract void commitBufferRW(Rect r);
+
+  static LogWriter vlog = new LogWriter("ModifiablePixelBuffer");
+  ///////////////////////////////////////////////
+  // Basic rendering operations
+  // These operations DO NOT clip to the pixelbuffer area, or trap overruns.
+
+  // Fill a rectangle
+  public synchronized void fillRect(Rect r, byte[] pix)
+  {
+    WritableRaster buf;
+    int w, h;
+
+    w = r.width();
+    h = r.height();
+
+    if (h == 0 || w ==0)
+      return;
+
+    buf = getBufferRW(r);
+
+    ByteBuffer src =
+      ByteBuffer.allocate(r.area()*format.bpp/8).order(format.getByteOrder());
+    for (int i=0; i < r.area(); i++)
+      src.put(pix);
+    Raster raster = format.rasterFromBuffer(r, (ByteBuffer)src.rewind());
+    buf.setDataElements(0, 0, raster);
+
+    commitBufferRW(r);
+  }
+
+  // Copy pixel data to the buffer
+  public synchronized void imageRect(Rect r, byte[] pixels)
+  {
+    WritableRaster dest = getBufferRW(r);
+
+    ByteBuffer src = ByteBuffer.wrap(pixels).order(format.getByteOrder());
+    Raster raster = format.rasterFromBuffer(r, src);
+    dest.setDataElements(0, 0, raster);
+
+    commitBufferRW(r);
+  }
+
+  // Copy pixel data from one PixelBuffer location to another
+  public synchronized void copyRect(Rect rect,
+                                    Point move_by_delta)
+  {
+    Raster srcData;
+    WritableRaster dstData;
+
+    Rect drect, srect;
+
+    drect = new Rect(rect.tl, rect.br);
+    if (!drect.enclosed_by(getRect())) {
+      String msg = "Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d";
+      vlog.error(String.format(msg, drect.width(), drect.height(),
+                               drect.tl.x, drect.tl.y, width_, height_));
+      drect = drect.intersect(getRect());
+    }
+
+    if (drect.is_empty())
+      return;
+
+    srect = drect.translate(move_by_delta.negate());
+    if (!srect.enclosed_by(getRect())) {
+      String msg = "Source rect %dx%d at %d,%d exceeds framebuffer %dx%d";
+      vlog.error(String.format(msg, srect.width(), srect.height(),
+                               srect.tl.x, srect.tl.y, width_, height_));
+      srect = srect.intersect(getRect());
+      // Need to readjust the destination now that the area has changed
+      drect = srect.translate(move_by_delta);
+    }
+
+    if (srect.is_empty())
+      return;
+
+    srcData = getBuffer(srect);
+    dstData = getBufferRW(drect);
+
+    dstData.setDataElements(0, 0, srcData);
+
+    commitBufferRW(rect);
+  }
+
+  // Copy pixel data to the buffer through a mask
+  //   pixels is a pointer to the pixel to be copied to r.tl.
+  //   maskPos specifies the pixel offset in the mask to start from.
+  //   mask_ is a pointer to the mask bits at (0,0).
+  //   pStride and mStride are the strides of the pixel and mask buffers.
+  public synchronized void maskRect(Rect r,
+                                    Object pixels, byte[] mask_)
+  {
+    Rect cr = getRect().intersect(r);
+    if (cr.is_empty()) return;
+    WritableRaster data = getBufferRW(cr);
+
+    // FIXME
+    ColorModel cm = format.getColorModel();
+    SampleModel sm =
+      cm.createCompatibleSampleModel(r.width(), r.height());
+    DataBuffer db = null;
+    ByteBuffer src =
+      ByteBuffer.wrap((byte[])pixels).order(format.getByteOrder());
+    Buffer dst;
+    switch (sm.getTransferType()) {
+    case TYPE_INT:
+      dst = IntBuffer.allocate(src.remaining()).put(src.asIntBuffer());
+      db = new DataBufferInt(((IntBuffer)dst).array(), r.area());
+      break;
+    case TYPE_BYTE:
+      db = new DataBufferByte(src.array(), r.area());
+      break;
+    case TYPE_SHORT:
+      dst = ShortBuffer.allocate(src.remaining()).put(src.asShortBuffer());
+      db = new DataBufferShort(((ShortBuffer)dst).array(), r.area());
+      break;
+    }
+    assert(db != null);
+    Raster raster =
+      Raster.createRaster(sm, db, new java.awt.Point(0, 0));
+    ColorConvertOp converter = format.getColorConvertOp(cm.getColorSpace());
+    WritableRaster t = data.createCompatibleWritableRaster();
+    converter.filter(raster, t);
+
+    int w = cr.width();
+    int h = cr.height();
+
+    Point offset = new Point(cr.tl.x-r.tl.x, cr.tl.y-r.tl.y);
+
+    int maskBytesPerRow = (w + 7) / 8;
+
+    for (int y = 0; y < h; y++) {
+      int cy = offset.y + y;
+      for (int x = 0; x < w; x++) {
+        int cx = offset.x + x;
+        int byte_ = cy * maskBytesPerRow + y / 8;
+        int bit = 7 - cx % 8;
+
+        if ((mask_[byte_] & (1 << bit)) != 0)
+          data.setDataElements(x+cx, y+cy, t.getDataElements(x+cx, y+cy, null));
+      }
+    }
+
+    commitBufferRW(r);
+  }
+
+  //   pixel is the Pixel value to be used where mask_ is set
+  public synchronized void maskRect(Rect r, int pixel, byte[] mask)
+  {
+    // FIXME
+  }
+
+  // Render in a specific format
+  //   Does the exact same thing as the above methods, but the given
+  //   pixel values are defined by the given PixelFormat. 
+  public synchronized void fillRect(PixelFormat pf, Rect dest, byte[] pix)
+  {
+    WritableRaster dstBuffer = getBufferRW(dest);
+
+    ColorModel cm = pf.getColorModel();
+    if (cm.isCompatibleRaster(dstBuffer) &&
+        cm.isCompatibleSampleModel(dstBuffer.getSampleModel())) {
+      fillRect(dest, pix);
+    } else {
+      ByteBuffer src =
+        ByteBuffer.allocate(dest.area()*pf.bpp/8).order(pf.getByteOrder());
+      for (int i=0; i < dest.area(); i++)
+        src.put(pix);
+      Raster raster = pf.rasterFromBuffer(dest, (ByteBuffer)src.rewind());
+      ColorConvertOp converter = format.getColorConvertOp(cm.getColorSpace());
+      converter.filter(raster, dstBuffer);
+    }
+
+    commitBufferRW(dest);
+  }
+
+  public synchronized void imageRect(PixelFormat pf, Rect dest, byte[] pixels)
+  {
+    WritableRaster dstBuffer = getBufferRW(dest);
+
+    ColorModel cm = pf.getColorModel();
+    if (cm.isCompatibleRaster(dstBuffer) &&
+        cm.isCompatibleSampleModel(dstBuffer.getSampleModel())) {
+      imageRect(dest, pixels);
+    } else {
+      ByteBuffer src = ByteBuffer.wrap(pixels).order(pf.getByteOrder());
+      Raster raster = pf.rasterFromBuffer(dest, src);
+      ColorConvertOp converter = format.getColorConvertOp(cm.getColorSpace());
+      converter.filter(raster, dstBuffer);
+    }
+
+    commitBufferRW(dest);
+  }
+
+  public synchronized void imageRect(PixelFormat pf, Rect dest, Raster pixels)
+  {
+    WritableRaster dstBuffer = getBufferRW(dest);
+
+    ColorModel cm = pf.getColorModel();
+    if (cm.isCompatibleRaster(dstBuffer) &&
+        cm.isCompatibleSampleModel(dstBuffer.getSampleModel())) {
+      dstBuffer.setDataElements(0, 0, pixels);
+    } else {
+      ColorConvertOp converter = format.getColorConvertOp(cm.getColorSpace());
+      converter.filter(pixels, dstBuffer);
+    }
+
+    commitBufferRW(dest);
+  }
+
+}
diff --git a/java/com/tigervnc/rfb/PixelBuffer.java b/java/com/tigervnc/rfb/PixelBuffer.java
index a46667d..1b7d2c1 100644
--- a/java/com/tigervnc/rfb/PixelBuffer.java
+++ b/java/com/tigervnc/rfb/PixelBuffer.java
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2016 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,117 +17,67 @@
  * USA.
  */
 
-//
-// PixelBuffer - note that this code is only written for the 8, 16, and 32 bpp cases at the
-// moment.
-//
+// -=- Generic pixel buffer class
 
 package com.tigervnc.rfb;
 
 import java.awt.image.*;
+import java.awt.Color;
+import java.nio.*;
+import java.util.concurrent.atomic.*;
 
-public class PixelBuffer {
+public abstract class PixelBuffer {
 
-  public PixelBuffer() {
-    setPF(new PixelFormat());
-  }
-
-  public void setPF(PixelFormat pf) {
-    if (!(pf.bpp == 32) && !(pf.bpp == 16) && !(pf.bpp == 8))
-      throw new Exception("Internal error: bpp must be 8, 16, or 32 in PixelBuffer ("+pf.bpp+")");
+  public PixelBuffer(PixelFormat pf, int w, int h) {
     format = pf;
-    switch (pf.depth) {
-    case  3:
-      // Fall-through to depth 8
-    case  6:
-      // Fall-through to depth 8
-    case  8:
-      if (!pf.trueColour) {
-        if (cm == null)
-          cm = new IndexColorModel(8, 256, new byte[256], new byte[256], new byte[256]);
-        break;
-      }
-      int rmask = pf.redMax << pf.redShift;
-      int gmask = pf.greenMax << pf.greenShift;
-      int bmask = pf.blueMax << pf.blueShift;
-      cm = new DirectColorModel(8, rmask, gmask, bmask);
-      break;
-    case 16:
-      cm = new DirectColorModel(32, 0xF800, 0x07C0, 0x003E);
-      break;
-    case 24:
-      cm = new DirectColorModel(32, (0xff << 16), (0xff << 8), 0xff);
-      break;
-    case 32:
-      cm = new DirectColorModel(32, (0xff << pf.redShift),
-        (0xff << pf.greenShift), (0xff << pf.blueShift));
-      break;
-    default:
-      throw new Exception("Unsupported color depth ("+pf.depth+")");
-    }
+    width_ = w;
+    height_= h;
   }
-  public PixelFormat getPF() { return format; }
 
+  protected PixelBuffer() { width_ = 0; height_ = 0; }
+
+  // Get pixel format
+  public final PixelFormat getPF() { return format; }
+
+  // Get width, height and number of pixels
   public final int width() { return width_; }
   public final int height() { return height_; }
   public final int area() { return width_ * height_; }
 
-  public void fillRect(int x, int y, int w, int h, int pix) {
-    for (int ry = y; ry < y + h; ry++)
-      for (int rx = x; rx < x + w; rx++)
-        data[ry * width_ + rx] = pix;
+  // Get rectangle encompassing this buffer
+  //   Top-left of rectangle is either at (0,0), or the specified point.
+  public final Rect getRect() { return new Rect(0, 0, width_, height_); }
+  public final Rect getRect(Point pos) {
+    return new Rect(pos, pos.translate(new Point(width_, height_)));
   }
 
-  public void imageRect(int x, int y, int w, int h, int[] pix) {
-    for (int j = 0; j < h; j++)
-      System.arraycopy(pix, (w * j), data, width_ * (y + j) + x, w);
-  }
+  ///////////////////////////////////////////////
+  // Access to pixel data
+  //
 
-  public void copyRect(int x, int y, int w, int h, int srcX, int srcY) {
-    int dest = (width_ * y) + x;
-    int src = (width_ * srcY) + srcX;
-    int inc = width_;
+  // Get a pointer into the buffer
+  //   The pointer is to the top-left pixel of the specified Rect.
+  public abstract Raster getBuffer(Rect r);
 
-    if (y > srcY) {
-      src += (h-1) * inc;
-      dest += (h-1) * inc;
-      inc = -inc;
-    }
-    int destEnd = dest + h * inc;
+  // Get pixel data for a given part of the buffer
+  //   Data is copied into the supplied buffer, with the specified
+  //   stride. Try to avoid using this though as getBuffer() will in
+  //   most cases avoid the extra memory copy.
+  //void getImage(void* imageBuf, const Rect& r, int stride=0) const;
+  // Get pixel data in a given format
+  //   Works just the same as getImage(), but guaranteed to be in a
+  //   specific format.
+  //void getImage(const PixelFormat& pf, void* imageBuf,
+  //                const Rect& r, int stride=0) const;
 
-    while (dest != destEnd) {
-      System.arraycopy(data, src, data, dest, w);
-      src += inc;
-      dest += inc;
-    }
-  }
+  ///////////////////////////////////////////////
+  // Framebuffer update methods
+  //
 
-  public void maskRect(int x, int y, int w, int h, int[] pix, byte[] mask) {
-    int maskBytesPerRow = (w + 7) / 8;
-
-    for (int j = 0; j < h; j++) {
-      int cy = y + j;
-
-      if (cy < 0 || cy >= height_)
-        continue;
-
-      for (int i = 0; i < w; i++) {
-        int cx = x + i;
-
-        if (cx < 0 || cx >= width_)
-          continue;
-
-        int byte_ = j * maskBytesPerRow + i / 8;
-        int bit = 7 - i % 8;
-
-        if ((mask[byte_] & (1 << bit)) != 0)
-         data[cy * width_ + cx] = pix[j * w + i];
-      }
-    }
-  }
-
-  public int[] data;
-  public ColorModel cm;
+  // Ensure that the specified rectangle of buffer is up to date.
+  //   Overridden by derived classes implementing framebuffer access
+  //   to copy the required display data into place.
+  //public abstract void grabRegion(Region& region) {}
 
   protected PixelFormat format;
   protected int width_, height_;
diff --git a/java/com/tigervnc/rfb/PixelFormat.java b/java/com/tigervnc/rfb/PixelFormat.java
index c4d6870..9a26999 100644
--- a/java/com/tigervnc/rfb/PixelFormat.java
+++ b/java/com/tigervnc/rfb/PixelFormat.java
@@ -25,40 +25,80 @@
 
 package com.tigervnc.rfb;
 
+import java.awt.color.*;
+import java.awt.image.*;
+import java.nio.*;
+import java.util.*;
+
 import com.tigervnc.rdr.*;
-import java.awt.image.ColorModel;
 
 public class PixelFormat {
 
-  public PixelFormat(int b, int d, boolean e, boolean t) {
-    bpp = b;
-    depth = d;
-    bigEndian = e;
-    trueColour = t;
-  }
   public PixelFormat(int b, int d, boolean e, boolean t,
-                     int rm, int gm, int bm, int rs, int gs, int bs) {
-    this(b, d, e, t);
-    redMax = rm;
-    greenMax = gm;
-    blueMax = bm;
-    redShift = rs;
-    greenShift = gs;
-    blueShift = bs;
-  }
-  public PixelFormat() { this(8,8,false,true,7,7,3,0,3,6); }
+                     int rm, int gm, int bm, int rs, int gs, int bs)
+  {
+    bpp = b; depth = d; trueColour = t; bigEndian = e;
+    redMax = rm; greenMax = gm; blueMax = bm;
+    redShift = rs; greenShift = gs; blueShift = bs;
+    converters = new HashMap<Integer, ColorConvertOp>();
+    assert(isSane());
 
-  public boolean equal(PixelFormat x) {
-    return (bpp == x.bpp &&
-            depth == x.depth &&
-            (bigEndian == x.bigEndian || bpp == 8) &&
-            trueColour == x.trueColour &&
-            (!trueColour || (redMax == x.redMax &&
-                             greenMax == x.greenMax &&
-                             blueMax == x.blueMax &&
-                             redShift == x.redShift &&
-                             greenShift == x.greenShift &&
-                             blueShift == x.blueShift)));
+    updateState();
+  }
+
+  public PixelFormat()
+  {
+    this(8, 8, false, true, 7, 7, 3, 0, 3, 6);
+    updateState();
+  }
+
+  public boolean equal(PixelFormat other)
+  {
+    if (bpp != other.bpp || depth != other.depth)
+      return false;
+
+    if (redMax != other.redMax)
+      return false;
+    if (greenMax != other.greenMax)
+      return false;
+    if (blueMax != other.blueMax)
+      return false;
+
+    // Endianness requires more care to determine compatibility
+    if (bigEndian == other.bigEndian || bpp == 8) {
+      if (redShift != other.redShift)
+        return false;
+      if (greenShift != other.greenShift)
+        return false;
+      if (blueShift != other.blueShift)
+        return false;
+    } else {
+      // Has to be the same byte for each channel
+      if (redShift/8 != (3 - other.redShift/8))
+        return false;
+      if (greenShift/8 != (3 - other.greenShift/8))
+        return false;
+      if (blueShift/8 != (3 - other.blueShift/8))
+        return false;
+
+      // And the same bit offset within the byte
+      if (redShift%8 != other.redShift%8)
+        return false;
+      if (greenShift%8 != other.greenShift%8)
+        return false;
+      if (blueShift%8 != other.blueShift%8)
+        return false;
+
+      // And not cross a byte boundary
+      if (redShift/8 != (redShift + redBits - 1)/8)
+        return false;
+      if (greenShift/8 != (greenShift + greenBits - 1)/8)
+        return false;
+      if (blueShift/8 != (blueShift + blueBits - 1)/8)
+        return false;
+    }
+
+    return true;
   }
 
   public void read(InStream is) {
@@ -73,6 +113,23 @@
     greenShift = is.readU8();
     blueShift = is.readU8();
     is.skip(3);
+
+    // We have no real support for colour maps. If the client
+    // wants one, then we force a 8-bit true colour format and
+    // pretend it's a colour map.
+    if (!trueColour) {
+      redMax = 7;
+      greenMax = 7;
+      blueMax = 3;
+      redShift = 0;
+      greenShift = 3;
+      blueShift = 6;
+    }
+
+    if (!isSane())
+      throw new Exception("invalid pixel format: "+print());
+
+    updateState();
   }
 
   public void write(OutStream os) {
@@ -89,6 +146,14 @@
     os.pad(3);
   }
 
+  public final boolean isBigEndian() {
+    return bigEndian;
+  }
+
+  public final boolean isLittleEndian() {
+    return ! bigEndian;
+  }
+
   public final boolean is888() {
     if(!trueColour)
       return false;
@@ -139,53 +204,140 @@
     return 0;
   }
 
-  public void bufferFromRGB(int[] dst, int dstPtr, byte[] src,
-                            int srcPtr, int pixels) {
+  public void bufferFromRGB(ByteBuffer dst, ByteBuffer src, int pixels)
+  {
+    bufferFromRGB(dst, src, pixels, pixels, 1);
+  }
+
+  public void bufferFromRGB(ByteBuffer dst, ByteBuffer src,
+                            int w, int stride, int h)
+  {
     if (is888()) {
       // Optimised common case
-      int r, g, b;
+      int r, g, b, x;
 
-      for (int i=srcPtr; i < pixels; i++) {
-        if (bigEndian) {
-          r = (src[3*i+0] & 0xff) << (24 - redShift);
-          g = (src[3*i+1] & 0xff) << (24 - greenShift);
-          b = (src[3*i+2] & 0xff) << (24 - blueShift);
-          dst[dstPtr+i] = r | g | b | 0xff;
-        } else {
-          r = (src[3*i+0] & 0xff) << redShift;
-          g = (src[3*i+1] & 0xff) << greenShift;
-          b = (src[3*i+2] & 0xff) << blueShift;
-          dst[dstPtr+i] = (0xff << 24) | r | g | b;
+      if (bigEndian) {
+        r = dst.position() + (24 - redShift)/8;
+        g = dst.position() + (24 - greenShift)/8;
+        b = dst.position() + (24 - blueShift)/8;
+        x = dst.position() + (24 - (48 - redShift - greenShift - blueShift))/8;
+      } else {
+        r = dst.position() + redShift/8;
+        g = dst.position() + greenShift/8;
+        b = dst.position() + blueShift/8;
+        x = dst.position() + (48 - redShift - greenShift - blueShift)/8;
+      }
+
+      int dstPad = (stride - w) * 4;
+      while (h-- > 0) {
+        int w_ = w;
+        while (w_-- > 0) {
+          dst.put(r, src.get());
+          dst.put(g, src.get());
+          dst.put(b, src.get());
+          dst.put(x, (byte)0);
+          r += 4;
+          g += 4;
+          b += 4;
+          x += 4;
         }
+        r += dstPad;
+        g += dstPad;
+        b += dstPad;
+        x += dstPad;
       }
     } else {
       // Generic code
-      int p, r, g, b;
-      int[] rgb = new int[4];
+      int dstPad = (stride - w) * bpp/8;
+      while (h-- > 0) {
+        int w_ = w;
+        while (w_-- > 0) {
+          int p;
+          int r, g, b;
 
-      int i = srcPtr; int j = dstPtr;
-      while (i < pixels) {
-        r = src[i++] & 0xff;
-        g = src[i++] & 0xff;
-        b = src[i++] & 0xff;
+          r = src.get();
+          g = src.get();
+          b = src.get();
 
-        //p = pixelFromRGB(r, g, b, cm);
-        p = ColorModel.getRGBdefault().getDataElement(new int[] {0xff, r, g, b}, 0);
+          p = pixelFromRGB(r, g, b, model);
 
-        bufferFromPixel(dst, j, p);
-        j += bpp/8;
+          bufferFromPixel(dst, p);
+          dst.position(dst.position() + bpp/8);
+        }
+        dst.position(dst.position() + dstPad);
       }
     }
   }
 
-  public void rgbFromBuffer(byte[] dst, int dstPtr, byte[] src, int srcPtr, int pixels, ColorModel cm)
+  public void rgbFromBuffer(ByteBuffer dst, ByteBuffer src, int pixels)
+  {
+    rgbFromBuffer(dst, src, pixels, pixels, 1);
+  }
+
+  public void rgbFromBuffer(ByteBuffer dst, ByteBuffer src,
+                            int w, int stride, int h)
+  {
+    if (is888()) {
+      // Optimised common case
+      int r, g, b;
+
+      if (bigEndian) {
+        r = src.position() + (24 - redShift)/8;
+        g = src.position() + (24 - greenShift)/8;
+        b = src.position() + (24 - blueShift)/8;
+      } else {
+        r = src.position() + redShift/8;
+        g = src.position() + greenShift/8;
+        b = src.position() + blueShift/8;
+      }
+
+      int srcPad = (stride - w) * 4;
+      while (h-- > 0) {
+        int w_ = w;
+        while (w_-- > 0) {
+          dst.put(src.get(r));
+          dst.put(src.get(g));
+          dst.put(src.get(b));
+          r += 4;
+          g += 4;
+          b += 4;
+        }
+        r += srcPad;
+        g += srcPad;
+        b += srcPad;
+      }
+    } else {
+      // Generic code
+      int srcPad = (stride - w) * bpp/8;
+      while (h-- > 0) {
+        int w_ = w;
+        while (w_-- > 0) {
+          int p;
+          byte r, g, b;
+
+          p = pixelFromBuffer(src.duplicate());
+
+          r = (byte)getColorModel().getRed(p);
+          g = (byte)getColorModel().getGreen(p);
+          b = (byte)getColorModel().getBlue(p);
+
+          dst.put(r);
+          dst.put(g);
+          dst.put(b);
+          src.position(src.position() + bpp/8);
+        }
+        src.reset().position(src.position() + srcPad).mark();
+      }
+    }
+  }
+
+  public void rgbFromPixels(byte[] dst, int dstPtr, int[] src, int srcPtr, int pixels, ColorModel cm)
   {
     int p;
     byte r, g, b;
 
     for (int i=0; i < pixels; i++) {
-      p = pixelFromBuffer(src, srcPtr);
-      srcPtr += bpp/8;
+      p = src[i];
 
       dst[dstPtr++] = (byte)cm.getRed(p);
       dst[dstPtr++] = (byte)cm.getGreen(p);
@@ -193,31 +345,29 @@
     }
   }
 
-  public int pixelFromBuffer(byte[] buffer, int bufferPtr)
+  public int pixelFromBuffer(ByteBuffer buffer)
   {
     int p;
 
-    p = 0;
+    p = 0xff000000;
 
-    if (bigEndian) {
+    if (!bigEndian) {
       switch (bpp) {
       case 32:
-        p = (buffer[0] & 0xff) << 24 | (buffer[1] & 0xff) << 16 | (buffer[2] & 0xff) << 8 | 0xff;
-        break;
+        p |= buffer.get() << 24;
+        p |= buffer.get() << 16;
       case 16:
-        p = (buffer[0] & 0xff) << 8 | (buffer[1] & 0xff);
-        break;
+        p |= buffer.get() << 8;
       case 8:
-        p = (buffer[0] & 0xff);
-        break;
+        p |= buffer.get();
       }
     } else {
-      p = (buffer[0] & 0xff);
+      p |= buffer.get(0);
       if (bpp >= 16) {
-        p |= (buffer[1] & 0xff) << 8;
+        p |= buffer.get(1) << 8;
         if (bpp == 32) {
-          p |= (buffer[2] & 0xff) << 16;
-          p |= (buffer[3] & 0xff) << 24;
+          p |= buffer.get(2) << 16;
+          p |= buffer.get(3) << 24;
         }
       }
     }
@@ -263,33 +413,212 @@
     return s.toString();
   }
 
-  public void bufferFromPixel(int[] buffer, int bufPtr, int p)
+  private static int bits(int value)
+  {
+    int bits;
+
+    bits = 16;
+
+    if ((value & 0xff00) == 0) {
+      bits -= 8;
+      value <<= 8;
+    }
+    if ((value & 0xf000) == 0) {
+      bits -= 4;
+      value <<= 4;
+    }
+    if ((value & 0xc000) == 0) {
+      bits -= 2;
+      value <<= 2;
+    }
+    if ((value & 0x8000) == 0) {
+      bits -= 1;
+      value <<= 1;
+    }
+
+    return bits;
+  }
+
+  private void updateState()
+  {
+    int endianTest = 1;
+
+    redBits = bits(redMax);
+    greenBits = bits(greenMax);
+    blueBits = bits(blueMax);
+
+    maxBits = redBits;
+    if (greenBits > maxBits)
+      maxBits = greenBits;
+    if (blueBits > maxBits)
+      maxBits = blueBits;
+
+    minBits = redBits;
+    if (greenBits < minBits)
+      minBits = greenBits;
+    if (blueBits < minBits)
+      minBits = blueBits;
+
+    if ((((char)endianTest) == 0) != bigEndian)
+      endianMismatch = true;
+    else
+      endianMismatch = false;
+
+    model = getColorModel(this);
+  }
+
+  private boolean isSane()
+  {
+    int totalBits;
+
+    if ((bpp != 8) && (bpp != 16) && (bpp != 32))
+      return false;
+    if (depth > bpp)
+      return false;
+
+    if (!trueColour && (depth != 8))
+      return false;
+
+    if ((redMax & (redMax + 1)) != 0)
+      return false;
+    if ((greenMax & (greenMax + 1)) != 0)
+      return false;
+    if ((blueMax & (blueMax + 1)) != 0)
+      return false;
+
+    /*
+     * We don't allow individual channels > 8 bits in order to keep our
+     * conversions simple.
+     */
+    if (redMax >= (1 << 8))
+      return false;
+    if (greenMax >= (1 << 8))
+      return false;
+    if (blueMax >= (1 << 8))
+      return false;
+
+    totalBits = bits(redMax) + bits(greenMax) + bits(blueMax);
+    if (totalBits > bpp)
+      return false;
+
+    if (((redMax << redShift) & (greenMax << greenShift)) != 0)
+      return false;
+    if (((redMax << redShift) & (blueMax << blueShift)) != 0)
+      return false;
+    if (((greenMax << greenShift) & (blueMax << blueShift)) != 0)
+      return false;
+
+    return true;
+  }
+
+  public void bufferFromPixel(ByteBuffer buffer, int p)
   {
     if (bigEndian) {
       switch (bpp) {
         case 32:
-          buffer[bufPtr++] = (p >> 24) & 0xff;
-          buffer[bufPtr++] = (p >> 16) & 0xff;
+          buffer.put((byte)((p >> 24) & 0xff));
+          buffer.put((byte)((p >> 16) & 0xff));
           break;
         case 16:
-          buffer[bufPtr++] = (p >> 8) & 0xff;
+          buffer.put((byte)((p >> 8) & 0xff));
           break;
         case 8:
-          buffer[bufPtr++] = (p >> 0) & 0xff;
+          buffer.put((byte)((p >> 0) & 0xff));
           break;
       }
     } else {
-      buffer[0] = (p >> 0) & 0xff;
+      buffer.put(0, (byte)((p >> 0) & 0xff));
       if (bpp >= 16) {
-        buffer[1] = (p >> 8) & 0xff;
+        buffer.put(1, (byte)((p >> 8) & 0xff));
         if (bpp == 32) {
-          buffer[2] = (p >> 16) & 0xff;
-          buffer[3] = (p >> 24) & 0xff;
+          buffer.put(2, (byte)((p >> 16) & 0xff));
+          buffer.put(3, (byte)((p >> 24) & 0xff));
         }
       }
     }
   }
 
+  public ColorModel getColorModel()
+  {
+    return model;
+  }
+
+  public static ColorModel getColorModel(PixelFormat pf) {
+    if (!(pf.bpp == 32) && !(pf.bpp == 16) && !(pf.bpp == 8))
+      throw new Exception("Internal error: bpp must be 8, 16, or 32 in PixelBuffer ("+pf.bpp+")");
+    ColorModel cm;
+    switch (pf.depth) {
+    case  3:
+      // Fall-through to depth 8
+    case  6:
+      // Fall-through to depth 8
+    case  8:
+      int rmask = pf.redMax << pf.redShift;
+      int gmask = pf.greenMax << pf.greenShift;
+      int bmask = pf.blueMax << pf.blueShift;
+      cm = new DirectColorModel(8, rmask, gmask, bmask);
+      break;
+    case 16:
+      cm = new DirectColorModel(32, 0xF800, 0x07C0, 0x003E);
+      break;
+    case 24:
+      cm = new DirectColorModel(32, (0xff << 16), (0xff << 8), 0xff);
+      break;
+    case 32:
+      cm = new DirectColorModel(32, (0xff << pf.redShift),
+        (0xff << pf.greenShift), (0xff << pf.blueShift));
+      break;
+    default:
+      throw new Exception("Unsupported color depth ("+pf.depth+")");
+    }
+    assert(cm != null);
+    return cm;
+  }
+
+  public ColorConvertOp getColorConvertOp(ColorSpace src)
+  {
+    // The overhead associated with initializing ColorConvertOps is
+    // enough to justify maintaining a static lookup table.
+    if (converters.containsKey(src.getType()))
+      return converters.get(src.getType());
+    ColorSpace dst = model.getColorSpace();
+    converters.put(src.getType(), new ColorConvertOp(src, dst, null));
+    return converters.get(src.getType());
+  }
+
+  public ByteOrder getByteOrder()
+  {
+    if (isBigEndian())
+      return ByteOrder.BIG_ENDIAN;
+    else
+      return ByteOrder.LITTLE_ENDIAN;
+  }
+
+  public Raster rasterFromBuffer(Rect r, ByteBuffer buf)
+  {
+    Buffer dst;
+    DataBuffer db = null;
+
+    SampleModel sm =
+      model.createCompatibleSampleModel(r.width(), r.height());
+    switch (sm.getTransferType()) {
+    case DataBuffer.TYPE_INT:
+      dst = IntBuffer.allocate(r.area()).put(buf.asIntBuffer());
+      db = new DataBufferInt(((IntBuffer)dst).array(), r.area());
+      break;
+    case DataBuffer.TYPE_BYTE:
+      db = new DataBufferByte(buf.array(), r.area());
+      break;
+    case DataBuffer.TYPE_SHORT:
+      dst = ShortBuffer.allocate(r.area()).put(buf.asShortBuffer());
+      db = new DataBufferShort(((ShortBuffer)dst).array(), r.area());
+      break;
+    }
+    assert(db != null);
+    return Raster.createRaster(sm, db, new java.awt.Point(0, 0));
+  }
+
+  private static HashMap<Integer, ColorConvertOp> converters;
 
   public int bpp;
   public int depth;
@@ -301,4 +630,10 @@
   public int redShift;
   public int greenShift;
   public int blueShift;
+
+  protected int redBits, greenBits, blueBits;
+  protected int maxBits, minBits;
+  protected boolean endianMismatch;
+
+  private ColorModel model;
 }
diff --git a/java/com/tigervnc/rfb/RREDecoder.java b/java/com/tigervnc/rfb/RREDecoder.java
index 487aa3d..c73c7a9 100644
--- a/java/com/tigervnc/rfb/RREDecoder.java
+++ b/java/com/tigervnc/rfb/RREDecoder.java
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2016 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,30 +19,90 @@
 
 package com.tigervnc.rfb;
 
+import java.nio.*;
+
 import com.tigervnc.rdr.*;
 
 public class RREDecoder extends Decoder {
 
-  public RREDecoder(CMsgReader reader_) { reader = reader_; }
+  public RREDecoder() { super(DecoderFlags.DecoderPlain); }
 
-  public void readRect(Rect r, CMsgHandler handler) {
-    InStream is = reader.getInStream();
-    int bytesPerPixel = handler.cp.pf().bpp / 8;
-    boolean bigEndian = handler.cp.pf().bigEndian;
+  public void readRect(Rect r, InStream is,
+                       ConnParams cp, OutStream os)
+  {
+    int numRects;
+
+    numRects = is.readU32();
+    os.writeU32(numRects);
+
+    os.copyBytes(is, cp.pf().bpp/8 + numRects * (cp.pf().bpp/8 + 8));
+  }
+
+  public void decodeRect(Rect r, Object buffer,
+                         int buflen, ConnParams cp,
+                         ModifiablePixelBuffer pb)
+  {
+    MemInStream is = new MemInStream((byte[])buffer, 0, buflen);
+    PixelFormat pf = cp.pf();
+    switch (pf.bpp) {
+    case 8:  rreDecode8 (r, is, pf, pb); break;
+    case 16: rreDecode16(r, is, pf, pb); break;
+    case 32: rreDecode32(r, is, pf, pb); break;
+    }
+  }
+
+  private static ByteBuffer READ_PIXEL(InStream is, PixelFormat pf) {
+    ByteBuffer b = ByteBuffer.allocate(4);
+    switch (pf.bpp) {
+    case 8:
+      b.putInt(is.readOpaque8());
+      return ByteBuffer.allocate(1).put(b.get(3));
+    case 16:
+      b.putInt(is.readOpaque16());
+      return ByteBuffer.allocate(2).put(b.array(), 2, 2);
+    case 32:
+    default:
+      b.putInt(is.readOpaque32());
+      return b;
+    }
+  }
+
+  private void RRE_DECODE(Rect r, InStream is,
+                          PixelFormat pf, ModifiablePixelBuffer pb)
+  {
     int nSubrects = is.readU32();
-    int bg = is.readPixel(bytesPerPixel, bigEndian);
-    handler.fillRect(r, bg);
+    byte[] bg = READ_PIXEL(is, pf).array();
+    pb.fillRect(pf, r, bg);
 
     for (int i = 0; i < nSubrects; i++) {
-      int pix = is.readPixel(bytesPerPixel, bigEndian);
+      byte[] pix = READ_PIXEL(is, pf).array();
       int x = is.readU16();
       int y = is.readU16();
       int w = is.readU16();
       int h = is.readU16();
-      handler.fillRect(new Rect(r.tl.x + x, r.tl.y + y,
-                                r.tl.x + x + w, r.tl.y + y + h), pix);
+      pb.fillRect(pf, new Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix);
     }
   }
 
-  CMsgReader reader;
+  private void rreDecode8(Rect r, InStream is,
+                          PixelFormat pf,
+                          ModifiablePixelBuffer pb)
+  {
+    RRE_DECODE(r, is, pf, pb);
+  }
+
+  private void rreDecode16(Rect r, InStream is,
+                           PixelFormat pf,
+                           ModifiablePixelBuffer pb)
+  {
+    RRE_DECODE(r, is, pf, pb);
+  }
+
+  private void rreDecode32(Rect r, InStream is,
+                           PixelFormat pf,
+                           ModifiablePixelBuffer pb)
+  {
+    RRE_DECODE(r, is, pf, pb);
+  }
+
 }
diff --git a/java/com/tigervnc/rfb/RawDecoder.java b/java/com/tigervnc/rfb/RawDecoder.java
index b2219a2..71b7960 100644
--- a/java/com/tigervnc/rfb/RawDecoder.java
+++ b/java/com/tigervnc/rfb/RawDecoder.java
@@ -18,28 +18,25 @@
 
 package com.tigervnc.rfb;
 
+import com.tigervnc.rdr.*;
+
 public class RawDecoder extends Decoder {
 
-  public RawDecoder(CMsgReader reader_) { reader = reader_; }
+  public RawDecoder() { super(DecoderFlags.DecoderPlain); }
 
-  public void readRect(Rect r, CMsgHandler handler) {
-    int x = r.tl.x;
-    int y = r.tl.y;
-    int w = r.width();
-    int h = r.height();
-    int[] imageBuf = new int[w*h];
-    int nPixels = imageBuf.length;
-    int bytesPerRow = w * (reader.bpp() / 8);
-    while (h > 0) {
-      int nRows = nPixels / w;
-      if (nRows > h) nRows = h;
-      reader.getInStream().readPixels(imageBuf, nPixels, (reader.bpp() / 8), handler.cp.pf().bigEndian);
-      handler.imageRect(new Rect(x, y, x+w, y+nRows), imageBuf);
-      h -= nRows;
-      y += nRows;
-    }
+  public void readRect(Rect r, InStream is,
+                       ConnParams cp, OutStream os)
+  {
+    os.copyBytes(is, r.area() * cp.pf().bpp/8);
   }
 
-  CMsgReader reader;
   static LogWriter vlog = new LogWriter("RawDecoder");
+  public void decodeRect(Rect r, Object buffer,
+                         int buflen, ConnParams cp,
+                         ModifiablePixelBuffer pb)
+  {
+    assert(buflen >= r.area() * cp.pf().bpp/8);
+    pb.imageRect(cp.pf(), r, (byte[])buffer);
+  }
+
 }
diff --git a/java/com/tigervnc/rfb/Region.java b/java/com/tigervnc/rfb/Region.java
new file mode 100644
index 0000000..f7da91d
--- /dev/null
+++ b/java/com/tigervnc/rfb/Region.java
@@ -0,0 +1,102 @@
+/* Copyright (C) 2016 Brian P. Hinz.  All Rights Reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+package com.tigervnc.rfb;
+
+import java.awt.*;
+import java.awt.geom.*;
+
+public class Region extends Area {
+
+  // Create an empty region
+  public Region() {
+    super();
+  }
+
+  // Create a rectangular region
+  public Region(Rect r) {
+    super(new Rectangle(r.tl.x, r.tl.y, r.width(), r.height()));
+  }
+
+  public Region(Region r) {
+    super(r);
+    //intersect(r);
+  }
+
+  public void clear() { reset(); }
+
+  public void reset(Rect r) {
+    if (r.is_empty()) {
+      clear();
+    } else {
+      clear();
+      assign_union(new Region(r));
+      /*
+      xrgn.numRects = 1;
+      xrgn.rects[0].x1 = xrgn.extents.x1 = r.tl.x;
+      xrgn.rects[0].y1 = xrgn.extents.y1 = r.tl.y;
+      xrgn.rects[0].x2 = xrgn.extents.x2 = r.br.x;
+      xrgn.rects[0].y2 = xrgn.extents.y2 = r.br.y;
+      */
+    }
+  }
+
+  public void translate(Point delta) {
+    AffineTransform t = 
+      AffineTransform.getTranslateInstance((double)delta.x, (double)delta.y);
+    transform(t);
+  }
+
+  public void assign_intersect(Region r) {
+    intersect(r);
+  }
+
+  public void assign_union(Region r) {
+    add(r);
+  }
+
+  public void assign_subtract(Region r) {
+    subtract(r);
+  }
+
+  public Region intersect(Region r) {
+    Region ret = new Region(this);
+    ((Area)ret).intersect(this);
+    return ret;
+  }
+
+  public Region union(Region r) {
+    Region ret = new Region(r);
+    ((Area)ret).add(this);
+    return ret;
+  }
+
+  public Region subtract(Region r) {
+    Region ret = new Region(this);
+    ((Area)ret).subtract(r);
+    return ret;
+  }
+
+  public boolean is_empty() { return isEmpty(); }
+
+  public Rect get_bounding_rect() {
+    Rectangle b = getBounds();
+    return new Rect((int)b.getX(), (int)b.getY(),
+                    (int)b.getWidth(), (int)b.getHeight());
+  }
+}
diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java
index b644cdb..aa468eb 100644
--- a/java/com/tigervnc/rfb/TightDecoder.java
+++ b/java/com/tigervnc/rfb/TightDecoder.java
@@ -22,56 +22,181 @@
 package com.tigervnc.rfb;
 
 import com.tigervnc.rdr.InStream;
+import com.tigervnc.rdr.MemInStream;
+import com.tigervnc.rdr.OutStream;
 import com.tigervnc.rdr.ZlibInStream;
 import java.util.ArrayList;
 import java.io.InputStream;
 import java.awt.image.*;
 import java.awt.*;
+import java.math.BigInteger;
+import java.io.*;
+import java.nio.*;
+import javax.imageio.*;
+import javax.imageio.stream.*;
 
 public class TightDecoder extends Decoder {
 
   final static int TIGHT_MAX_WIDTH = 2048;
+  final static int TIGHT_MIN_TO_COMPRESS = 12;
 
   // Compression control
-  final static int rfbTightExplicitFilter = 0x04;
-  final static int rfbTightFill = 0x08;
-  final static int rfbTightJpeg = 0x09;
-  final static int rfbTightMaxSubencoding = 0x09;
+  final static int tightExplicitFilter = 0x04;
+  final static int tightFill = 0x08;
+  final static int tightJpeg = 0x09;
+  final static int tightMaxSubencoding = 0x09;
 
   // Filters to improve compression efficiency
-  final static int rfbTightFilterCopy = 0x00;
-  final static int rfbTightFilterPalette = 0x01;
-  final static int rfbTightFilterGradient = 0x02;
-  final static int rfbTightMinToCompress = 12;
+  final static int tightFilterCopy = 0x00;
+  final static int tightFilterPalette = 0x01;
+  final static int tightFilterGradient = 0x02;
 
-  final static Toolkit tk = Toolkit.getDefaultToolkit();
-
-  public TightDecoder(CMsgReader reader_) {
-    reader = reader_;
+  public TightDecoder() {
+    super(DecoderFlags.DecoderPartiallyOrdered);
     zis = new ZlibInStream[4];
     for (int i = 0; i < 4; i++)
       zis[i] = new ZlibInStream();
   }
 
-  public void readRect(Rect r, CMsgHandler handler)
+  public void readRect(Rect r, InStream is,
+                       ConnParams cp, OutStream os)
   {
-    InStream is = reader.getInStream();
-    boolean cutZeros = false;
-    clientpf = handler.getPreferredPF();
-    serverpf = handler.cp.pf();
-    int bpp = serverpf.bpp;
-    cutZeros = false;
-    if (bpp == 32) {
-      if (serverpf.is888()) {
-        cutZeros = true;
+    int comp_ctl;
+
+    comp_ctl = is.readU8();
+    os.writeU8(comp_ctl);
+
+    comp_ctl >>= 4;
+
+    // "Fill" compression type.
+    if (comp_ctl == tightFill) {
+      if (cp.pf().is888())
+        os.copyBytes(is, 3);
+      else
+        os.copyBytes(is, cp.pf().bpp/8);
+      return;
+    }
+
+    // "JPEG" compression type.
+    if (comp_ctl == tightJpeg) {
+      int len;
+
+      len = readCompact(is);
+      os.writeOpaque32(len);
+      os.copyBytes(is, len);
+      return;
+    }
+
+    // Quit on unsupported compression type.
+    if (comp_ctl > tightMaxSubencoding)
+      throw new Exception("TightDecoder: bad subencoding value received");
+
+    // "Basic" compression type.
+
+    int palSize = 0;
+
+    if (r.width() > TIGHT_MAX_WIDTH)
+      throw new Exception("TightDecoder: too large rectangle ("+r.width()+" pixels)");
+
+    // Possible palette
+    if ((comp_ctl & tightExplicitFilter) != 0) {
+      int filterId;
+
+      filterId = is.readU8() & 0xff;
+      os.writeU8(filterId);
+
+      switch (filterId) {
+      case tightFilterPalette:
+        palSize = is.readU8() + 1;
+        os.writeU32(palSize - 1);
+
+        if (cp.pf().is888())
+          os.copyBytes(is, palSize * 3);
+        else
+          os.copyBytes(is, palSize * cp.pf().bpp/8);
+        break;
+      case tightFilterGradient:
+        if (cp.pf().bpp == 8)
+          throw new Exception("TightDecoder: invalid BPP for gradient filter");
+        break;
+      case tightFilterCopy:
+        break;
+      default:
+        throw new Exception("TightDecoder: unknown filter code received");
       }
     }
 
-    int comp_ctl = is.readU8();
+    int rowSize, dataSize;
 
-    boolean bigEndian = handler.cp.pf().bigEndian;
+    if (palSize != 0) {
+      if (palSize <= 2)
+        rowSize = (r.width() + 7) / 8;
+      else
+        rowSize = r.width();
+    } else if (cp.pf().is888()) {
+      rowSize = r.width() * 3;
+    } else {
+      rowSize = r.width() * cp.pf().bpp/8;
+    }
 
-    // Flush zlib streams if we are told by the server to do so.
+    dataSize = r.height() * rowSize;
+
+    if (dataSize < TIGHT_MIN_TO_COMPRESS) {
+      os.copyBytes(is, dataSize);
+    } else {
+      int len;
+
+      len = readCompact(is);
+      os.writeOpaque32(len);
+      os.copyBytes(is, len);
+    }
+  }
+
+  public boolean doRectsConflict(Rect rectA,
+                                 Object bufferA,
+                                 int buflenA,
+                                 Rect rectB,
+                                 Object bufferB,
+                                 int buflenB,
+                                 ConnParams cp)
+  {
+    byte comp_ctl_a, comp_ctl_b;
+
+    assert(buflenA >= 1);
+    assert(buflenB >= 1);
+
+    comp_ctl_a = ((byte[])bufferA)[0];
+    comp_ctl_b = ((byte[])bufferB)[0];
+
+    // Resets or use of zlib pose the same problem, so merge them
+    if ((comp_ctl_a & 0x80) == 0x00)
+      comp_ctl_a |= 1 << ((comp_ctl_a >> 4) & 0x03);
+    if ((comp_ctl_b & 0x80) == 0x00)
+      comp_ctl_b |= 1 << ((comp_ctl_b >> 4) & 0x03);
+
+    if (((comp_ctl_a & 0x0f) & (comp_ctl_b & 0x0f)) != 0)
+      return true;
+
+    return false;
+  }
+
+  public void decodeRect(Rect r, Object buffer,
+                         int buflen, ConnParams cp,
+                         ModifiablePixelBuffer pb)
+  {
+    ByteBuffer bufptr;
+    PixelFormat pf = cp.pf();
+
+    int comp_ctl;
+
+    bufptr = ByteBuffer.wrap((byte[])buffer);
+
+    assert(buflen >= 1);
+
+    comp_ctl = bufptr.get() & 0xff;
+    buflen -= 1;
+
+    // Reset zlib streams if we are told by the server to do so.
     for (int i = 0; i < 4; i++) {
       if ((comp_ctl & 1) != 0) {
         zis[i].reset();
@@ -80,190 +205,216 @@
     }
 
     // "Fill" compression type.
-    if (comp_ctl == rfbTightFill) {
-      int[] pix = new int[1];
-      if (cutZeros) {
-        byte[] bytebuf = new byte[3];
-        is.readBytes(bytebuf, 0, 3);
-        serverpf.bufferFromRGB(pix, 0, bytebuf, 0, 1);
+    if (comp_ctl == tightFill) {
+      if (pf.is888()) {
+        ByteBuffer pix = ByteBuffer.allocate(4);
+
+        assert(buflen >= 3);
+
+        pf.bufferFromRGB(pix, bufptr, 1);
+        pb.fillRect(pf, r, pix.array());
       } else {
-        pix[0] = is.readPixel(serverpf.bpp/8, serverpf.bigEndian);
+        assert(buflen >= pf.bpp/8);
+        byte[] pix = new byte[pf.bpp/8];
+        bufptr.get(pix);
+        pb.fillRect(pf, r, pix);
       }
-      handler.fillRect(r, pix[0]);
       return;
     }
 
     // "JPEG" compression type.
-    if (comp_ctl == rfbTightJpeg) {
-      DECOMPRESS_JPEG_RECT(r, is, handler);
+    if (comp_ctl == tightJpeg) {
+      int len;
+
+      WritableRaster buf;
+
+      JpegDecompressor jd = new JpegDecompressor();
+
+      assert(buflen >= 4);
+
+      len = bufptr.getInt();
+      buflen -= 4;
+
+      // We always use direct decoding with JPEG images
+      buf = pb.getBufferRW(r);
+      jd.decompress(bufptr, len, buf, r, pb.getPF());
+      pb.commitBufferRW(r);
       return;
     }
 
     // Quit on unsupported compression type.
-    if (comp_ctl > rfbTightMaxSubencoding) {
+    if (comp_ctl > tightMaxSubencoding)
       throw new Exception("TightDecoder: bad subencoding value received");
-    }
 
     // "Basic" compression type.
     int palSize = 0;
-    int[] palette = new int[256];
+    ByteBuffer palette = ByteBuffer.allocate(256 * 4);
     boolean useGradient = false;
 
-    if ((comp_ctl & rfbTightExplicitFilter) != 0) {
-      int filterId = is.readU8();
+    if ((comp_ctl & tightExplicitFilter) != 0) {
+      int filterId;
+
+      assert(buflen >= 1);
+
+      filterId = bufptr.get();
 
       switch (filterId) {
-      case rfbTightFilterPalette:
-        palSize = is.readU8() + 1;
-        byte[] tightPalette;
-        if (cutZeros) {
-          tightPalette = new byte[256 * 3];
-          is.readBytes(tightPalette, 0, palSize * 3);
-          serverpf.bufferFromRGB(palette, 0, tightPalette, 0, palSize);
+      case tightFilterPalette:
+        assert(buflen >= 1);
+
+        palSize = bufptr.getInt() + 1;
+        buflen -= 4;
+
+        if (pf.is888()) {
+          ByteBuffer tightPalette = ByteBuffer.allocate(palSize * 3);
+
+          assert(buflen >= tightPalette.capacity());
+
+          bufptr.get(tightPalette.array(), 0, tightPalette.capacity());
+          buflen -= tightPalette.capacity();
+
+          pf.bufferFromRGB(palette.duplicate(), tightPalette, palSize);
         } else {
-          is.readPixels(palette, palSize, serverpf.bpp/8, serverpf.bigEndian);
+          int len;
+
+          len = palSize * pf.bpp/8;
+
+          assert(buflen >= len);
+
+          bufptr.get(palette.array(), 0, len);
+          buflen -= len;
         }
         break;
-      case rfbTightFilterGradient:
+      case tightFilterGradient:
         useGradient = true;
         break;
-      case rfbTightFilterCopy:
+      case tightFilterCopy:
         break;
       default:
-        throw new Exception("TightDecoder: unknown filter code recieved");
+        assert(false);
       }
     }
 
-    int bppp = bpp;
-    if (palSize != 0) {
-      bppp = (palSize <= 2) ? 1 : 8;
-    } else if (cutZeros) {
-      bppp = 24;
-    }
-
     // Determine if the data should be decompressed or just copied.
-    int rowSize = (r.width() * bppp + 7) / 8;
-    int dataSize = r.height() * rowSize;
-    int streamId = -1;
-    InStream input;
-    if (dataSize < rfbTightMinToCompress) {
-      input = is;
+    int rowSize, dataSize;
+    byte[] netbuf;
+
+    if (palSize != 0) {
+      if (palSize <= 2)
+        rowSize = (r.width() + 7) / 8;
+      else
+        rowSize = r.width();
+    } else if (pf.is888()) {
+      rowSize = r.width() * 3;
     } else {
-      int length = is.readCompactLength();
-      streamId = comp_ctl & 0x03;
-      zis[streamId].setUnderlying(is, length);
-      input = (ZlibInStream)zis[streamId];
+      rowSize = r.width() * pf.bpp/8;
     }
 
-    // Allocate netbuf and read in data
-    byte[] netbuf = new byte[dataSize];
-    input.readBytes(netbuf, 0, dataSize);
+    dataSize = r.height() * rowSize;
 
+    if (dataSize < TIGHT_MIN_TO_COMPRESS) {
+      assert(buflen >= dataSize);
+    } else {
+      int len;
+      int streamId;
+      MemInStream ms;
+
+      assert(buflen >= 4);
+
+      len = bufptr.getInt();
+      buflen -= 4;
+
+      assert(buflen >= len);
+
+      streamId = comp_ctl & 0x03;
+      ms = new MemInStream(bufptr.array(), bufptr.position(), len);
+      zis[streamId].setUnderlying(ms, len);
+
+      // Allocate netbuf and read in data
+      netbuf = new byte[dataSize];
+
+      zis[streamId].readBytes(netbuf, 0, dataSize);
+
+      zis[streamId].removeUnderlying();
+      ms = null;
+
+      bufptr = ByteBuffer.wrap(netbuf);
+      buflen = dataSize;
+    }
+
+    ByteBuffer outbuf = ByteBuffer.allocate(r.area() * pf.bpp/8);
     int stride = r.width();
-    int[] buf = reader.getImageBuf(r.area());
 
     if (palSize == 0) {
       // Truecolor data.
       if (useGradient) {
-        if (bpp == 32 && cutZeros) {
-          FilterGradient24(netbuf, buf, stride, r);
+        if (pf.is888()) {
+          FilterGradient24(bufptr, pf, outbuf, stride, r);
         } else {
-          FilterGradient(netbuf, buf, stride, r);
+          switch (pf.bpp) {
+          case 8:
+            assert(false);
+            break;
+          case 16:
+            FilterGradient(bufptr, pf, outbuf, stride, r);
+            break;
+          case 32:
+            FilterGradient(bufptr, pf, outbuf, stride, r);
+            break;
+          }
         }
       } else {
         // Copy
-        int h = r.height();
-        int ptr = 0;
-        int srcPtr = 0;
+        ByteBuffer ptr = (ByteBuffer)outbuf.duplicate().mark();
+        ByteBuffer srcPtr = bufptr.duplicate();
         int w = r.width();
-        if (cutZeros) {
-          serverpf.bufferFromRGB(buf, ptr, netbuf, srcPtr, w*h);
-        } else {
-          int pixelSize = (bpp >= 24) ? 3 : bpp/8;
+        int h = r.height();
+        if (pf.is888()) {
           while (h > 0) {
-            for (int i = 0; i < w; i++) {
-              if (bpp == 8) {
-                buf[ptr+i] = netbuf[srcPtr+i] & 0xff;
-              } else {
-                for (int j = pixelSize-1; j >= 0; j--)
-                  buf[ptr+i] |= ((netbuf[srcPtr+i+j] & 0xff) << j*8);
-              }
-            }
-            ptr += stride;
-            srcPtr += w * pixelSize;
+            pf.bufferFromRGB(ptr.duplicate(), srcPtr.duplicate(), w);
+            ptr.position(ptr.position() + stride * pf.bpp/8);
+            srcPtr.position(srcPtr.position() + w * 3);
+            h--;
+          }
+        } else {
+          while (h > 0) {
+            ptr.put(srcPtr.array(), srcPtr.position(), w * pf.bpp/8);
+            ptr.reset().position(ptr.position() + stride * pf.bpp/8).mark();
+            srcPtr.position(srcPtr.position() + w * pf.bpp/8);
             h--;
           }
         }
       }
     } else {
       // Indexed color
-      int x, h = r.height(), w = r.width(), b, pad = stride - w;
-      int ptr = 0;
-      int srcPtr = 0, bits;
-      if (palSize <= 2) {
-        // 2-color palette
-        while (h > 0) {
-          for (x = 0; x < w / 8; x++) {
-            bits = netbuf[srcPtr++];
-            for(b = 7; b >= 0; b--) {
-              buf[ptr++] = palette[bits >> b & 1];
-            }
-          }
-          if (w % 8 != 0) {
-            bits = netbuf[srcPtr++];
-            for (b = 7; b >= 8 - w % 8; b--) {
-              buf[ptr++] = palette[bits >> b & 1];
-            }
-          }
-          ptr += pad;
-          h--;
-        }
-      } else {
-        // 256-color palette
-        while (h > 0) {
-          int endOfRow = ptr + w;
-          while (ptr < endOfRow) {
-            buf[ptr++] = palette[netbuf[srcPtr++] & 0xff];
-          }
-          ptr += pad;
-          h--;
-        }
+      switch (pf.bpp) {
+      case 8:
+        FilterPalette8(palette, palSize,
+                       bufptr, outbuf, stride, r);
+        break;
+      case 16:
+        FilterPalette16(palette.asShortBuffer(), palSize,
+                        bufptr, outbuf.asShortBuffer(), stride, r);
+        break;
+      case 32:
+        FilterPalette32(palette.asIntBuffer(), palSize,
+                        bufptr, outbuf.asIntBuffer(), stride, r);
+        break;
       }
     }
 
-    handler.imageRect(r, buf);
+    pb.imageRect(pf, r, outbuf.array());
 
-    if (streamId != -1) {
-      zis[streamId].reset();
-    }
   }
 
-  final private void DECOMPRESS_JPEG_RECT(Rect r, InStream is, CMsgHandler handler)
+  final private void FilterGradient24(ByteBuffer inbuf,
+                                      PixelFormat pf, ByteBuffer outbuf,
+                                      int stride, Rect r)
   {
-    // Read length
-    int compressedLen = is.readCompactLength();
-    if (compressedLen <= 0)
-      vlog.info("Incorrect data received from the server.");
-
-    // Allocate netbuf and read in data
-    byte[] netbuf = new byte[compressedLen];
-    is.readBytes(netbuf, 0, compressedLen);
-
-    // Create an Image object from the JPEG data.
-    Image jpeg = tk.createImage(netbuf);
-    jpeg.setAccelerationPriority(1);
-    handler.imageRect(r, jpeg);
-    jpeg.flush();
-  }
-
-  final private void FilterGradient24(byte[] netbuf, int[] buf, int stride,
-                                      Rect r)
-  {
-
     int x, y, c;
     byte[] prevRow = new byte[TIGHT_MAX_WIDTH*3];
     byte[] thisRow = new byte[TIGHT_MAX_WIDTH*3];
-    byte[] pix = new byte[3];
+    ByteBuffer pix = ByteBuffer.allocate(3);
     int[] est = new int[3];
 
     // Set up shortcut variables
@@ -273,38 +424,38 @@
     for (y = 0; y < rectHeight; y++) {
       /* First pixel in a row */
       for (c = 0; c < 3; c++) {
-        pix[c] = (byte)(netbuf[y*rectWidth*3+c] + prevRow[c]);
-        thisRow[c] = pix[c];
+        pix.put(c, (byte)(inbuf.get(y*rectWidth*3+c) + prevRow[c]));
+        thisRow[c] = pix.get(c);
       }
-      serverpf.bufferFromRGB(buf, y*stride, pix, 0, 1);
+      pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride), pix, 1);
 
       /* Remaining pixels of a row */
       for (x = 1; x < rectWidth; x++) {
         for (c = 0; c < 3; c++) {
-          est[c] = (int)(prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]);
-          if (est[c] > 0xFF) {
-            est[c] = 0xFF;
+          est[c] = prevRow[x*3+c] + pix.get(c) - prevRow[(x-1)*3+c];
+          if (est[c] > 0xff) {
+            est[c] = 0xff;
           } else if (est[c] < 0) {
             est[c] = 0;
           }
-          pix[c] = (byte)(netbuf[(y*rectWidth+x)*3+c] + est[c]);
-          thisRow[x*3+c] = pix[c];
+          pix.put(c, (byte)(inbuf.get((y*rectWidth+x)*3+c) + est[c]));
+          thisRow[x*3+c] = pix.get(c);
         }
-        serverpf.bufferFromRGB(buf, y*stride+x, pix, 0, 1);
+        pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride+x), pix, 1);
       }
 
       System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
     }
   }
 
-  final private void FilterGradient(byte[] netbuf, int[] buf, int stride,
-                                    Rect r)
+  final private void FilterGradient(ByteBuffer inbuf,
+                                    PixelFormat pf, ByteBuffer outbuf,
+                                    int stride, Rect r)
   {
-
     int x, y, c;
     byte[] prevRow = new byte[TIGHT_MAX_WIDTH];
     byte[] thisRow = new byte[TIGHT_MAX_WIDTH];
-    byte[] pix = new byte[3];
+    ByteBuffer pix = ByteBuffer.allocate(3);
     int[] est = new int[3];
 
     // Set up shortcut variables
@@ -313,19 +464,18 @@
 
     for (y = 0; y < rectHeight; y++) {
       /* First pixel in a row */
-      // FIXME
-      //serverpf.rgbFromBuffer(pix, 0, netbuf, y*rectWidth, 1, cm);
+      pf.rgbFromBuffer(pix, (ByteBuffer)inbuf.position(y*rectWidth), 1);
       for (c = 0; c < 3; c++)
-        pix[c] += prevRow[c];
+        pix.put(c, (byte)(pix.get(c) + prevRow[c]));
 
-      System.arraycopy(pix, 0, thisRow, 0, pix.length);
+      System.arraycopy(pix.array(), 0, thisRow, 0, pix.capacity());
 
-      serverpf.bufferFromRGB(buf, y*stride, pix, 0, 1);
+      pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride), pix, 1);
 
       /* Remaining pixels of a row */
       for (x = 1; x < rectWidth; x++) {
         for (c = 0; c < 3; c++) {
-          est[c] = (int)(prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]);
+          est[c] = prevRow[x*3+c] + pix.get(c) - prevRow[(x-1)*3+c];
           if (est[c] > 0xff) {
             est[c] = 0xff;
           } else if (est[c] < 0) {
@@ -333,24 +483,156 @@
           }
         }
 
-        // FIXME
-        //serverpf.rgbFromBuffer(pix, 0, netbuf, y*rectWidth+x, 1, cm);
+        pf.rgbFromBuffer(pix, (ByteBuffer)inbuf.position(y*rectWidth+x), 1);
         for (c = 0; c < 3; c++)
-          pix[c] += est[c];
+          pix.put(c, (byte)(pix.get(c) + est[c]));
 
-        System.arraycopy(pix, 0, thisRow, x*3, pix.length);
+        System.arraycopy(pix.array(), 0, thisRow, x*3, pix.capacity());
 
-        serverpf.bufferFromRGB(buf, y*stride+x, pix, 0, 1);
+        pf.bufferFromRGB((ByteBuffer)outbuf.position(y*stride+x), pix, 1);
       }
 
       System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
     }
   }
 
-  private CMsgReader reader;
+  private void FilterPalette8(ByteBuffer palette, int palSize,
+                              ByteBuffer inbuf, ByteBuffer outbuf,
+                              int stride, Rect r)
+  {
+    // Indexed color
+    int x, h = r.height(), w = r.width(), b, pad = stride - w;
+    ByteBuffer ptr = outbuf.duplicate();
+    byte bits;
+    ByteBuffer srcPtr = inbuf.duplicate();
+    if (palSize <= 2) {
+      // 2-color palette
+      while (h > 0) {
+        for (x = 0; x < w / 8; x++) {
+          bits = srcPtr.get();
+          for (b = 7; b >= 0; b--) {
+            ptr.put(palette.get(bits >> b & 1));
+          }
+        }
+        if (w % 8 != 0) {
+          bits = srcPtr.get();
+          for (b = 7; b >= 8 - w % 8; b--) {
+            ptr.put(palette.get(bits >> b & 1));
+          }
+        }
+        ptr.position(ptr.position() + pad);
+        h--;
+      }
+    } else {
+      // 256-color palette
+      while (h > 0) {
+        int endOfRow = ptr.position() + w;
+        while (ptr.position() < endOfRow) {
+          ptr.put(palette.get(srcPtr.get()));
+        }
+        ptr.position(ptr.position() + pad);
+        h--;
+      }
+    }
+  }
+
+  private void FilterPalette16(ShortBuffer palette, int palSize,
+                               ByteBuffer inbuf, ShortBuffer outbuf,
+                               int stride, Rect r)
+  {
+    // Indexed color
+    int x, h = r.height(), w = r.width(), b, pad = stride - w;
+    ShortBuffer ptr = outbuf.duplicate();
+    byte bits;
+    ByteBuffer srcPtr = inbuf.duplicate();
+    if (palSize <= 2) {
+      // 2-color palette
+      while (h > 0) {
+        for (x = 0; x < w / 8; x++) {
+          bits = srcPtr.get();
+          for (b = 7; b >= 0; b--) {
+            ptr.put(palette.get(bits >> b & 1));
+          }
+        }
+        if (w % 8 != 0) {
+          bits = srcPtr.get();
+          for (b = 7; b >= 8 - w % 8; b--) {
+            ptr.put(palette.get(bits >> b & 1));
+          }
+        }
+        ptr.position(ptr.position() + pad);
+        h--;
+      }
+    } else {
+      // 256-color palette
+      while (h > 0) {
+        int endOfRow = ptr.position() + w;
+        while (ptr.position() < endOfRow) {
+          ptr.put(palette.get(srcPtr.get()));
+        }
+        ptr.position(ptr.position() + pad);
+        h--;
+      }
+    }
+  }
+
+  private void FilterPalette32(IntBuffer palette, int palSize,
+                               ByteBuffer inbuf, IntBuffer outbuf,
+                               int stride, Rect r)
+  {
+    // Indexed color
+    int x, h = r.height(), w = r.width(), b, pad = stride - w;
+    IntBuffer ptr = outbuf.duplicate();
+    byte bits;
+    ByteBuffer srcPtr = inbuf.duplicate();
+    if (palSize <= 2) {
+      // 2-color palette
+      while (h > 0) {
+        for (x = 0; x < w / 8; x++) {
+          bits = srcPtr.get();
+          for (b = 7; b >= 0; b--) {
+            ptr.put(palette.get(bits >> b & 1));
+          }
+        }
+        if (w % 8 != 0) {
+          bits = srcPtr.get();
+          for (b = 7; b >= 8 - w % 8; b--) {
+            ptr.put(palette.get(bits >> b & 1));
+          }
+        }
+        ptr.position(ptr.position() + pad);
+        h--;
+      }
+    } else {
+      // 256-color palette
+      while (h > 0) {
+        int endOfRow = ptr.position() + w;
+        while (ptr.position() < endOfRow) {
+          ptr.put(palette.get(srcPtr.get() & 0xff));
+        }
+        ptr.position(ptr.position() + pad);
+        h--;
+      }
+    }
+  }
+
+  public final int readCompact(InStream is) {
+    byte b;
+    int result;
+
+    b = (byte)is.readU8();
+    result = (int)b & 0x7F;
+    if ((b & 0x80) != 0) {
+      b = (byte)is.readU8();
+      result |= ((int)b & 0x7F) << 7;
+      if ((b & 0x80) != 0) {
+        b = (byte)is.readU8();
+        result |= ((int)b & 0xFF) << 14;
+      }
+    }
+    return result;
+  }
+
   private ZlibInStream[] zis;
-  private PixelFormat serverpf;
-  private PixelFormat clientpf;
-  static LogWriter vlog = new LogWriter("TightDecoder");
 
 }
diff --git a/java/com/tigervnc/rfb/ZRLEDecoder.java b/java/com/tigervnc/rfb/ZRLEDecoder.java
index e706510..c1f908a 100644
--- a/java/com/tigervnc/rfb/ZRLEDecoder.java
+++ b/java/com/tigervnc/rfb/ZRLEDecoder.java
@@ -18,22 +18,143 @@
 
 package com.tigervnc.rfb;
 
+import java.awt.image.*;
+import java.nio.*;
+import java.util.*;
+
 import com.tigervnc.rdr.*;
 
 public class ZRLEDecoder extends Decoder {
 
-  public ZRLEDecoder(CMsgReader reader_) {
-    reader = reader_;
+  private static int readOpaque24A(InStream is)
+  {
+    is.check(3);
+    ByteBuffer r = ByteBuffer.allocate(4);
+    r.put(0, (byte)is.readU8());
+    r.put(1, (byte)is.readU8());
+    r.put(2, (byte)is.readU8());
+    return ((ByteBuffer)r.rewind()).getInt();
+  }
+
+  private static int readOpaque24B(InStream is)
+  {
+    is.check(3);
+    ByteBuffer r = ByteBuffer.allocate(4);
+    r.put(2, (byte)is.readU8());
+    r.put(1, (byte)is.readU8());
+    r.put(0, (byte)is.readU8());
+    return ((ByteBuffer)r.rewind()).getInt();
+  }
+
+  public ZRLEDecoder() {
+    super(DecoderFlags.DecoderOrdered);
     zis = new ZlibInStream();
   }
 
-  public void readRect(Rect r, CMsgHandler handler) {
-    InStream is = reader.getInStream();
-    int[] buf = reader.getImageBuf(64 * 64 * 4);
-    int bpp = handler.cp.pf().bpp;
-    int bytesPerPixel = (bpp > 24 ? 3 : bpp / 8);
-    boolean bigEndian = handler.cp.pf().bigEndian;
+  public void readRect(Rect r, InStream is,
+                      ConnParams cp, OutStream os)
+  {
+    int len;
 
+    len = is.readU32();
+    os.writeU32(len);
+    os.copyBytes(is, len);
+  }
+
+  public void decodeRect(Rect r, Object buffer,
+                         int buflen, ConnParams cp,
+                         ModifiablePixelBuffer pb)
+  {
+    MemInStream is = new MemInStream((byte[])buffer, 0, buflen);
+    PixelFormat pf = cp.pf();
+    ByteBuffer buf = ByteBuffer.allocate(64 * 64 * 4);
+    switch (pf.bpp) {
+    case 8:  zrleDecode8(r, is, zis, buf, pf, pb); break;
+    case 16: zrleDecode16(r, is, zis, buf, pf, pb); break;
+    case 32:
+        int maxPixel = pf.pixelFromRGB(-1, -1, -1, pf.getColorModel());
+        boolean fitsInLS3Bytes = maxPixel < (1<<24);
+        boolean fitsInMS3Bytes = (maxPixel & 0xff) == 0;
+
+        if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
+            (fitsInMS3Bytes && pf.isBigEndian()))
+        {
+          zrleDecode24A(r, is, zis, buf, pf, pb);
+        }
+        else if ((fitsInLS3Bytes && pf.isBigEndian()) ||
+                (fitsInMS3Bytes && pf.isLittleEndian()))
+        {
+          zrleDecode24B(r, is, zis, buf, pf, pb);
+        }
+        else
+        {
+          zrleDecode32(r, is, zis, buf, pf, pb);
+        }
+        break;
+    }
+  }
+
+  private static enum PIXEL_T { U8, U16, U24A, U24B, U32 };
+
+  private static ByteBuffer READ_PIXEL(InStream is, PIXEL_T type) {
+    ByteBuffer b = ByteBuffer.allocate(4);
+    switch (type) {
+    case U8:
+      b.putInt(is.readOpaque8());
+      return (ByteBuffer)ByteBuffer.allocate(1).put(b.get(3)).rewind();
+    case U16:
+      b.putInt(is.readOpaque16());
+      return (ByteBuffer)ByteBuffer.allocate(2).put(b.array(), 2, 2).rewind();
+    case U24A:
+      return (ByteBuffer)b.putInt(readOpaque24A(is)).rewind();
+    case U24B:
+      return (ByteBuffer)b.putInt(readOpaque24B(is)).rewind();
+    case U32:
+    default:
+      return (ByteBuffer)b.putInt(is.readOpaque32()).rewind();
+    }
+  }
+
+  private void zrleDecode8(Rect r, InStream is,
+                           ZlibInStream zis, ByteBuffer buf,
+                           PixelFormat pf, ModifiablePixelBuffer pb)
+  {
+    ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U8);
+  }
+
+  private void zrleDecode16(Rect r, InStream is,
+                            ZlibInStream zis, ByteBuffer buf,
+                            PixelFormat pf, ModifiablePixelBuffer pb)
+  {
+    ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U16);
+  }
+
+  private void zrleDecode24A(Rect r, InStream is,
+                             ZlibInStream zis, ByteBuffer buf,
+                             PixelFormat pf, ModifiablePixelBuffer pb)
+  {
+    ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U24A);
+  }
+
+  private void zrleDecode24B(Rect r, InStream is,
+                             ZlibInStream zis, ByteBuffer buf,
+                             PixelFormat pf, ModifiablePixelBuffer pb)
+  {
+    ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U24B);
+  }
+
+  private void zrleDecode32(Rect r, InStream is,
+                            ZlibInStream zis, ByteBuffer buf,
+                            PixelFormat pf, ModifiablePixelBuffer pb)
+  {
+    ZRLE_DECODE(r, is, zis, buf, pf, pb, PIXEL_T.U32);
+  }
+
+  private void ZRLE_DECODE(Rect r, InStream is,
+                           ZlibInStream zis, ByteBuffer buf,
+                           PixelFormat pf, ModifiablePixelBuffer pb,
+                           PIXEL_T pix_t)
+  {
     int length = is.readU32();
     zis.setUnderlying(is, length);
     Rect t = new Rect();
@@ -49,13 +170,16 @@
         int mode = zis.readU8();
         boolean rle = (mode & 128) != 0;
         int palSize = mode & 127;
-        int[] palette = new int[128];
+        ByteBuffer palette = ByteBuffer.allocate(128 * pf.bpp/8);
 
-        zis.readPixels(palette, palSize, bytesPerPixel, bigEndian);
+        for (int i = 0; i < palSize; i++) {
+          palette.put(READ_PIXEL(zis, pix_t));
+        }
 
         if (palSize == 1) {
-          int pix = palette[0];
-          handler.fillRect(t, pix);
+          ByteBuffer pix = 
+            ByteBuffer.allocate(pf.bpp/8).put(palette.array(), 0, pf.bpp/8);
+          pb.fillRect(pf, t, pix.array());
           continue;
         }
 
@@ -63,8 +187,17 @@
           if (palSize == 0) {
 
             // raw
-
-            zis.readPixels(buf, t.area(), bytesPerPixel, bigEndian);
+            switch (pix_t) {
+            case U24A:
+            case U24B:
+              ByteBuffer ptr = buf.duplicate();
+              for (int iptr=0; iptr < t.area(); iptr++) {
+                ptr.put(READ_PIXEL(zis, pix_t));
+              }
+              break;
+            default:
+              zis.readBytes(buf, t.area() * (pf.bpp/8));
+            }
 
           } else {
 
@@ -72,21 +205,21 @@
             int bppp = ((palSize > 16) ? 8 :
                         ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1)));
 
-            int ptr = 0;
+            ByteBuffer ptr = buf.duplicate();
 
             for (int i = 0; i < t.height(); i++) {
-              int eol = ptr + t.width();
+              int eol = ptr.position() + t.width()*pf.bpp/8;
               int b = 0;
               int nbits = 0;
 
-              while (ptr < eol) {
+              while (ptr.position() < eol) {
                 if (nbits == 0) {
                   b = zis.readU8();
                   nbits = 8;
                 }
                 nbits -= bppp;
                 int index = (b >> nbits) & ((1 << bppp) - 1) & 127;
-                buf[ptr++] = palette[index];
+                ptr.put(palette.array(), index*pf.bpp/8, pf.bpp/8);
               }
             }
           }
@@ -97,10 +230,10 @@
 
             // plain RLE
 
-            int ptr = 0;
-            int end = ptr + t.area();
-            while (ptr < end) {
-              int pix = zis.readPixel(bytesPerPixel, bigEndian);
+            ByteBuffer ptr = buf.duplicate();
+            int end = ptr.position() + t.area()*pf.bpp/8;
+            while (ptr.position() < end) {
+              ByteBuffer pix = READ_PIXEL(zis, pix_t);
               int len = 1;
               int b;
               do {
@@ -108,19 +241,21 @@
                 len += b;
               } while (b == 255);
 
-              if (!(len <= end - ptr))
-                throw new Exception("ZRLEDecoder: assertion (len <= end - ptr)"
-                                    +" failed");
+              if (end - ptr.position() < len*(pf.bpp/8)) {
+                System.err.println("ZRLE decode error\n");
+                throw new Exception("ZRLE decode error");
+              }
 
-              while (len-- > 0) buf[ptr++] = pix;
+              while (len-- > 0) ptr.put(pix);
+
             }
           } else {
 
             // palette RLE
 
-            int ptr = 0;
-            int end = ptr + t.area();
-            while (ptr < end) {
+            ByteBuffer ptr = buf.duplicate();
+            int end = ptr.position() + t.area()*pf.bpp/8;
+            while (ptr.position() < end) {
               int index = zis.readU8();
               int len = 1;
               if ((index & 128) != 0) {
@@ -130,27 +265,26 @@
                   len += b;
                 } while (b == 255);
 
-                if (!(len <= end - ptr))
-                  throw new Exception("ZRLEDecoder: assertion "
-                                      +"(len <= end - ptr) failed");
+                if (end - ptr.position() < len*(pf.bpp/8)) {
+                  System.err.println("ZRLE decode error\n");
+                  throw new Exception("ZRLE decode error");
+                }
               }
 
               index &= 127;
 
-              int pix = palette[index];
+              while (len-- > 0) ptr.put(palette.array(), index*pf.bpp/8, pf.bpp/8);
 
-              while (len-- > 0) buf[ptr++] = pix;
             }
           }
         }
 
-        handler.imageRect(t, buf);
+        pb.imageRect(pf, t, buf.array());
       }
     }
 
-    zis.reset();
+    zis.removeUnderlying();
   }
 
-  CMsgReader reader;
-  ZlibInStream zis;
+  private ZlibInStream zis;
 }
diff --git a/java/com/tigervnc/vncviewer/BIPixelBuffer.java b/java/com/tigervnc/vncviewer/BIPixelBuffer.java
deleted file mode 100644
index 1634ebd..0000000
--- a/java/com/tigervnc/vncviewer/BIPixelBuffer.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright (C) 2012 Brian P. Hinz
- * Copyright (C) 2012 D. R. Commander.  All Rights Reserved.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-package com.tigervnc.vncviewer;
-
-import java.awt.*;
-import java.awt.image.*;
-
-import com.tigervnc.rfb.*;
-import com.tigervnc.rfb.Exception;
-
-public class BIPixelBuffer extends PlatformPixelBuffer implements ImageObserver
-{
-  public BIPixelBuffer(PixelFormat pf, int w, int h, DesktopWindow desktop_) {
-    super(pf, w, h, desktop_);
-    clip = new Rectangle();
-  }
-
-  public void setPF(PixelFormat pf) {
-    super.setPF(pf);
-    createImage(width(), height());
-  }
-
-  public void updateColourMap() {
-    super.updateColourMap();
-    createImage(width_, height_);
-  }
-
-  // resize() resizes the image, preserving the image data where possible.
-  public void resize(int w, int h) {
-    if (w == width() && h == height())
-      return;
-
-    width_ = w;
-    height_ = h;
-    createImage(w, h);
-  }
-
-  private void createImage(int w, int h) {
-    if (w == 0 || h == 0) return;
-    WritableRaster wr;
-    if (cm instanceof IndexColorModel)
-      wr = ((IndexColorModel)cm).createCompatibleWritableRaster(w, h);
-    else
-      wr = ((DirectColorModel)cm).createCompatibleWritableRaster(w, h);
-    image = new BufferedImage(cm, wr, true, null);
-    db = wr.getDataBuffer();
-  }
-
-  public void fillRect(int x, int y, int w, int h, int pix) {
-    Graphics2D graphics = (Graphics2D)image.getGraphics();
-    switch (format.depth) {
-    case 24:
-      graphics.setColor(new Color(pix));
-      graphics.fillRect(x, y, w, h);
-      break;
-    default:
-      Color color = new Color((0xff << 24) | (cm.getRed(pix) << 16) |
-                              (cm.getGreen(pix) << 8) | (cm.getBlue(pix)));
-      graphics.setColor(color);
-      graphics.fillRect(x, y, w, h);
-      break;
-    }
-    graphics.dispose();
-  }
-
-  public void imageRect(int x, int y, int w, int h, Object pix) {
-    if (pix instanceof Image) {
-      Image img = (Image)pix;
-      clip = new Rectangle(x, y, w, h);
-      synchronized(clip) {
-        tk.prepareImage(img, -1, -1, this);
-        try {
-          clip.wait(1000);
-        } catch (InterruptedException e) {
-          throw new Exception("Error decoding JPEG data");
-        }
-      }
-      clip = null;
-      img.flush();
-    } else {
-      if (image.getSampleModel().getTransferType() == DataBuffer.TYPE_BYTE) {
-        byte[] bytes = new byte[((int[])pix).length];
-        for (int i = 0; i < bytes.length; i++)
-          bytes[i] = (byte)((int[])pix)[i];
-        pix = bytes;
-      }
-      image.getSampleModel().setDataElements(x, y, w, h, pix, db);
-    }
-  }
-
-  public void copyRect(int x, int y, int w, int h, int srcX, int srcY) {
-    Graphics2D graphics = (Graphics2D)image.getGraphics();
-    graphics.copyArea(srcX, srcY, w, h, x - srcX, y - srcY);
-    graphics.dispose();
-  }
-
-  public Image getImage() {
-    return (Image)image;
-  }
-
-  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
-    if ((infoflags & (ALLBITS | ABORT)) == 0) {
-      return true;
-    } else {
-      if ((infoflags & ALLBITS) != 0) {
-        if (clip != null) {
-          synchronized(clip) {
-            Graphics2D graphics = (Graphics2D)image.getGraphics();
-            graphics.drawImage(img, clip.x, clip.y, clip.width, clip.height, null);
-            graphics.dispose();
-            clip.notify();
-          }
-        }
-      }
-      return false;
-    }
-  }
-
-  BufferedImage image;
-  DataBuffer db;
-  Rectangle clip;
-
-  static LogWriter vlog = new LogWriter("BIPixelBuffer");
-}
diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java
index d713434..8a2303b 100644
--- a/java/com/tigervnc/vncviewer/CConn.java
+++ b/java/com/tigervnc/vncviewer/CConn.java
@@ -63,16 +63,20 @@
 import static com.tigervnc.vncviewer.Parameters.*;
 
 public class CConn extends CConnection implements 
-  UserPasswdGetter, UserMsgBox,
-  FdInStreamBlockCallback, ActionListener {
+  UserPasswdGetter, FdInStreamBlockCallback, ActionListener {
 
-  public final PixelFormat getPreferredPF() { return fullColorPF; }
+  // 8 colours (1 bit per component)
   static final PixelFormat verylowColorPF =
     new PixelFormat(8, 3, false, true, 1, 1, 1, 2, 1, 0);
+
+  // 64 colours (2 bits per component)
   static final PixelFormat lowColorPF =
     new PixelFormat(8, 6, false, true, 3, 3, 3, 4, 2, 0);
+
+  // 256 colours (2-3 bits per component)
   static final PixelFormat mediumColorPF =
-    new PixelFormat(8, 8, false, false, 7, 7, 3, 0, 3, 6);
+    new PixelFormat(8, 8, false, true, 7, 7, 3, 5, 2, 0);
+
   static final int KEY_LOC_SHIFT_R = 0;
   static final int KEY_LOC_SHIFT_L = 16;
   static final int SUPER_MASK = 1<<15;
@@ -82,6 +86,7 @@
 
   public CConn(String vncServerName, Socket socket)
   {
+    serverHost = null; serverPort = 0; desktop = null;
     pendingPFChange = false;
     currentEncoding = Encodings.encodingTight; lastServerEncoding = -1;
     formatChange = false; encodingChange = false;
@@ -93,13 +98,12 @@
     downKeySym = new HashMap<Integer, Integer>();
 
     upg = this;
-    msg = this;
 
     int encNum = Encodings.encodingNum(preferredEncoding.getValue());
     if (encNum != -1)
       currentEncoding = encNum;
 
-    cp.supportsLocalCursor = useLocalCursor.getValue();
+    cp.supportsLocalCursor = true;
 
     cp.supportsDesktopResize = true;
     cp.supportsExtendedDesktopSize = true;
@@ -107,12 +111,13 @@
 
     cp.supportsSetDesktopSize = false;
     cp.supportsClientRedirect = true;
+
     if (customCompressLevel.getValue())
       cp.compressLevel = compressLevel.getValue();
     else
       cp.compressLevel = -1;
 
-    if (noJpeg.getValue())
+    if (!noJpeg.getValue())
       cp.qualityLevel = qualityLevel.getValue();
     else
       cp.qualityLevel = -1;
@@ -142,6 +147,7 @@
         vlog.info("connected to host "+Hostname.getHost(name)+" port "+Hostname.getPort(name));
     }
 
+    // See callback below
     sock.inStream().setBlockCallback(this);
 
     setStreams(sock.inStream(), sock.outStream());
@@ -161,21 +167,37 @@
       requestNewUpdate();
   }
 
-  public boolean showMsgBox(int flags, String title, String text)
-  {
-    //StringBuffer titleText = new StringBuffer("VNC Viewer: "+title);
-    return true;
+  public String connectionInfo() {
+    String info = new String("Desktop name: %s%n"+
+                             "Host: %s:%d%n"+
+                             "Size: %dx%d%n"+
+                             "Pixel format: %s%n"+
+                             "  (server default: %s)%n"+
+                             "Requested encoding: %s%n"+
+                             "Last used encoding: %s%n"+
+                             "Line speed estimate: %d kbit/s%n"+
+                             "Protocol version: %d.%d%n"+
+                             "Security method: %s [%s]%n");
+    String infoText =
+      String.format(info, cp.name(),
+                    sock.getPeerName(), sock.getPeerPort(),
+                    cp.width, cp.height,
+                    cp.pf().print(),
+                    serverPF.print(),
+                    Encodings.encodingName(currentEncoding),
+                    Encodings.encodingName(lastServerEncoding),
+                    sock.inStream().kbitsPerSecond(),
+                    cp.majorVersion, cp.minorVersion,
+                    Security.secTypeName(csecurity.getType()),
+                    csecurity.description());
+
+    return infoText;
   }
 
-  // deleteWindow() is called when the user closes the desktop or menu windows.
+  // The RFB core is not properly asynchronous, so it calls this callback
+  // whenever it needs to block to wait for more data. Since FLTK is
+  // monitoring the socket, we just make sure FLTK gets to run.
 
-  void deleteWindow() {
-    if (viewport != null)
-      viewport.dispose();
-    viewport = null;
-  }
-
-  // blockCallback() is called when reading from the socket would block.
   public void blockCallback() {
     try {
       synchronized(this) {
@@ -238,12 +260,13 @@
     return true;
   }
 
-  // CConnection callback methods
+  ////////////////////// CConnection callback methods //////////////////////
 
   // serverInit() is called when the serverInit message has been received.  At
   // this point we create the desktop window and display it.  We also tell the
   // server the pixel format and encodings to use and request the first update.
-  public void serverInit() {
+  public void serverInit()
+  {
     super.serverInit();
 
     // If using AutoSelect with old servers, start in FullColor
@@ -265,23 +288,22 @@
     // This initial update request is a bit of a corner case, so we need
     // to help out setting the correct format here.
     assert(pendingPFChange);
-    desktop.setServerPF(pendingPF);
     cp.setPF(pendingPF);
     pendingPFChange = false;
-
-    recreateViewport();
   }
 
   // setDesktopSize() is called when the desktop size changes (including when
   // it is set initially).
-  public void setDesktopSize(int w, int h) {
+  public void setDesktopSize(int w, int h)
+  {
     super.setDesktopSize(w, h);
     resizeFramebuffer();
   }
 
   // setExtendedDesktopSize() is a more advanced version of setDesktopSize()
   public void setExtendedDesktopSize(int reason, int result, int w, int h,
-                                     ScreenSet layout) {
+                                     ScreenSet layout)
+  {
     super.setExtendedDesktopSize(reason, result, w, h, layout);
 
     if ((reason == screenTypes.reasonClient) &&
@@ -294,8 +316,8 @@
   }
 
   // clientRedirect() migrates the client to another host/port
-  public void clientRedirect(int port, String host,
-                             String x509subject) {
+  public void clientRedirect(int port, String host, String x509subject)
+  {
     try {
       sock.close();
       sock = new TcpSocket(host, port);
@@ -311,10 +333,11 @@
   }
 
   // setName() is called when the desktop name changes
-  public void setName(String name) {
+  public void setName(String name)
+  {
     super.setName(name);
-    if (viewport != null)
-      viewport.setTitle(name+" - TigerVNC");
+    if (desktop != null)
+      desktop.setName(name);
   }
 
   // framebufferUpdateStart() is called at the beginning of an update.
@@ -323,12 +346,23 @@
   // one.
   public void framebufferUpdateStart()
   {
+    ModifiablePixelBuffer pb;
+    PlatformPixelBuffer ppb;
+
     super.framebufferUpdateStart();
 
     // Note: This might not be true if sync fences are supported
     pendingUpdate = false;
 
     requestNewUpdate();
+
+    // We might still be rendering the previous update
+    pb = getFramebuffer();
+    assert(pb != null);
+    ppb = (PlatformPixelBuffer)pb;
+    assert(ppb != null);
+
+    //FIXME
   }
 
   // framebufferUpdateEnd() is called at the end of an update.
@@ -342,53 +376,17 @@
     desktop.updateWindow();
 
     if (firstUpdate) {
-      int width, height;
-
       // We need fences to make extra update requests and continuous
       // updates "safe". See fence() for the next step.
       if (cp.supportsFence)
         writer().writeFence(fenceTypes.fenceFlagRequest | fenceTypes.fenceFlagSyncNext, 0, null);
 
-      if (cp.supportsSetDesktopSize &&
-          !desktopSize.getValue().isEmpty() &&
-          desktopSize.getValue().split("x").length == 2) {
-        width = Integer.parseInt(desktopSize.getValue().split("x")[0]);
-        height = Integer.parseInt(desktopSize.getValue().split("x")[1]);
-        ScreenSet layout;
-
-        layout = cp.screenLayout;
-
-        if (layout.num_screens() == 0)
-          layout.add_screen(new Screen());
-        else if (layout.num_screens() != 1) {
-
-          while (true) {
-            Iterator<Screen> iter = layout.screens.iterator();
-            Screen screen = (Screen)iter.next();
-
-            if (!iter.hasNext())
-              break;
-
-            layout.remove_screen(screen.id);
-          }
-        }
-
-        Screen screen0 = (Screen)layout.screens.iterator().next();
-        screen0.dimensions.tl.x = 0;
-        screen0.dimensions.tl.y = 0;
-        screen0.dimensions.br.x = width;
-        screen0.dimensions.br.y = height;
-
-        writer().writeSetDesktopSize(width, height, layout);
-      }
-
       firstUpdate = false;
     }
 
     // A format change has been scheduled and we are now past the update
     // with the old format. Time to active the new one.
     if (pendingPFChange) {
-      desktop.setServerPF(pendingPF);
       cp.setPF(pendingPF);
       pendingPFChange = false;
     }
@@ -400,16 +398,19 @@
 
   // The rest of the callbacks are fairly self-explanatory...
 
-  public void setColourMapEntries(int firstColor, int nColors, int[] rgbs) {
-    desktop.setColourMapEntries(firstColor, nColors, rgbs);
+  public void setColourMapEntries(int firstColor, int nColors, int[] rgbs)
+  {
+    vlog.error("Invalid SetColourMapEntries from server!");
   }
 
-  public void bell() {
+  public void bell()
+  {
     if (acceptBell.getValue())
       desktop.getToolkit().beep();
   }
 
-  public void serverCutText(String str, int len) {
+  public void serverCutText(String str, int len)
+  {
     StringSelection buffer;
 
     if (!acceptClipboard.getValue())
@@ -418,34 +419,21 @@
     ClipboardDialog.serverCutText(str);
   }
 
-  // We start timing on beginRect and stop timing on endRect, to
-  // avoid skewing the bandwidth estimation as a result of the server
-  // being slow or the network having high latency
-  public void beginRect(Rect r, int encoding) {
+  public void dataRect(Rect r, int encoding)
+  {
     sock.inStream().startTiming();
-    if (encoding != Encodings.encodingCopyRect) {
-      lastServerEncoding = encoding;
-    }
-  }
 
-  public void endRect(Rect r, int encoding) {
+    if (encoding != Encodings.encodingCopyRect)
+      lastServerEncoding = encoding;
+
+    super.dataRect(r, encoding);
+
     sock.inStream().stopTiming();
   }
 
-  public void fillRect(Rect r, int p) {
-    desktop.fillRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
-  }
-
-  public void imageRect(Rect r, Object p) {
-    desktop.imageRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
-  }
-
-  public void copyRect(Rect r, int sx, int sy) {
-    desktop.copyRect(r.tl.x, r.tl.y, r.width(), r.height(), sx, sy);
-  }
-
   public void setCursor(int width, int height, Point hotspot,
-                        int[] data, byte[] mask) {
+                        byte[] data, byte[] mask)
+  {
     desktop.setCursor(width, height, hotspot, data, mask);
   }
 
@@ -480,11 +468,11 @@
 
       pf.read(memStream);
 
-      desktop.setServerPF(pf);
       cp.setPF(pf);
     }
   }
 
+  ////////////////////// Internal methods //////////////////////
   private void resizeFramebuffer()
   {
     if (desktop == null)
@@ -493,82 +481,7 @@
     if (continuousUpdates)
       writer().writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height);
 
-    if ((cp.width == 0) && (cp.height == 0))
-      return;
-    if ((desktop.width() == cp.width) && (desktop.height() == cp.height))
-      return;
-
-    desktop.resize();
-    if (!firstUpdate)
-      recreateViewport();
-  }
-  
-  // recreateViewport() recreates our top-level window.  This seems to be
-  // better than attempting to resize the existing window, at least with
-  // various X window managers.
-
-  public void recreateViewport() {
-    if (embed.getValue()) {
-      desktop.setViewport(VncViewer.getViewport());
-      Container viewer =
-        SwingUtilities.getAncestorOfClass(JApplet.class, desktop);
-      viewer.addFocusListener(new FocusAdapter() {
-        public void focusGained(FocusEvent e) {
-          Container c =
-            SwingUtilities.getAncestorOfClass(JApplet.class, desktop);
-          if (c != null && desktop.isAncestorOf(c))
-            desktop.requestFocus();
-        }
-        public void focusLost(FocusEvent e) {
-          releaseDownKeys();
-        }
-      });
-      viewer.validate();
-      desktop.requestFocus();
-    } else {
-      if (viewport != null)
-        viewport.dispose();
-      viewport = new Viewport(cp.name(), this);
-      viewport.setUndecorated(fullScreen.getValue());
-      desktop.setViewport(viewport.getViewport());
-      reconfigureViewport();
-      if ((cp.width > 0) && (cp.height > 0))
-        viewport.setVisible(true);
-      desktop.requestFocusInWindow();
-    }
-  }
-
-  private void reconfigureViewport() {
-    Dimension dpySize = viewport.getScreenSize();
-    int w = desktop.scaledWidth;
-    int h = desktop.scaledHeight;
-    if (fullScreen.getValue()) {
-      if (!fullScreenAllMonitors.getValue())
-        viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
-      viewport.setBounds(viewport.getScreenBounds());
-      if (!fullScreenAllMonitors.getValue())
-        Viewport.setFullScreenWindow(viewport);
-    } else {
-      int wmDecorationWidth = viewport.getInsets().left + viewport.getInsets().right;
-      int wmDecorationHeight = viewport.getInsets().top + viewport.getInsets().bottom;
-      if (w + wmDecorationWidth >= dpySize.width)
-        w = dpySize.width - wmDecorationWidth;
-      if (h + wmDecorationHeight >= dpySize.height)
-        h = dpySize.height - wmDecorationHeight;
-      if (viewport.getExtendedState() == JFrame.MAXIMIZED_BOTH) {
-        w = viewport.getSize().width;
-        h = viewport.getSize().height;
-        int x = viewport.getLocation().x;
-        int y = viewport.getLocation().y;
-        viewport.setGeometry(x, y, w, h);
-      } else {
-        int x = (dpySize.width - w - wmDecorationWidth) / 2;
-        int y = (dpySize.height - h - wmDecorationHeight)/2;
-        viewport.setExtendedState(JFrame.NORMAL);
-        viewport.setGeometry(x, y, w, h);
-      }
-      Viewport.setFullScreenWindow(null);
-    }
+    desktop.resizeFramebuffer(cp.width, cp.height);
   }
 
   // autoSelectFormatAndEncoding() chooses the format and encoding appropriate
@@ -586,11 +499,12 @@
   //   Note: The system here is fairly arbitrary and should be replaced
   //         with something more intelligent at the server end.
   //
-  private void autoSelectFormatAndEncoding() {
+  private void autoSelectFormatAndEncoding()
+  {
     long kbitsPerSecond = sock.inStream().kbitsPerSecond();
     long timeWaited = sock.inStream().timeWaited();
     boolean newFullColor = fullColor.getValue();
-    int newQualityLevel = cp.qualityLevel;
+    int newQualityLevel = qualityLevel.getValue();
 
     // Always use Tight
     if (currentEncoding != Encodings.encodingTight) {
@@ -603,13 +517,13 @@
       return;
 
     // Select appropriate quality level
-    if (!cp.noJpeg) {
+    if (!noJpeg.getValue()) {
       if (kbitsPerSecond > 16000)
         newQualityLevel = 8;
       else
         newQualityLevel = 6;
 
-      if (newQualityLevel != cp.qualityLevel) {
+      if (newQualityLevel != qualityLevel.getValue()) {
         vlog.info("Throughput "+kbitsPerSecond+
                   " kbit/s - changing to quality "+newQualityLevel);
         cp.qualityLevel = newQualityLevel;
@@ -637,7 +551,17 @@
                 (newFullColor ? "enabled" : "disabled"));
       fullColor.setParam(newFullColor);
       formatChange = true;
-      forceNonincremental = true;
+    }
+  }
+
+  // checkEncodings() sends a setEncodings message if one is needed.
+  private void checkEncodings()
+  {
+    if (encodingChange && (writer() != null)) {
+      vlog.info("Using " + Encodings.encodingName(currentEncoding) +
+        " encoding");
+      writer().writeSetEncodings(currentEncoding, true);
+      encodingChange = false;
     }
   }
 
@@ -699,84 +623,9 @@
     forceNonincremental = false;
   }
 
-
-  ////////////////////////////////////////////////////////////////////
-  // The following methods are all called from the GUI thread
-
-  // close() shuts down the socket, thus waking up the RFB thread.
-  public void close() {
-    if (closeListener != null) {
-      embed.setParam(true);
-      JFrame f =
-        (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, desktop);
-      if (f != null)
-        f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
-    }
-    deleteWindow();
-    shuttingDown = true;
-    try {
-      if (sock != null)
-        sock.shutdown();
-    } catch (java.lang.Exception e) {
-      throw new Exception(e.getMessage());
-    }
-  }
-
-  void showInfo() {
-    Window fullScreenWindow = Viewport.getFullScreenWindow();
-    if (fullScreenWindow != null)
-      Viewport.setFullScreenWindow(null);
-    String info = new String("Desktop name: %s%n"+
-                             "Host: %s:%d%n"+
-                             "Size: %dx%d%n"+
-                             "Pixel format: %s%n"+
-                             "  (server default: %s)%n"+
-                             "Requested encoding: %s%n"+
-                             "Last used encoding: %s%n"+
-                             "Line speed estimate: %d kbit/s%n"+
-                             "Protocol version: %d.%d%n"+
-                             "Security method: %s [%s]%n");
-    String msg =
-      String.format(info, cp.name(),
-                    sock.getPeerName(), sock.getPeerPort(),
-                    cp.width, cp.height,
-                    desktop.getPF().print(),
-                    serverPF.print(),
-                    Encodings.encodingName(currentEncoding),
-                    Encodings.encodingName(lastServerEncoding),
-                    sock.inStream().kbitsPerSecond(),
-                    cp.majorVersion, cp.minorVersion,
-                    Security.secTypeName(csecurity.getType()),
-                    csecurity.description());
-    Object[] options = {"Close  \u21B5"};
-    JOptionPane op =
-      new JOptionPane(msg, JOptionPane.PLAIN_MESSAGE,
-                      JOptionPane.DEFAULT_OPTION, null, options);
-    JDialog dlg = op.createDialog(desktop, "VNC connection info");
-    dlg.setIconImage(VncViewer.frameIcon);
-    dlg.setAlwaysOnTop(true);
-    dlg.setVisible(true);
-    if (fullScreenWindow != null)
-      Viewport.setFullScreenWindow(fullScreenWindow);
-  }
-
-  public void refresh() {
-    writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), false);
-    pendingUpdate = true;
-  }
-
-  public synchronized int currentEncoding() {
-    return currentEncoding;
-  }
-
   public void handleOptions()
   {
 
-    if (viewport != null && viewport.isVisible()) {
-      viewport.toFront();
-      viewport.requestFocus();
-    }
-
     // Checking all the details of the current set of encodings is just
     // a pain. Assume something has changed, as resending the encoding
     // list is cheap. Avoid overriding what the auto logic has selected
@@ -788,7 +637,7 @@
         this.currentEncoding = encNum;
     }
 
-    this.cp.supportsLocalCursor = useLocalCursor.getValue();
+    this.cp.supportsLocalCursor = true;
 
     if (customCompressLevel.getValue())
       this.cp.compressLevel = compressLevel.getValue();
@@ -829,17 +678,66 @@
 
   }
 
-  public void toggleFullScreen() {
-    if (embed.getValue())
-      return;
-    fullScreen.setParam(!fullScreen.getValue());
-    if (viewport != null) {
-      if (!viewport.lionFSSupported()) {
-        recreateViewport();
-      } else {
-        viewport.toggleLionFS();
-      }
+  ////////////////////////////////////////////////////////////////////
+  // The following methods are all called from the GUI thread
+
+  // close() shuts down the socket, thus waking up the RFB thread.
+  public void close() {
+    if (closeListener != null) {
+      embed.setParam(true);
+      JFrame f =
+        (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, desktop);
+      if (f != null)
+        f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
     }
+    shuttingDown = true;
+    try {
+      if (sock != null)
+        sock.shutdown();
+    } catch (java.lang.Exception e) {
+      throw new Exception(e.getMessage());
+    }
+  }
+
+  void showInfo() {
+    Window fullScreenWindow = DesktopWindow.getFullScreenWindow();
+    if (fullScreenWindow != null)
+      DesktopWindow.setFullScreenWindow(null);
+    String info = new String("Desktop name: %s%n"+
+                             "Host: %s:%d%n"+
+                             "Size: %dx%d%n"+
+                             "Pixel format: %s%n"+
+                             "  (server default: %s)%n"+
+                             "Requested encoding: %s%n"+
+                             "Last used encoding: %s%n"+
+                             "Line speed estimate: %d kbit/s%n"+
+                             "Protocol version: %d.%d%n"+
+                             "Security method: %s [%s]%n");
+    String msg =
+      String.format(info, cp.name(),
+                    sock.getPeerName(), sock.getPeerPort(),
+                    cp.width, cp.height,
+                    cp.pf().print(),
+                    serverPF.print(),
+                    Encodings.encodingName(currentEncoding),
+                    Encodings.encodingName(lastServerEncoding),
+                    sock.inStream().kbitsPerSecond(),
+                    cp.majorVersion, cp.minorVersion,
+                    Security.secTypeName(csecurity.getType()),
+                    csecurity.description());
+    JOptionPane op = new JOptionPane(msg, JOptionPane.PLAIN_MESSAGE,
+                                     JOptionPane.DEFAULT_OPTION);
+    JDialog dlg = op.createDialog(desktop, "VNC connection info");
+    dlg.setIconImage(VncViewer.frameIcon);
+    dlg.setAlwaysOnTop(true);
+    dlg.setVisible(true);
+    if (fullScreenWindow != null)
+      DesktopWindow.setFullScreenWindow(fullScreenWindow);
+  }
+
+  public void refresh() {
+    writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), false);
+    pendingUpdate = true;
   }
 
   // writeClientCutText() is called from the clipboard dialog
@@ -860,7 +758,7 @@
       return;
 
     boolean down = (ev.getID() == KeyEvent.KEY_PRESSED);
-   
+
     int keySym, keyCode = ev.getKeyCode();
 
     // If neither the keyCode or keyChar are defined, then there's
@@ -875,9 +773,9 @@
       if (iter == null) {
         // Note that dead keys will raise this sort of error falsely
         // See https://bugs.openjdk.java.net/browse/JDK-6534883 
-        vlog.error("Unexpected key release of keyCode "+keyCode);
+        vlog.debug("Unexpected key release of keyCode "+keyCode);
         String fmt = ev.paramString().replaceAll("%","%%");
-        vlog.error(String.format(fmt.replaceAll(",","%n       ")));
+        vlog.debug(String.format(fmt.replaceAll(",","%n       ")));
 
         return;
       }
@@ -961,15 +859,6 @@
       break;
     }
 
-    if (cp.width != desktop.scaledWidth ||
-        cp.height != desktop.scaledHeight) {
-      int sx = (desktop.scaleWidthRatio == 1.00) ?
-        ev.getX() : (int)Math.floor(ev.getX() / desktop.scaleWidthRatio);
-      int sy = (desktop.scaleHeightRatio == 1.00) ?
-        ev.getY() : (int)Math.floor(ev.getY() / desktop.scaleHeightRatio);
-      ev.translatePoint(sx - ev.getX(), sy - ev.getY());
-    }
-
     writer().writePointerEvent(new Point(ev.getX(), ev.getY()), buttonMask);
   }
 
@@ -1014,16 +903,6 @@
   ////////////////////////////////////////////////////////////////////
   // The following methods are called from both RFB and GUI threads
 
-  // checkEncodings() sends a setEncodings message if one is needed.
-  private void checkEncodings() {
-    if (encodingChange && (writer() != null)) {
-      vlog.info("Requesting " + Encodings.encodingName(currentEncoding) +
-        " encoding");
-      writer().writeSetEncodings(currentEncoding, true);
-      encodingChange = false;
-    }
-  }
-
   // the following never change so need no synchronization:
 
   // access to desktop by different threads is specified in DesktopWindow
@@ -1031,7 +910,6 @@
   // the following need no synchronization:
 
   public static UserPasswdGetter upg;
-  public UserMsgBox msg;
 
   // shuttingDown is set by the GUI thread and only ever tested by the RFB
   // thread after the window has been destroyed.
@@ -1072,7 +950,6 @@
 
   private boolean supportsSyncFence;
 
-  Viewport viewport;
   private HashMap<Integer, Integer> downKeySym;
   public ActionListener closeListener = null;
 
diff --git a/java/com/tigervnc/vncviewer/DesktopWindow.java b/java/com/tigervnc/vncviewer/DesktopWindow.java
index de2d2cd..e76a015 100644
--- a/java/com/tigervnc/vncviewer/DesktopWindow.java
+++ b/java/com/tigervnc/vncviewer/DesktopWindow.java
@@ -1,8 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright (C) 2006 Constantin Kaplinsky.  All Rights Reserved.
- * Copyright (C) 2009 Paul Donohue.  All Rights Reserved.
- * Copyright (C) 2010, 2012-2013 D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2011-2014 Brian P. Hinz
+ * Copyright (C) 2011-2016 Brian P. Hinz
+ * Copyright (C) 2012-2013 D. R. Commander.  All Rights Reserved.
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,584 +18,631 @@
  * USA.
  */
 
-//
-// DesktopWindow is an AWT Canvas representing a VNC desktop.
-//
-// Methods on DesktopWindow are called from both the GUI thread and the thread
-// which processes incoming RFB messages ("the RFB thread").  This means we
-// need to be careful with synchronization here.
-//
-
 package com.tigervnc.vncviewer;
+
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.image.*;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.Clipboard;
-import java.io.BufferedReader;
-import java.nio.CharBuffer;
+import java.lang.reflect.*;
+import java.util.*;
 import javax.swing.*;
+import javax.swing.Timer;
+import javax.swing.border.*;
 
 import com.tigervnc.rfb.*;
-import com.tigervnc.rfb.Cursor;
 import com.tigervnc.rfb.Point;
+import java.lang.Exception;
+
+import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
+import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER;
+import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
+import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
+import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
+import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
 
 import static com.tigervnc.vncviewer.Parameters.*;
 
-class DesktopWindow extends JPanel implements Runnable, MouseListener,
-  MouseMotionListener, MouseWheelListener, KeyListener {
+public class DesktopWindow extends JFrame
+{
 
-  ////////////////////////////////////////////////////////////////////
-  // The following methods are all called from the RFB thread
+  static LogWriter vlog = new LogWriter("DesktopWindow");
 
-  public DesktopWindow(int width, int height, String name, PixelFormat serverPF,
-                       CConn cc_) {
+  public DesktopWindow(int w, int h, String name,
+                       PixelFormat serverPF, CConn cc_)
+  {
     cc = cc_;
-    setSize(width, height);
-    setScaledSize();
-    setOpaque(false);
-    if (cc.viewport != null)
-      cc.viewport.setName(name);
-    GraphicsEnvironment ge =
-      GraphicsEnvironment.getLocalGraphicsEnvironment();
-    GraphicsDevice gd = ge.getDefaultScreenDevice();
-    GraphicsConfiguration gc = gd.getDefaultConfiguration();
-    BufferCapabilities bufCaps = gc.getBufferCapabilities();
-    ImageCapabilities imgCaps = gc.getImageCapabilities();
-    if (bufCaps.isPageFlipping() || bufCaps.isMultiBufferAvailable() ||
-        imgCaps.isAccelerated()) {
-      vlog.debug("GraphicsDevice supports HW acceleration.");
-    } else {
-      vlog.debug("GraphicsDevice does not support HW acceleration.");
-    }
-    im = new BIPixelBuffer(serverPF, width, height, this);
+    firstUpdate = true;
+    delayedFullscreen = false; delayedDesktopSize = false;
 
-    cursor = new Cursor();
-    cursorBacking = new ManagedPixelBuffer();
-    Dimension bestSize = tk.getBestCursorSize(16, 16);
-    BufferedImage cursorImage;
-    cursorImage = new BufferedImage(bestSize.width, bestSize.height,
-                                    BufferedImage.TYPE_INT_ARGB);
-    java.awt.Point hotspot = new java.awt.Point(0,0);
-    nullCursor = tk.createCustomCursor(cursorImage, hotspot, "nullCursor");
-    cursorImage.flush();
-    if (!cc.cp.supportsLocalCursor && !bestSize.equals(new Dimension(0,0)))
-      setCursor(nullCursor);
-    addMouseListener(this);
-    addMouseWheelListener(this);
-    addMouseMotionListener(this);
-    addKeyListener(this);
-    addFocusListener(new FocusAdapter() {
-      public void focusGained(FocusEvent e) {
-        ClipboardDialog.clientCutText();
+    setFocusable(false);
+    setFocusTraversalKeysEnabled(false);
+    getToolkit().setDynamicLayout(false);
+    if (!VncViewer.os.startsWith("mac os x"))
+      setIconImage(VncViewer.frameIcon);
+    UIManager.getDefaults().put("ScrollPane.ancestorInputMap",
+      new UIDefaults.LazyInputMap(new Object[]{}));
+    scroll = new JScrollPane(new Viewport(w, h, serverPF, cc));
+    viewport = (Viewport)scroll.getViewport().getView();
+    scroll.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
+    getContentPane().add(scroll);
+
+    setName(name);
+
+    lastScaleFactor = scalingFactor.getValue();
+    if (VncViewer.os.startsWith("mac os x"))
+      if (!noLionFS.getValue())
+        enableLionFS();
+
+    OptionsDialog.addCallback("handleOptions", this);
+
+    addWindowFocusListener(new WindowAdapter() {
+      public void windowGainedFocus(WindowEvent e) {
+        if (isVisible())
+          if (scroll.getViewport() != null)
+            scroll.getViewport().getView().requestFocusInWindow();
       }
-      public void focusLost(FocusEvent e) {
+      public void windowLostFocus(WindowEvent e) {
         cc.releaseDownKeys();
       }
     });
-    setFocusTraversalKeysEnabled(false);
-    setFocusable(true);
-    OptionsDialog.addCallback("handleOptions", this);
-  }
 
-  public int width() {
-    return getWidth();
-  }
+    addWindowListener(new WindowAdapter() {
+      public void windowClosing(WindowEvent e) {
+        cc.close();
+      }
+      public void windowDeiconified(WindowEvent e) {
+        // ViewportBorder sometimes lost when window is shaded or de-iconified
+        repositionViewport();
+      }
+    });
 
-  public int height() {
-    return getHeight();
-  }
-
-  public final PixelFormat getPF() { return im.getPF(); }
-
-  public void setViewport(JViewport viewport) {
-    setScaledSize();
-    viewport.setView(this);
-    // pack() must be called on a JFrame before getInsets()
-    // will return anything other than 0.
-    if (viewport.getRootPane() != null)
-      if (getRootPane().getParent() instanceof JFrame)
-        ((JFrame)getRootPane().getParent()).pack();
-  }
-
-  // Methods called from the RFB thread - these need to be synchronized
-  // wherever they access data shared with the GUI thread.
-
-  public void setCursor(int w, int h, Point hotspot,
-                        int[] data, byte[] mask) {
-    // strictly we should use a mutex around this test since useLocalCursor
-    // might be being altered by the GUI thread.  However it's only a single
-    // boolean and it doesn't matter if we get the wrong value anyway.
-
-    if (!useLocalCursor.getValue())
-      return;
-
-    hideLocalCursor();
-
-    cursor.hotspot = (hotspot != null) ? hotspot : new Point(0, 0);
-    cursor.setSize(w, h);
-    cursor.setPF(getPF());
-
-    cursorBacking.setSize(cursor.width(), cursor.height());
-    cursorBacking.setPF(getPF());
-
-    cursor.data = new int[cursor.width() * cursor.height()];
-    cursor.mask = new byte[cursor.maskLen()];
-
-    int maskBytesPerRow = (w + 7) / 8;
-    for (int y = 0; y < h; y++) {
-      for (int x = 0; x < w; x++) {
-        int byte_ = y * maskBytesPerRow + x / 8;
-        int bit = 7 - x % 8;
-        if ((mask[byte_] & (1 << bit)) > 0) {
-          cursor.data[y * cursor.width() + x] = (0xff << 24) |
-            (im.cm.getRed(data[y * w + x]) << 16) |
-            (im.cm.getGreen(data[y * w + x]) << 8) |
-            (im.cm.getBlue(data[y * w + x]));
+    addWindowStateListener(new WindowAdapter() {
+      public void windowStateChanged(WindowEvent e) {
+        int state = e.getNewState();
+        if ((state & JFrame.MAXIMIZED_BOTH) != JFrame.MAXIMIZED_BOTH) {
+          Rectangle b = getGraphicsConfiguration().getBounds();
+          if (!b.contains(getLocationOnScreen()))
+            setLocation((int)b.getX(), (int)b.getY());
         }
+        // ViewportBorder sometimes lost when restoring on Windows
+        repositionViewport();
       }
-      System.arraycopy(mask, y * maskBytesPerRow, cursor.mask,
-        y * ((cursor.width() + 7) / 8), maskBytesPerRow);
-    }
+    });
 
-    int cw = (int)Math.floor((float)cursor.width() * scaleWidthRatio);
-    int ch = (int)Math.floor((float)cursor.height() * scaleHeightRatio);
-    Dimension bestSize = tk.getBestCursorSize(cw, ch);
-    MemoryImageSource cursorSrc;
-    cursorSrc = new MemoryImageSource(cursor.width(), cursor.height(),
-                                      ColorModel.getRGBdefault(),
-                                      cursor.data, 0, cursor.width());
-    Image srcImage = tk.createImage(cursorSrc);
-    BufferedImage cursorImage;
-    cursorImage = new BufferedImage(bestSize.width, bestSize.height,
-                                    BufferedImage.TYPE_INT_ARGB);
-    Graphics2D g2 = cursorImage.createGraphics();
-    g2.setRenderingHint(RenderingHints.KEY_RENDERING,
-                        RenderingHints.VALUE_RENDER_SPEED);
-    g2.drawImage(srcImage, 0, 0, (int)Math.min(cw, bestSize.width),
-                 (int)Math.min(ch, bestSize.height), 0, 0, cursor.width(),
-                 cursor.height(), null);
-    g2.dispose();
-    srcImage.flush();
-
-    int x = (int)Math.floor((float)cursor.hotspot.x * scaleWidthRatio);
-    int y = (int)Math.floor((float)cursor.hotspot.y * scaleHeightRatio);
-    x = (int)Math.min(x, Math.max(bestSize.width - 1, 0));
-    y = (int)Math.min(y, Math.max(bestSize.height - 1, 0));
-    java.awt.Point hs = new java.awt.Point(x, y);
-    if (!bestSize.equals(new Dimension(0, 0)))
-      softCursor = tk.createCustomCursor(cursorImage, hs, "softCursor");
-    cursorImage.flush();
-
-    if (softCursor != null) {
-      setCursor(softCursor);
-      cursorAvailable = false;
-      return;
-    }
-
-    if (!cursorAvailable) {
-      cursorAvailable = true;
-    }
-
-    showLocalCursor();
-  }
-
-  public void setServerPF(PixelFormat pf) {
-    im.setPF(pf);
-  }
-
-  public PixelFormat getPreferredPF() {
-    return im.getNativePF();
-  }
-
-  // setColourMapEntries() changes some of the entries in the colourmap.
-  // Unfortunately these messages are often sent one at a time, so we delay the
-  // settings taking effect unless the whole colourmap has changed.  This is
-  // because getting java to recalculate its internal translation table and
-  // redraw the screen is expensive.
-
-  public synchronized void setColourMapEntries(int firstColour, int nColours,
-                                               int[] rgbs) {
-    im.setColourMapEntries(firstColour, nColours, rgbs);
-    if (nColours <= 256) {
-      im.updateColourMap();
-    } else {
-      if (setColourMapEntriesTimerThread == null) {
-        setColourMapEntriesTimerThread = new Thread(this);
-        setColourMapEntriesTimerThread.start();
+    // Window resize events
+    timer = new Timer(500, new AbstractAction() {
+      public void actionPerformed(ActionEvent e) {
+        handleResizeTimeout();
       }
-    }
-  }
-
-  // Update the actual window with the changed parts of the framebuffer.
-  public void updateWindow() {
-    Rect r = damage;
-    if (!r.is_empty()) {
-      if (cc.cp.width != scaledWidth || cc.cp.height != scaledHeight) {
-        int x = (int)Math.floor(r.tl.x * scaleWidthRatio);
-        int y = (int)Math.floor(r.tl.y * scaleHeightRatio);
-        // Need one extra pixel to account for rounding.
-        int width = (int)Math.ceil(r.width() * scaleWidthRatio) + 1;
-        int height = (int)Math.ceil(r.height() * scaleHeightRatio) + 1;
-        paintImmediately(x, y, width, height);
-      } else {
-        paintImmediately(r.tl.x, r.tl.y, r.width(), r.height());
-      }
-      damage.clear();
-    }
-  }
-
-  // resize() is called when the desktop has changed size
-  public void resize() {
-    int w = cc.cp.width;
-    int h = cc.cp.height;
-    hideLocalCursor();
-    setSize(w, h);
-    setScaledSize();
-    im.resize(w, h);
-  }
-
-  public final void fillRect(int x, int y, int w, int h, int pix) {
-    if (overlapsCursor(x, y, w, h)) hideLocalCursor();
-    im.fillRect(x, y, w, h, pix);
-    damageRect(new Rect(x, y, x+w, y+h));
-    showLocalCursor();
-  }
-
-  public final void imageRect(int x, int y, int w, int h,
-                              Object pix) {
-    if (overlapsCursor(x, y, w, h)) hideLocalCursor();
-    im.imageRect(x, y, w, h, pix);
-    damageRect(new Rect(x, y, x+w, y+h));
-    showLocalCursor();
-  }
-
-  public final void copyRect(int x, int y, int w, int h,
-                             int srcX, int srcY) {
-    if (overlapsCursor(x, y, w, h) || overlapsCursor(srcX, srcY, w, h))
-      hideLocalCursor();
-    im.copyRect(x, y, w, h, srcX, srcY);
-    damageRect(new Rect(x, y, x+w, y+h));
-    showLocalCursor();
-  }
-
-
-  // mutex MUST be held when overlapsCursor() is called
-  final boolean overlapsCursor(int x, int y, int w, int h) {
-    return (x < cursorBackingX + cursorBacking.width() &&
-            y < cursorBackingY + cursorBacking.height() &&
-            x + w > cursorBackingX && y + h > cursorBackingY);
-  }
-
-
-  ////////////////////////////////////////////////////////////////////
-  // The following methods are all called from the GUI thread
-
-  void resetLocalCursor() {
-    if (cc.cp.supportsLocalCursor) {
-      if (softCursor != null)
-        setCursor(softCursor);
-    } else {
-      setCursor(nullCursor);
-    }
-    hideLocalCursor();
-    cursorAvailable = false;
-  }
-
-  //
-  // Callback methods to determine geometry of our Component.
-  //
-
-  public Dimension getPreferredSize() {
-    return new Dimension(scaledWidth, scaledHeight);
-  }
-
-  public Dimension getMinimumSize() {
-    return new Dimension(scaledWidth, scaledHeight);
-  }
-
-  public Dimension getMaximumSize() {
-    return new Dimension(scaledWidth, scaledHeight);
-  }
-
-  public void setScaledSize() {
-    String scaleString = scalingFactor.getValue();
-    if (!scaleString.equalsIgnoreCase("Auto") &&
-        !scaleString.equalsIgnoreCase("FixedRatio")) {
-      int scalingFactor = Integer.parseInt(scaleString);
-      scaledWidth =
-        (int)Math.floor((float)cc.cp.width * (float)scalingFactor/100.0);
-      scaledHeight =
-        (int)Math.floor((float)cc.cp.height * (float)scalingFactor/100.0);
-    } else {
-      if (cc.viewport == null) {
-        scaledWidth = cc.cp.width;
-        scaledHeight = cc.cp.height;
-      } else {
-        Dimension vpSize = cc.viewport.getSize();
-        Insets vpInsets = cc.viewport.getInsets();
-        Dimension availableSize =
-          new Dimension(vpSize.width - vpInsets.left - vpInsets.right,
-                        vpSize.height - vpInsets.top - vpInsets.bottom);
-        if (availableSize.width == 0 || availableSize.height == 0)
-          availableSize = new Dimension(cc.cp.width, cc.cp.height);
-        if (scaleString.equalsIgnoreCase("FixedRatio")) {
-          float widthRatio = (float)availableSize.width / (float)cc.cp.width;
-          float heightRatio = (float)availableSize.height / (float)cc.cp.height;
-          float ratio = Math.min(widthRatio, heightRatio);
-          scaledWidth = (int)Math.floor(cc.cp.width * ratio);
-          scaledHeight = (int)Math.floor(cc.cp.height * ratio);
+    });
+    timer.setRepeats(false);
+    addComponentListener(new ComponentAdapter() {
+      public void componentResized(ComponentEvent e) {
+        if (remoteResize.getValue()) {
+          if (timer.isRunning())
+            timer.restart();
+          else
+            // Try to get the remote size to match our window size, provided
+            // the following conditions are true:
+            //
+            // a) The user has this feature turned on
+            // b) The server supports it
+            // c) We're not still waiting for a chance to handle DesktopSize
+            // d) We're not still waiting for startup fullscreen to kick in
+            if (!firstUpdate && !delayedFullscreen &&
+                remoteResize.getValue() && cc.cp.supportsSetDesktopSize)
+              timer.start();
         } else {
-          scaledWidth = availableSize.width;
-          scaledHeight = availableSize.height;
+          String scaleString = scalingFactor.getValue();
+          if (!scaleString.matches("^[0-9]+$")) {
+            Dimension maxSize = getContentPane().getSize();
+            if ((maxSize.width != viewport.scaledWidth) ||
+                (maxSize.height != viewport.scaledHeight))
+              viewport.setScaledSize(maxSize.width, maxSize.height);
+            if (!scaleString.equals("Auto")) {
+              if (!isMaximized() && !fullscreen_active()) {
+                int dx = getInsets().left + getInsets().right;
+                int dy = getInsets().top + getInsets().bottom;
+                setSize(viewport.scaledWidth+dx, viewport.scaledHeight+dy);
+              }
+            }
+          }
+          repositionViewport();
         }
       }
-    }
-    scaleWidthRatio = (float)scaledWidth / (float)cc.cp.width;
-    scaleHeightRatio = (float)scaledHeight / (float)cc.cp.height;
-  }
+    });
 
-  public void paintComponent(Graphics g) {
-    Graphics2D g2 = (Graphics2D) g;
-    if (cc.cp.width != scaledWidth || cc.cp.height != scaledHeight) {
-      g2.setRenderingHint(RenderingHints.KEY_RENDERING,
-                          RenderingHints.VALUE_RENDER_QUALITY);
-      g2.drawImage(im.getImage(), 0, 0, scaledWidth, scaledHeight, null);
+    pack();
+    if (embed.getValue()) {
+      scroll.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
+      scroll.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
+      VncViewer.setupEmbeddedFrame(scroll);
     } else {
-      g2.drawImage(im.getImage(), 0, 0, null);
+      if (fullScreen.getValue())
+        fullscreen_on();
+      else
+        setVisible(true);
+
+      if (maximize.getValue())
+        setExtendedState(JFrame.MAXIMIZED_BOTH);
     }
-    g2.dispose();
+
   }
 
-  // Mouse-Motion callback function
-  private void mouseMotionCB(MouseEvent e) {
-    if (!viewOnly.getValue() &&
-        e.getX() >= 0 && e.getX() <= scaledWidth &&
-        e.getY() >= 0 && e.getY() <= scaledHeight)
-      cc.writePointerEvent(e);
-    // - If local cursor rendering is enabled then use it
-    if (cursorAvailable) {
-      // - Render the cursor!
-      if (e.getX() != cursorPosX || e.getY() != cursorPosY) {
-        hideLocalCursor();
-        if (e.getX() >= 0 && e.getX() < im.width() &&
-            e.getY() >= 0 && e.getY() < im.height()) {
-          cursorPosX = e.getX();
-          cursorPosY = e.getY();
-          showLocalCursor();
-        }
+  // Remove resize listener in order to prevent recursion when resizing
+  @Override
+  public void setSize(Dimension d)
+  {
+    ComponentListener[] listeners = getListeners(ComponentListener.class);
+    for (ComponentListener l : listeners)
+      removeComponentListener(l);
+    super.setSize(d);
+    for (ComponentListener l : listeners)
+      addComponentListener(l);
+  }
+
+  @Override
+  public void setSize(int width, int height)
+  {
+    ComponentListener[] listeners = getListeners(ComponentListener.class);
+    for (ComponentListener l : listeners)
+      removeComponentListener(l);
+    super.setSize(width, height);
+    for (ComponentListener l : listeners)
+      addComponentListener(l);
+  }
+
+  @Override
+  public void setBounds(Rectangle r)
+  {
+    ComponentListener[] listeners = getListeners(ComponentListener.class);
+    for (ComponentListener l : listeners)
+      removeComponentListener(l);
+    super.setBounds(r);
+    for (ComponentListener l : listeners)
+      addComponentListener(l);
+  }
+
+  private void repositionViewport()
+  {
+    scroll.revalidate();
+    Rectangle r = scroll.getViewportBorderBounds();
+    int dx = r.width - viewport.scaledWidth;
+    int dy = r.height - viewport.scaledHeight;
+    int top = (int)Math.max(Math.floor(dy/2), 0);
+    int left = (int)Math.max(Math.floor(dx/2), 0);
+    int bottom = (int)Math.max(dy - top, 0);
+    int right = (int)Math.max(dx - left, 0);
+    Insets insets = new Insets(top, left, bottom, right);
+    scroll.setViewportBorder(new MatteBorder(insets, Color.BLACK));
+    scroll.revalidate();
+  }
+
+  public PixelFormat getPreferredPF()
+  {
+    return viewport.getPreferredPF();
+  }
+
+  public void setName(String name)
+  {
+    setTitle(name);
+  }
+
+	// Copy the areas of the framebuffer that have been changed (damaged)
+	// to the displayed window.
+
+	public void updateWindow()
+	{
+	  if (firstUpdate) {
+	    if (cc.cp.supportsSetDesktopSize && !desktopSize.getValue().equals("")) {
+	      // Hack: Wait until we're in the proper mode and position until
+	      // resizing things, otherwise we might send the wrong thing.
+	      if (delayedFullscreen)
+	        delayedDesktopSize = true;
+	      else
+	        handleDesktopSize();
+	    }
+	    firstUpdate = false;
+	  }
+
+	  viewport.updateWindow();
+	}
+
+  public void resizeFramebuffer(int new_w, int new_h)
+  {
+    if ((new_w == viewport.scaledWidth) && (new_h == viewport.scaledHeight))
+      return;
+
+    // If we're letting the viewport match the window perfectly, then
+    // keep things that way for the new size, otherwise just keep things
+    // like they are.
+    int dx = getInsets().left + getInsets().right;
+    int dy = getInsets().top + getInsets().bottom;
+    if (!fullscreen_active()) {
+      if ((w() == viewport.scaledWidth) && (h() == viewport.scaledHeight))
+        setSize(new_w+dx, new_h+dy);
+      else {
+        // Make sure the window isn't too big. We do this manually because
+        // we have to disable the window size restriction (and it isn't
+        // entirely trustworthy to begin with).
+        if ((w() > new_w) || (h() > new_h))
+          setSize(Math.min(w(), new_w)+dx, Math.min(h(), new_h)+dy);
       }
     }
-    lastX = e.getX();
-    lastY = e.getY();
-  }
-  public void mouseDragged(MouseEvent e) { mouseMotionCB(e); }
-  public void mouseMoved(MouseEvent e) { mouseMotionCB(e); }
 
-  // Mouse callback function
-  private void mouseCB(MouseEvent e) {
-    if (!viewOnly.getValue()) {
-      if ((e.getID() == MouseEvent.MOUSE_RELEASED) ||
-          (e.getX() >= 0 && e.getX() <= scaledWidth &&
-           e.getY() >= 0 && e.getY() <= scaledHeight))
-        cc.writePointerEvent(e);
-    }
-    lastX = e.getX();
-    lastY = e.getY();
-  }
-  public void mouseReleased(MouseEvent e) { mouseCB(e); }
-  public void mousePressed(MouseEvent e) { mouseCB(e); }
-  public void mouseClicked(MouseEvent e) {}
-  public void mouseEntered(MouseEvent e) {
-    if (embed.getValue())
-      requestFocus();
-  }
-  public void mouseExited(MouseEvent e) {}
+    viewport.resize(0, 0, new_w, new_h);
 
-  // MouseWheel callback function
-  private void mouseWheelCB(MouseWheelEvent e) {
-    if (!viewOnly.getValue())
-      cc.writeWheelEvent(e);
+    // We might not resize the main window, so we need to manually call this
+    // to make sure the viewport is centered.
+    repositionViewport();
+
+    // repositionViewport() makes sure the scroll widget notices any changes
+    // in position, but it might be just the size that changes so we also
+    // need a poke here as well.
+    validate();
   }
 
-  public void mouseWheelMoved(MouseWheelEvent e) {
-    mouseWheelCB(e);
+  public void setCursor(int width, int height, Point hotspot,
+                        byte[] data, byte[] mask)
+  {
+    viewport.setCursor(width, height, hotspot, data, mask);
   }
 
-  private static final Integer keyEventLock = 0; 
+  public void fullscreen_on()
+  {
+    fullScreen.setParam(true);
+    lastState = getExtendedState();
+    lastBounds = getBounds();
+    dispose();
+    // Screen bounds calculation affected by maximized window?
+    setExtendedState(JFrame.NORMAL);
+    setUndecorated(true);
+    setVisible(true);
+    setBounds(getScreenBounds());
+  }
 
-  // Handle the key-typed event.
-  public void keyTyped(KeyEvent e) { }
+  public void fullscreen_off()
+  {
+    fullScreen.setParam(false);
+    dispose();
+    setUndecorated(false);
+    setExtendedState(lastState);
+    setBounds(lastBounds);
+    setVisible(true);
+  }
 
-  // Handle the key-released event.
-  public void keyReleased(KeyEvent e) {
-    synchronized(keyEventLock) {
-      cc.writeKeyEvent(e);
+  public boolean fullscreen_active()
+  {
+    return isUndecorated();
+  }
+
+  private void handleDesktopSize()
+  {
+    if (!desktopSize.getValue().equals("")) {
+      int width, height;
+
+      // An explicit size has been requested
+
+      if (desktopSize.getValue().split("x").length != 2)
+        return;
+
+      width = Integer.parseInt(desktopSize.getValue().split("x")[0]);
+      height = Integer.parseInt(desktopSize.getValue().split("x")[1]);
+      remoteResize(width, height);
+    } else if (remoteResize.getValue()) {
+      // No explicit size, but remote resizing is on so make sure it
+      // matches whatever size the window ended up being
+      remoteResize(w(), h());
     }
   }
 
-  // Handle the key-pressed event.
-  public void keyPressed(KeyEvent e) {
-    if (e.getKeyCode() == MenuKey.getMenuKeyCode()) {
-      int sx = (scaleWidthRatio == 1.00) ?
-        lastX : (int)Math.floor(lastX * scaleWidthRatio);
-      int sy = (scaleHeightRatio == 1.00) ?
-        lastY : (int)Math.floor(lastY * scaleHeightRatio);
-      java.awt.Point ev = new java.awt.Point(lastX, lastY);
-      ev.translate(sx - lastX, sy - lastY);
-      F8Menu menu = new F8Menu(cc);
-      menu.show(this, (int)ev.getX(), (int)ev.getY());
+  public void handleResizeTimeout()
+  {
+    DesktopWindow self = (DesktopWindow)this;
+
+    assert(self != null);
+
+    self.remoteResize(self.w(), self.h());
+  }
+
+  private void remoteResize(int width, int height)
+  {
+    ScreenSet layout;
+    ListIterator<Screen> iter;
+
+    if (!fullscreen_active() || (width > w()) || (height > h())) {
+      // In windowed mode (or the framebuffer is so large that we need
+      // to scroll) we just report a single virtual screen that covers
+      // the entire framebuffer.
+
+      layout = cc.cp.screenLayout;
+
+      // Not sure why we have no screens, but adding a new one should be
+      // safe as there is nothing to conflict with...
+      if (layout.num_screens() == 0)
+        layout.add_screen(new Screen());
+      else if (layout.num_screens() != 1) {
+        // More than one screen. Remove all but the first (which we
+        // assume is the "primary").
+
+        while (true) {
+          iter = layout.begin();
+          Screen screen = iter.next();
+
+          if (iter == layout.end())
+            break;
+
+          layout.remove_screen(screen.id);
+        }
+      }
+
+      // Resize the remaining single screen to the complete framebuffer
+      ((Screen)layout.begin().next()).dimensions.tl.x = 0;
+      ((Screen)layout.begin().next()).dimensions.tl.y = 0;
+      ((Screen)layout.begin().next()).dimensions.br.x = width;
+      ((Screen)layout.begin().next()).dimensions.br.y = height;
+    } else {
+      layout = new ScreenSet();
+      int id;
+      int sx, sy, sw, sh;
+      Rect viewport_rect = new Rect();
+      Rect screen_rect = new Rect();
+
+      // In full screen we report all screens that are fully covered.
+
+      viewport_rect.setXYWH(x() + (w() - width)/2, y() + (h() - height)/2,
+                            width, height);
+
+      // If we can find a matching screen in the existing set, we use
+      // that, otherwise we create a brand new screen.
+      //
+      // FIXME: We should really track screens better so we can handle
+      //        a resized one.
+      //
+      GraphicsEnvironment ge =
+        GraphicsEnvironment.getLocalGraphicsEnvironment();
+      for (GraphicsDevice gd : ge.getScreenDevices()) {
+        for (GraphicsConfiguration gc : gd.getConfigurations()) {
+          Rectangle bounds = gc.getBounds();
+          sx = bounds.x;
+          sy = bounds.y;
+          sw = bounds.width;
+          sh = bounds.height;
+
+          // Check that the screen is fully inside the framebuffer
+          screen_rect.setXYWH(sx, sy, sw, sh);
+          if (!screen_rect.enclosed_by(viewport_rect))
+            continue;
+
+          // Adjust the coordinates so they are relative to our viewport
+          sx -= viewport_rect.tl.x;
+          sy -= viewport_rect.tl.y;
+
+          // Look for perfectly matching existing screen...
+          for (iter = cc.cp.screenLayout.begin();
+              iter != cc.cp.screenLayout.end(); iter.next()) {
+            Screen screen = iter.next(); iter.previous();
+            if ((screen.dimensions.tl.x == sx) &&
+                (screen.dimensions.tl.y == sy) &&
+                (screen.dimensions.width() == sw) &&
+                (screen.dimensions.height() == sh))
+              break;
+          }
+
+          // Found it?
+          if (iter != cc.cp.screenLayout.end()) {
+            layout.add_screen(iter.next());
+            continue;
+          }
+
+          // Need to add a new one, which means we need to find an unused id
+          Random rng = new Random();
+          while (true) {
+            id = rng.nextInt();
+            for (iter = cc.cp.screenLayout.begin();
+                iter != cc.cp.screenLayout.end(); iter.next()) {
+              Screen screen = iter.next(); iter.previous();
+              if (screen.id == id)
+                break;
+            }
+
+            if (iter == cc.cp.screenLayout.end())
+              break;
+          }
+
+          layout.add_screen(new Screen(id, sx, sy, sw, sh, 0));
+        }
+
+        // If the viewport doesn't match a physical screen, then we might
+        // end up with no screens in the layout. Add a fake one...
+        if (layout.num_screens() == 0)
+          layout.add_screen(new Screen(0, 0, 0, width, height, 0));
+      }
+    }
+
+    // Do we actually change anything?
+    if ((width == cc.cp.width) &&
+        (height == cc.cp.height) &&
+        (layout == cc.cp.screenLayout))
+      return;
+
+    String buffer;
+    vlog.debug(String.format("Requesting framebuffer resize from %dx%d to %dx%d",
+               cc.cp.width, cc.cp.height, width, height));
+    layout.debug_print();
+
+    if (!layout.validate(width, height)) {
+      vlog.error("Invalid screen layout computed for resize request!");
       return;
     }
-    int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
-    if ((e.getModifiers() & ctrlAltShiftMask) == ctrlAltShiftMask) {
-      switch (e.getKeyCode()) {
-        case KeyEvent.VK_A:
-          VncViewer.showAbout(this);
-          return;
-        case KeyEvent.VK_F:
-          cc.toggleFullScreen();
-          return;
-        case KeyEvent.VK_H:
-          cc.refresh();
-          return;
-        case KeyEvent.VK_I:
-          cc.showInfo();
-          return;
-        case KeyEvent.VK_O:
-            OptionsDialog.showDialog(cc.viewport);
-          return;
-        case KeyEvent.VK_W:
-          VncViewer.newViewer();
-          return;
-        case KeyEvent.VK_LEFT:
-        case KeyEvent.VK_RIGHT:
-        case KeyEvent.VK_UP:
-        case KeyEvent.VK_DOWN:
-          return;
-      }
-    }
-    if ((e.getModifiers() & Event.META_MASK) == Event.META_MASK) {
-      switch (e.getKeyCode()) {
-        case KeyEvent.VK_COMMA:
-        case KeyEvent.VK_N:
-        case KeyEvent.VK_W:
-        case KeyEvent.VK_I:
-        case KeyEvent.VK_R:
-        case KeyEvent.VK_L:
-        case KeyEvent.VK_F:
-        case KeyEvent.VK_Z:
-        case KeyEvent.VK_T:
-          return;
-      }
-    }
-    synchronized(keyEventLock) {
-      cc.writeKeyEvent(e);
-    }
+
+    cc.writer().writeSetDesktopSize(width, height, layout);
   }
 
-  ////////////////////////////////////////////////////////////////////
-  // The following methods are called from both RFB and GUI threads
+  boolean lionFSSupported() { return canDoLionFS; }
 
-  // Note that mutex MUST be held when hideLocalCursor() and showLocalCursor()
-  // are called.
+  private int x() { return getContentPane().getX(); }
+  private int y() { return getContentPane().getY(); }
+  private int w() { return getContentPane().getWidth(); }
+  private int h() { return getContentPane().getHeight(); }
 
-  private synchronized void hideLocalCursor() {
-    // - Blit the cursor backing store over the cursor
-    if (cursorVisible) {
-      cursorVisible = false;
-      im.imageRect(cursorBackingX, cursorBackingY, cursorBacking.width(),
-                   cursorBacking.height(), cursorBacking.data);
-      damageRect(new Rect(cursorBackingX, cursorBackingY,
-                          cursorBackingX+cursorBacking.width(),
-                          cursorBackingY+cursorBacking.height()));
-    }
-  }
-
-  private synchronized void showLocalCursor() {
-    if (cursorAvailable && !cursorVisible) {
-      if (!im.getPF().equal(cursor.getPF()) ||
-          cursor.width() == 0 || cursor.height() == 0) {
-        vlog.debug("attempting to render invalid local cursor");
-        cursorAvailable = false;
-        return;
-      }
-      cursorVisible = true;
-
-      int cursorLeft = cursor.hotspot.x;
-      int cursorTop = cursor.hotspot.y;
-      int cursorRight = cursorLeft + cursor.width();
-      int cursorBottom = cursorTop + cursor.height();
-
-      int x = (cursorLeft >= 0 ? cursorLeft : 0);
-      int y = (cursorTop >= 0 ? cursorTop : 0);
-      int w = ((cursorRight < im.width() ? cursorRight : im.width()) - x);
-      int h = ((cursorBottom < im.height() ? cursorBottom : im.height()) - y);
-
-      cursorBackingX = x;
-      cursorBackingY = y;
-      cursorBacking.setSize(w, h);
-
-      for (int j = 0; j < h; j++)
-        System.arraycopy(im.data, (y + j) * im.width() + x,
-                         cursorBacking.data, j * w, w);
-
-      im.maskRect(cursorLeft, cursorTop, cursor.width(), cursor.height(),
-                  cursor.data, cursor.mask);
-      damageRect(new Rect(x, y, x+w, y+h));
-    }
-  }
-
-  void damageRect(Rect r) {
-    if (damage.is_empty()) {
-      damage.setXYWH(r.tl.x, r.tl.y, r.width(), r.height());
-    } else {
-      r = damage.union_boundary(r);
-      damage.setXYWH(r.tl.x, r.tl.y, r.width(), r.height());
-    }
-  }
-
-  // run() is executed by the setColourMapEntriesTimerThread - it sleeps for
-  // 100ms before actually updating the colourmap.
-  public synchronized void run() {
+  void enableLionFS() {
     try {
-      Thread.sleep(100);
-    } catch(InterruptedException e) {}
-    im.updateColourMap();
-    setColourMapEntriesTimerThread = null;
+      String version = System.getProperty("os.version");
+      int firstDot = version.indexOf('.');
+      int lastDot = version.lastIndexOf('.');
+      if (lastDot > firstDot && lastDot >= 0) {
+        version = version.substring(0, version.indexOf('.', firstDot + 1));
+      }
+      double v = Double.parseDouble(version);
+      if (v < 10.7)
+        throw new Exception("Operating system version is " + v);
+
+      Class fsuClass = Class.forName("com.apple.eawt.FullScreenUtilities");
+      Class argClasses[] = new Class[]{Window.class, Boolean.TYPE};
+      Method setWindowCanFullScreen =
+        fsuClass.getMethod("setWindowCanFullScreen", argClasses);
+      setWindowCanFullScreen.invoke(fsuClass, this, true);
+
+      canDoLionFS = true;
+    } catch (Exception e) {
+      vlog.debug("Could not enable OS X 10.7+ full-screen mode: " +
+                 e.getMessage());
+    }
+  }
+
+  public void toggleLionFS() {
+    try {
+      Class appClass = Class.forName("com.apple.eawt.Application");
+      Method getApplication = appClass.getMethod("getApplication",
+                                                 (Class[])null);
+      Object app = getApplication.invoke(appClass);
+      Method requestToggleFullScreen =
+        appClass.getMethod("requestToggleFullScreen", Window.class);
+      requestToggleFullScreen.invoke(app, this);
+    } catch (Exception e) {
+      vlog.debug("Could not toggle OS X 10.7+ full-screen mode: " +
+                 e.getMessage());
+    }
+  }
+
+
+  public boolean isMaximized()
+  {
+    int state = getExtendedState();
+    return ((state & JFrame.MAXIMIZED_BOTH) == JFrame.MAXIMIZED_BOTH);
+  }
+
+  public Dimension getScreenSize() {
+    return getScreenBounds().getSize();
+  }
+
+  public Rectangle getScreenBounds() {
+    GraphicsEnvironment ge =
+      GraphicsEnvironment.getLocalGraphicsEnvironment();
+    Rectangle r = new Rectangle();
+    if (fullScreenAllMonitors.getValue()) {
+      for (GraphicsDevice gd : ge.getScreenDevices())
+        for (GraphicsConfiguration gc : gd.getConfigurations())
+          r = r.union(gc.getBounds());
+    } else {
+      GraphicsConfiguration gc = getGraphicsConfiguration();
+      r = gc.getBounds();
+    }
+    return r;
+  }
+
+  public static Window getFullScreenWindow() {
+    GraphicsEnvironment ge =
+      GraphicsEnvironment.getLocalGraphicsEnvironment();
+    for (GraphicsDevice gd : ge.getScreenDevices()) {
+      Window fullScreenWindow = gd.getFullScreenWindow();
+      if (fullScreenWindow != null)
+        return fullScreenWindow;
+    }
+    return null;
+  }
+
+  public static void setFullScreenWindow(Window fullScreenWindow) {
+    GraphicsEnvironment ge =
+      GraphicsEnvironment.getLocalGraphicsEnvironment();
+    if (fullScreenAllMonitors.getValue()) {
+      for (GraphicsDevice gd : ge.getScreenDevices())
+        gd.setFullScreenWindow(fullScreenWindow);
+    } else {
+      GraphicsDevice gd = ge.getDefaultScreenDevice();
+      gd.setFullScreenWindow(fullScreenWindow);
+    }
   }
 
   public void handleOptions()
   {
-    if (fullScreen.getValue() && Viewport.getFullScreenWindow() == null)
-      cc.toggleFullScreen();
-    else if (!fullScreen.getValue() && Viewport.getFullScreenWindow() != null)
-      cc.toggleFullScreen();
+
+    if (fullScreen.getValue() && !fullscreen_active())
+      fullscreen_on();
+    else if (!fullScreen.getValue() && fullscreen_active())
+      fullscreen_off();
+
+    if (remoteResize.getValue()) {
+      scroll.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
+      scroll.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
+      remoteResize(w(), h());
+    } else {
+      String scaleString = scalingFactor.getValue();
+      if (!scaleString.equals(lastScaleFactor)) {
+        if (scaleString.matches("^[0-9]+$")) {
+          scroll.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
+          scroll.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
+          viewport.setScaledSize(cc.cp.width, cc.cp.height);
+        } else {
+          scroll.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
+          scroll.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);
+          viewport.setScaledSize(w(), h());
+        }
+
+        if (isMaximized() || fullscreen_active()) {
+          repositionViewport();
+        } else {
+          int dx = getInsets().left + getInsets().right;
+          int dy = getInsets().top + getInsets().bottom;
+          setSize(viewport.scaledWidth+dx, viewport.scaledHeight+dy);
+        }
+
+        repositionViewport();
+        lastScaleFactor = scaleString;
+      }
+    }
+
+    if (isVisible()) {
+      toFront();
+      requestFocus();
+    }
   }
 
-  // access to cc by different threads is specified in CConn
-  CConn cc;
+  public void handleFullscreenTimeout()
+  {
+    DesktopWindow self = (DesktopWindow)this;
 
-  // access to the following must be synchronized:
-  PlatformPixelBuffer im;
-  Thread setColourMapEntriesTimerThread;
+    assert(self != null);
 
-  Cursor cursor;
-  boolean cursorVisible = false;     // Is cursor currently rendered?
-  boolean cursorAvailable = false;   // Is cursor available for rendering?
-  int cursorPosX, cursorPosY;
-  ManagedPixelBuffer cursorBacking;
-  int cursorBackingX, cursorBackingY;
-  java.awt.Cursor softCursor, nullCursor;
-  static Toolkit tk = Toolkit.getDefaultToolkit();
+    self.delayedFullscreen = false;
 
-  public int scaledWidth = 0, scaledHeight = 0;
-  float scaleWidthRatio, scaleHeightRatio;
+    if (self.delayedDesktopSize) {
+      self.handleDesktopSize();
+      self.delayedDesktopSize = false;
+    }
+  }
 
-  // the following are only ever accessed by the GUI thread:
-  int lastX, lastY;
-  Rect damage = new Rect();
+  private CConn cc;
+  private JScrollPane scroll;
+  public Viewport viewport;
 
-  static LogWriter vlog = new LogWriter("DesktopWindow");
+  private boolean firstUpdate;
+  private boolean delayedFullscreen;
+  private boolean delayedDesktopSize;
+  private boolean canDoLionFS;
+  private String lastScaleFactor;
+  private Rectangle lastBounds;
+  private int lastState;
+  private Timer timer;
 }
+
diff --git a/java/com/tigervnc/vncviewer/Dialog.java b/java/com/tigervnc/vncviewer/Dialog.java
index 6204ba1..a2fb04f 100644
--- a/java/com/tigervnc/vncviewer/Dialog.java
+++ b/java/com/tigervnc/vncviewer/Dialog.java
@@ -65,9 +65,6 @@
       int y = (dpySize.height - mySize.height) / 2;
       setLocation(x, y);
     }
-    fullScreenWindow = Viewport.getFullScreenWindow();
-    if (fullScreenWindow != null)
-      Viewport.setFullScreenWindow(null);
 
     if (getModalityType() == ModalityType.APPLICATION_MODAL)
       setAlwaysOnTop(true);
@@ -81,9 +78,6 @@
   public void endDialog() {
     setVisible(false);
     setAlwaysOnTop(false);
-    fullScreenWindow = Viewport.getFullScreenWindow();
-    if (fullScreenWindow != null)
-      Viewport.setFullScreenWindow(fullScreenWindow);
   }
 
   // initDialog() can be overridden in a derived class.  Typically it is used
diff --git a/java/com/tigervnc/vncviewer/F8Menu.java b/java/com/tigervnc/vncviewer/F8Menu.java
index d7f9e48..0c67305 100644
--- a/java/com/tigervnc/vncviewer/F8Menu.java
+++ b/java/com/tigervnc/vncviewer/F8Menu.java
@@ -106,19 +106,24 @@
     if (actionMatch(ev, exit)) {
       cc.close();
     } else if (actionMatch(ev, fullScreenCheckbox)) {
-      cc.toggleFullScreen();
+      if (fullScreenCheckbox.isSelected())
+        cc.desktop.fullscreen_on();
+      else
+        cc.desktop.fullscreen_off();
     } else if (actionMatch(ev, restore)) {
-      if (fullScreen.getValue()) cc.toggleFullScreen();
-      cc.viewport.setExtendedState(JFrame.NORMAL);
+      if (cc.desktop.fullscreen_active())
+        cc.desktop.fullscreen_off();
+      cc.desktop.setExtendedState(JFrame.NORMAL);
     } else if (actionMatch(ev, minimize)) {
-      if (fullScreen.getValue()) cc.toggleFullScreen();
-      cc.viewport.setExtendedState(JFrame.ICONIFIED);
+      if (cc.desktop.fullscreen_active())
+        cc.desktop.fullscreen_off();
+      cc.desktop.setExtendedState(JFrame.ICONIFIED);
     } else if (actionMatch(ev, maximize)) {
-      if (fullScreen.getValue()) cc.toggleFullScreen();
-      cc.viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
+      if (cc.desktop.fullscreen_active())
+        cc.desktop.fullscreen_off();
+      cc.desktop.setExtendedState(JFrame.MAXIMIZED_BOTH);
     } else if (actionMatch(ev, clipboard)) {
-      //ClipboardDialog dlg = new ClipboardDialog(cc);
-      ClipboardDialog.showDialog(cc.viewport);
+      ClipboardDialog.showDialog(cc.desktop);
     } else if (actionMatch(ev, f8)) {
       cc.writeKeyEvent(MenuKey.getMenuKeySym(), true);
       cc.writeKeyEvent(MenuKey.getMenuKeySym(), false);
@@ -134,7 +139,7 @@
     } else if (actionMatch(ev, newConn)) {
       VncViewer.newViewer();
     } else if (actionMatch(ev, options)) {
-      OptionsDialog.showDialog(cc.viewport);
+      OptionsDialog.showDialog(cc.desktop);
     } else if (actionMatch(ev, save)) {
 	    String title = "Save the TigerVNC configuration to file";
 	    File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc"));
@@ -170,6 +175,24 @@
     }
   }
 
+  public void show(Component invoker, int x, int y) {
+    // lightweight components can't show in FullScreen Exclusive mode
+    /*
+    Window fsw = DesktopWindow.getFullScreenWindow();
+    GraphicsDevice gd = null;
+    if (fsw != null) {
+      gd = fsw.getGraphicsConfiguration().getDevice();
+      if (gd.isFullScreenSupported())
+        DesktopWindow.setFullScreenWindow(null);
+    }
+    */
+    super.show(invoker, x, y);
+    /*
+    if (fsw != null && gd.isFullScreenSupported())
+      DesktopWindow.setFullScreenWindow(fsw);
+      */
+  }
+
   CConn cc;
   JMenuItem restore, move, size, minimize, maximize;
   JMenuItem exit, clipboard, ctrlAltDel, refresh;
diff --git a/java/com/tigervnc/vncviewer/JavaPixelBuffer.java b/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
new file mode 100644
index 0000000..b639673
--- /dev/null
+++ b/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
@@ -0,0 +1,59 @@
+/* Copyright (C) 2012-2016 Brian P. Hinz
+ * Copyright (C) 2012 D. R. Commander.  All Rights Reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+package com.tigervnc.vncviewer;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.nio.ByteOrder;
+
+import com.tigervnc.rfb.*;
+
+public class JavaPixelBuffer extends PlatformPixelBuffer 
+{
+
+  public JavaPixelBuffer(int w, int h) {
+    super(getPreferredPF(), w, h,
+          getPreferredPF().getColorModel().createCompatibleWritableRaster(w,h));
+  }
+
+  private static PixelFormat getPreferredPF()
+  {
+    GraphicsEnvironment ge =
+      GraphicsEnvironment.getLocalGraphicsEnvironment();
+    GraphicsDevice gd = ge.getDefaultScreenDevice();
+    GraphicsConfiguration gc = gd.getDefaultConfiguration();
+    ColorModel cm = gc.getColorModel();
+    int depth = ((cm.getPixelSize() > 24) ? 24 : cm.getPixelSize());
+    int bpp = (depth > 16 ? 32 : (depth > 8 ? 16 : 8));
+    ByteOrder byteOrder = ByteOrder.nativeOrder();
+    boolean bigEndian = (byteOrder == ByteOrder.BIG_ENDIAN ? true : false);
+    boolean trueColour = true;
+    int redShift    = cm.getComponentSize()[0] + cm.getComponentSize()[1];
+    int greenShift  = cm.getComponentSize()[0];
+    int blueShift   = 0;
+    int redMask   = ((int)Math.pow(2, cm.getComponentSize()[2]) - 1);
+    int greenMask = ((int)Math.pow(2, cm.getComponentSize()[1]) - 1);
+    int blueMmask = ((int)Math.pow(2, cm.getComponentSize()[0]) - 1);
+    return new PixelFormat(bpp, depth, bigEndian, trueColour,
+                           redMask, greenMask, blueMmask,
+                           redShift, greenShift, blueShift);
+  }
+
+}
diff --git a/java/com/tigervnc/vncviewer/OptionsDialog.java b/java/com/tigervnc/vncviewer/OptionsDialog.java
index db27491..a7c8778 100644
--- a/java/com/tigervnc/vncviewer/OptionsDialog.java
+++ b/java/com/tigervnc/vncviewer/OptionsDialog.java
@@ -94,7 +94,7 @@
     }
   }
 
-  private static Map<String, Object> callbacks = new HashMap<String, Object>();
+  private static Map<Object, String> callbacks = new HashMap<Object, String>();
   /* Compression */
   JCheckBox autoselectCheckbox;
 
@@ -140,13 +140,18 @@
   JCheckBox desktopSizeCheckbox;
   JTextField desktopWidthInput;
   JTextField desktopHeightInput;
+
+  ButtonGroup sizingGroup;
+  JRadioButton remoteResizeButton;
+  JRadioButton remoteScaleButton;
+  JComboBox scalingFactorInput;
+
   JCheckBox fullScreenCheckbox;
   JCheckBox fullScreenAllMonitorsCheckbox;
-  JComboBox scalingFactorInput;
 
   /* Misc. */
   JCheckBox sharedCheckbox;
-  JCheckBox localCursorCheckbox;
+  JCheckBox dotWhenNoCursorCheckbox;
   JCheckBox acceptBellCheckbox;
 
   /* SSH */
@@ -190,9 +195,10 @@
     tabPane.addTab("SSH", createSshPanel());
     tabPane.setBorder(BorderFactory.createEmptyBorder());
     // Resize the tabPane if necessary to prevent scrolling
-    Insets tpi =
-      (Insets)UIManager.get("TabbedPane:TabbedPaneTabArea.contentMargins");
-    int minWidth = tpi.left + tpi.right;
+    int minWidth = 0;
+    Object tpi = UIManager.get("TabbedPane:TabbedPaneTabArea.contentMargins");
+    if (tpi != null)
+      minWidth += ((Insets)tpi).left + ((Insets)tpi).right;
     for (int i = 0; i < tabPane.getTabCount(); i++)
       minWidth += tabPane.getBoundsAt(i).width;
     int minHeight = tabPane.getPreferredSize().height;
@@ -215,7 +221,7 @@
     });
 
     JPanel buttonPane = new JPanel(new GridLayout(1, 5, 10, 10));
-    buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
+    buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));
     buttonPane.add(Box.createRigidArea(new Dimension()));
     buttonPane.add(Box.createRigidArea(new Dimension()));
     buttonPane.add(Box.createRigidArea(new Dimension()));
@@ -240,12 +246,12 @@
 
   public static void addCallback(String cb, Object obj)
   {
-    callbacks.put(cb, obj);
+    callbacks.put(obj, cb);
   }
 
-  public static void removeCallback(String cb)
+  public static void removeCallback(Object obj)
   {
-    callbacks.remove(cb);
+    callbacks.remove(obj);
   }
 
   public void endDialog() {
@@ -258,15 +264,18 @@
     fullScreenCheckbox.setEnabled(s);
     fullScreenAllMonitorsCheckbox.setEnabled(s);
     scalingFactorInput.setEnabled(s);
+    Enumeration<AbstractButton> e = sizingGroup.getElements();
+    while (e.hasMoreElements())
+      e.nextElement().setEnabled(s);
   }
 
   private void loadOptions()
   {
     /* Compression */
     autoselectCheckbox.setSelected(autoSelect.getValue());
-  
+
     int encNum = Encodings.encodingNum(preferredEncoding.getValueStr());
-  
+
     switch (encNum) {
     case Encodings.encodingTight:
       tightButton.setSelected(true);
@@ -281,7 +290,7 @@
       rawButton.setSelected(true);
       break;
     }
-  
+
     if (fullColor.getValue())
       fullcolorButton.setSelected(true);
     else {
@@ -323,13 +332,13 @@
     encNoneCheckbox.setSelected(false);
     encTLSCheckbox.setSelected(false);
     encX509Checkbox.setSelected(false);
-  
+
     authNoneCheckbox.setSelected(false);
     authVncCheckbox.setSelected(false);
     authPlainCheckbox.setSelected(false);
     authIdentCheckbox.setSelected(false);
     sendLocalUsernameCheckbox.setSelected(sendLocalUsername.getValue());
-  
+
     secTypes = security.GetEnabledSecTypes();
     for (iter = secTypes.iterator(); iter.hasNext(); ) {
       switch ((Integer)iter.next()) {
@@ -343,7 +352,7 @@
         break;
       }
     }
-  
+
     secTypesExt = security.GetEnabledExtSecTypes();
     for (iterExt = secTypesExt.iterator(); iterExt.hasNext(); ) {
       switch ((Integer)iterExt.next()) {
@@ -404,14 +413,14 @@
     viewOnlyCheckbox.setSelected(viewOnly.getValue());
     acceptClipboardCheckbox.setSelected(acceptClipboard.getValue());
     sendClipboardCheckbox.setSelected(sendClipboard.getValue());
-  
+
     menuKeyChoice.setSelectedIndex(0);
-  
+
     String menuKeyStr = menuKey.getValueStr();
     for (int i = 0; i < menuKeyChoice.getItemCount(); i++)
       if (menuKeyStr.equals(menuKeyChoice.getItemAt(i)))
         menuKeyChoice.setSelectedIndex(i);
-  
+
     /* Screen */
     String width, height;
 
@@ -427,6 +436,10 @@
       height = desktopSize.getValueStr().split("x")[1];
       desktopHeightInput.setText(height);
     }
+    if (remoteResize.getValue())
+      remoteResizeButton.setSelected(true);
+    else
+      remoteScaleButton.setSelected(true);
     fullScreenCheckbox.setSelected(fullScreen.getValue());
     fullScreenAllMonitorsCheckbox.setSelected(fullScreenAllMonitors.getValue());
 
@@ -434,15 +447,17 @@
     String scaleStr = scalingFactor.getValueStr();
     if (scaleStr.matches("^[0-9]+$"))
       scaleStr = scaleStr.concat("%");
+    if (scaleStr.matches("^FixedRatio$"))
+      scaleStr = new String("Fixed Aspect Ratio");
     for (int i = 0; i < scalingFactorInput.getItemCount(); i++)
       if (scaleStr.equals(scalingFactorInput.getItemAt(i)))
         scalingFactorInput.setSelectedIndex(i);
 
     handleDesktopSize();
-  
+
     /* Misc. */
     sharedCheckbox.setSelected(shared.getValue());
-    localCursorCheckbox.setSelected(useLocalCursor.getValue());
+    dotWhenNoCursorCheckbox.setSelected(dotWhenNoCursor.getValue());
     acceptBellCheckbox.setSelected(acceptBell.getValue());
 
     /* SSH */
@@ -556,7 +571,7 @@
     File crlFile = new File(crlInput.getText());
     if (crlFile.exists() && crlFile.canRead())
       CSecurityTLS.X509CRL.setParam(crlFile.getAbsolutePath());
- 
+
     /* Input */
     viewOnly.setParam(viewOnlyCheckbox.isSelected());
     acceptClipboard.setParam(acceptClipboardCheckbox.isSelected());
@@ -576,18 +591,18 @@
     } else {
       desktopSize.setParam("");
     }
+    remoteResize.setParam(remoteResizeButton.isSelected());
     fullScreen.setParam(fullScreenCheckbox.isSelected());
     fullScreenAllMonitors.setParam(fullScreenAllMonitorsCheckbox.isSelected());
 
     String scaleStr =
       ((String)scalingFactorInput.getSelectedItem()).replace("%", "");
-    if (scaleStr.equals("Fixed Aspect Ratio"))
-      scaleStr = "FixedRatio";
+    scaleStr.replace("Fixed Aspect Ratio", "FixedRatio");
     scalingFactor.setParam(scaleStr);
 
     /* Misc. */
     shared.setParam(sharedCheckbox.isSelected());
-    useLocalCursor.setParam(localCursorCheckbox.isSelected());
+    dotWhenNoCursor.setParam(dotWhenNoCursorCheckbox.isSelected());
     acceptBell.setParam(acceptBellCheckbox.isSelected());
 
     /* SSH */
@@ -614,9 +629,11 @@
       sshKeyFile.setParam(sshKeyFileInput.getText());
 
     try {
-      for (Map.Entry<String, Object> iter : callbacks.entrySet()) {
-        Object obj = iter.getValue();
-        Method cb = obj.getClass().getMethod(iter.getKey(), new Class[]{});
+      for (Map.Entry<Object, String> iter : callbacks.entrySet()) {
+        Object obj = iter.getKey();
+        Method cb = obj.getClass().getMethod(iter.getValue(), new Class[]{});
+        if (cb == null)
+          vlog.info(obj.getClass().getName());
         cb.invoke(obj);
       }
     } catch (NoSuchMethodException e) {
@@ -1015,6 +1032,9 @@
   private JPanel createScreenPanel() {
     JPanel ScreenPanel = new JPanel(new GridBagLayout());
     ScreenPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
+
+    JPanel SizingPanel = new JPanel(new GridBagLayout());
+    SizingPanel.setBorder(BorderFactory.createTitledBorder("Desktop Sizing"));
     desktopSizeCheckbox = new JCheckBox("Resize remote session on connect");
     desktopSizeCheckbox.addItemListener(new ItemListener() {
       public void itemStateChanged(ItemEvent e) {
@@ -1028,16 +1048,28 @@
     desktopSizePanel.add(desktopWidthInput);
     desktopSizePanel.add(new JLabel(" x "));
     desktopSizePanel.add(desktopHeightInput);
-    fullScreenCheckbox = new JCheckBox("Full-screen mode");
-    fullScreenAllMonitorsCheckbox =
-      new JCheckBox("Enable full-screen mode over all monitors");
+    sizingGroup = new ButtonGroup();
+    remoteResizeButton =
+      new JRadioButton("Resize remote session to the local window");
+    sizingGroup.add(remoteResizeButton);
+    remoteScaleButton =
+      new JRadioButton("Scale remote session to the local window");
+    sizingGroup.add(remoteScaleButton);
+    remoteResizeButton.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        handleRemoteResize();
+      }
+    });
     JLabel scalingFactorLabel = new JLabel("Scaling Factor");
     Object[] scalingFactors = {
       "Auto", "Fixed Aspect Ratio", "50%", "75%", "95%", "100%", "105%",
       "125%", "150%", "175%", "200%", "250%", "300%", "350%", "400%" };
     scalingFactorInput = new MyJComboBox(scalingFactors);
     scalingFactorInput.setEditable(true);
-    ScreenPanel.add(desktopSizeCheckbox,
+    fullScreenCheckbox = new JCheckBox("Full-screen mode");
+    fullScreenAllMonitorsCheckbox =
+      new JCheckBox("Enable full-screen mode over all monitors");
+    SizingPanel.add(desktopSizeCheckbox,
                     new GridBagConstraints(0, 0,
                                            REMAINDER, 1,
                                            LIGHT, LIGHT,
@@ -1045,44 +1077,66 @@
                                            new Insets(0, 0, 0, 0),
                                            NONE, NONE));
     int indent = getButtonLabelInset(desktopSizeCheckbox);
-    ScreenPanel.add(desktopSizePanel,
+    SizingPanel.add(desktopSizePanel,
                     new GridBagConstraints(0, 1,
                                            REMAINDER, 1,
                                            LIGHT, LIGHT,
                                            LINE_START, NONE,
                                            new Insets(0, indent, 0, 0),
                                            NONE, NONE));
-    ScreenPanel.add(fullScreenCheckbox,
+    SizingPanel.add(remoteResizeButton,
                     new GridBagConstraints(0, 2,
                                            REMAINDER, 1,
                                            LIGHT, LIGHT,
                                            LINE_START, NONE,
                                            new Insets(0, 0, 4, 0),
                                            NONE, NONE));
+    SizingPanel.add(remoteScaleButton,
+                    new GridBagConstraints(0, 3,
+                                           REMAINDER, 1,
+                                           LIGHT, LIGHT,
+                                           LINE_START, NONE,
+                                           new Insets(0, 0, 4, 0),
+                                           NONE, NONE));
+    indent = getButtonLabelInset(remoteScaleButton);
+    SizingPanel.add(scalingFactorLabel,
+                    new GridBagConstraints(0, 4,
+                                           1, 1,
+                                           LIGHT, LIGHT,
+                                           LINE_START, NONE,
+                                           new Insets(0, indent, 4, 0),
+                                           NONE, NONE));
+    SizingPanel.add(scalingFactorInput,
+                    new GridBagConstraints(1, 4,
+                                           1, 1,
+                                           HEAVY, LIGHT,
+                                           LINE_START, NONE,
+                                           new Insets(0, 5, 4, 0),
+                                           NONE, NONE));
+    ScreenPanel.add(SizingPanel,
+                    new GridBagConstraints(0, 0,
+                                           REMAINDER, 1,
+                                           LIGHT, LIGHT,
+                                           LINE_START, HORIZONTAL,
+                                           new Insets(0, 0, 4, 0),
+                                           NONE, NONE));
+    ScreenPanel.add(fullScreenCheckbox,
+                    new GridBagConstraints(0, 1,
+                                           REMAINDER, 1,
+                                           LIGHT, LIGHT,
+                                           LINE_START, NONE,
+                                           new Insets(0, 0, 4, 0),
+                                           NONE, NONE));
     indent = getButtonLabelInset(fullScreenCheckbox);
     ScreenPanel.add(fullScreenAllMonitorsCheckbox,
-                    new GridBagConstraints(0, 3,
+                    new GridBagConstraints(0, 2,
                                            REMAINDER, 1,
                                            LIGHT, LIGHT,
                                            LINE_START, NONE,
                                            new Insets(0, indent, 4, 0),
                                            NONE, NONE));
-    ScreenPanel.add(scalingFactorLabel,
-                    new GridBagConstraints(0, 4,
-                                           1, 1,
-                                           LIGHT, LIGHT,
-                                           LINE_START, NONE,
-                                           new Insets(0, 0, 4, 0),
-                                           NONE, NONE));
-    ScreenPanel.add(scalingFactorInput,
-                    new GridBagConstraints(1, 4,
-                                           1, 1,
-                                           HEAVY, LIGHT,
-                                           LINE_START, NONE,
-                                           new Insets(0, 5, 4, 0),
-                                           NONE, NONE));
     ScreenPanel.add(Box.createRigidArea(new Dimension(5, 0)),
-                    new GridBagConstraints(0, 5,
+                    new GridBagConstraints(0, 3,
                                            REMAINDER, REMAINDER,
                                            HEAVY, HEAVY,
                                            LINE_START, BOTH,
@@ -1096,7 +1150,7 @@
     MiscPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
     sharedCheckbox =
       new JCheckBox("Shared (don't disconnect other viewers)");
-    localCursorCheckbox = new JCheckBox("Render cursor locally");
+    dotWhenNoCursorCheckbox = new JCheckBox("Show dot when no cursor");
     acceptBellCheckbox = new JCheckBox("Beep when requested by the server");
     MiscPanel.add(sharedCheckbox,
                   new GridBagConstraints(0, 0,
@@ -1105,7 +1159,7 @@
                                          LINE_START, NONE,
                                          new Insets(0, 0, 4, 0),
                                          NONE, NONE));
-    MiscPanel.add(localCursorCheckbox,
+    MiscPanel.add(dotWhenNoCursorCheckbox,
                   new GridBagConstraints(0, 1,
                                          1, 1,
                                          LIGHT, LIGHT,
@@ -1472,6 +1526,11 @@
     desktopHeightInput.setEnabled(desktopSizeCheckbox.isSelected());
   }
 
+  private void handleRemoteResize()
+  {
+    scalingFactorInput.setEnabled(!remoteResizeButton.isSelected());
+  }
+
   private void handleTunnel()
   {
     viaCheckbox.setEnabled(tunnelCheckbox.isSelected());
@@ -1533,6 +1592,8 @@
       desktopSizeCheckbox.setEnabled(false);
       desktopWidthInput.setEnabled(false);
       desktopHeightInput.setEnabled(false);
+      remoteResizeButton.setEnabled(false);
+      remoteScaleButton.setEnabled(false);
       fullScreenCheckbox.setEnabled(false);
       fullScreenAllMonitorsCheckbox.setEnabled(false);
       scalingFactorInput.setEnabled(false);
diff --git a/java/com/tigervnc/vncviewer/Parameters.java b/java/com/tigervnc/vncviewer/Parameters.java
index e6b91c3..50e26cb 100644
--- a/java/com/tigervnc/vncviewer/Parameters.java
+++ b/java/com/tigervnc/vncviewer/Parameters.java
@@ -31,168 +31,167 @@
 
 public class Parameters {
 
-
   public static BoolParameter noLionFS
   = new BoolParameter("NoLionFS",
-  "On Mac systems, setting this parameter will force the use of the old "+
-  "(pre-Lion) full-screen mode, even if the viewer is running on OS X 10.7 "+
-  "Lion or later.",
-  false);
+    "On Mac systems, setting this parameter will force the use of the old "+
+    "(pre-Lion) full-screen mode, even if the viewer is running on OS X 10.7 "+
+    "Lion or later.",
+    false);
 
   public static BoolParameter embed
   = new BoolParameter("Embed",
-  "If the viewer is being run as an applet, display its output to " +
-  "an embedded frame in the browser window rather than to a dedicated " +
-  "window. Embed=1 implies FullScreen=0 and Scale=100.",
-  false);
+    "If the viewer is being run as an applet, display its output to " +
+    "an embedded frame in the browser window rather than to a dedicated " +
+    "window. Embed=1 implies FullScreen=0 and Scale=100.",
+    false);
 
-  public static BoolParameter useLocalCursor
-  = new BoolParameter("UseLocalCursor",
-                      "Render the mouse cursor locally",
-                      true);
+  public static BoolParameter dotWhenNoCursor
+  = new BoolParameter("DotWhenNoCursor",
+    "Show the dot cursor when the server sends an invisible cursor",
+    false);
 
   public static BoolParameter sendLocalUsername
   = new BoolParameter("SendLocalUsername",
-                      "Send the local username for SecurityTypes "+
-                      "such as Plain rather than prompting",
-                      true);
+    "Send the local username for SecurityTypes "+
+    "such as Plain rather than prompting",
+    true);
 
   public static StringParameter passwordFile
   = new StringParameter("PasswordFile",
-                        "Password file for VNC authentication",
-                        "");
+    "Password file for VNC authentication",
+    "");
 
   public static AliasParameter passwd
   = new AliasParameter("passwd",
-                       "Alias for PasswordFile",
-                       passwordFile);
+    "Alias for PasswordFile",
+    passwordFile);
 
   public static BoolParameter autoSelect
   = new BoolParameter("AutoSelect",
-                      "Auto select pixel format and encoding",
-                      true);
+    "Auto select pixel format and encoding",
+    true);
 
   public static BoolParameter fullColor
   = new BoolParameter("FullColor",
-                      "Use full color - otherwise 6-bit colour is "+
-                      "used until AutoSelect decides the link is "+
-                      "fast enough",
-                      true);
+    "Use full color - otherwise 6-bit colour is used "+
+    "until AutoSelect decides the link is fast enough",
+    true);
 
   public static AliasParameter fullColorAlias
   = new AliasParameter("FullColour",
-                       "Alias for FullColor",
-                       Parameters.fullColor);
+    "Alias for FullColor",
+    Parameters.fullColor);
 
   public static IntParameter lowColorLevel
   = new IntParameter("LowColorLevel",
-                     "Color level to use on slow connections. "+
-                     "0 = Very Low (8 colors), 1 = Low (64 colors), "+
-                     "2 = Medium (256 colors)",
-                     2);
+    "Color level to use on slow connections. "+
+    "0 = Very Low (8 colors), 1 = Low (64 colors), "+
+    "2 = Medium (256 colors)",
+    2);
 
   public static AliasParameter lowColorLevelAlias
   = new AliasParameter("LowColourLevel",
-                       "Alias for LowColorLevel",
-                       lowColorLevel);
+    "Alias for LowColorLevel",
+    lowColorLevel);
 
   public static StringParameter preferredEncoding
   = new StringParameter("PreferredEncoding",
-                        "Preferred encoding to use (Tight, ZRLE, "+
-                        "hextile or raw) - implies AutoSelect=0",
-                        "Tight");
+    "Preferred encoding to use (Tight, ZRLE, "+
+    "hextile or raw) - implies AutoSelect=0",
+    "Tight");
+
+  public static BoolParameter remoteResize
+  = new BoolParameter("RemoteResize",
+    "Dynamically resize the remote desktop size as "+
+    "the size of the local client window changes. "+
+    "(Does not work with all servers)",
+    true);
 
   public static BoolParameter viewOnly
   = new BoolParameter("ViewOnly",
-                      "Don't send any mouse or keyboard events to "+
-                      "the server",
-                      false);
+    "Don't send any mouse or keyboard events to the server",
+    false);
 
   public static BoolParameter shared
   = new BoolParameter("Shared",
-                      "Don't disconnect other viewers upon "+
-                      "connection - share the desktop instead",
-                      false);
+    "Don't disconnect other viewers upon "+
+    "connection - share the desktop instead",
+    false);
+
+  public static BoolParameter maximize
+  = new BoolParameter("Maximize",
+    "Maximize viewer window",
+    false);
 
   public static BoolParameter fullScreen
   = new BoolParameter("FullScreen",
-                      "Full Screen Mode",
-                      false);
+    "Full Screen Mode",
+    false);
 
   public static BoolParameter fullScreenAllMonitors
   = new BoolParameter("FullScreenAllMonitors",
-                      "Enable full screen over all monitors",
-                      true);
+    "Enable full screen over all monitors",
+    true);
 
   public static BoolParameter acceptClipboard
   = new BoolParameter("AcceptClipboard",
-                      "Accept clipboard changes from the server",
-                      true);
+    "Accept clipboard changes from the server",
+    true);
 
   public static BoolParameter sendClipboard
   = new BoolParameter("SendClipboard",
-                      "Send clipboard changes to the server",
-                      true);
+    "Send clipboard changes to the server",
+    true);
 
   public static IntParameter maxCutText
   = new IntParameter("MaxCutText",
-                     "Maximum permitted length of an outgoing clipboard update",
-                     262144);
+    "Maximum permitted length of an outgoing clipboard update",
+    262144);
 
   public static StringParameter menuKey
   = new StringParameter("MenuKey",
-                        "The key which brings up the popup menu",
-                        "F8");
+    "The key which brings up the popup menu",
+    "F8");
 
   public static StringParameter desktopSize
   = new StringParameter("DesktopSize",
-                        "Reconfigure desktop size on the server on "+
-                        "connect (if possible)", "");
+    "Reconfigure desktop size on the server on connect (if possible)",
+    "");
 
   public static BoolParameter listenMode
   = new BoolParameter("listen",
-                      "Listen for connections from VNC servers",
-                      false);
+    "Listen for connections from VNC servers",
+    false);
 
   public static StringParameter scalingFactor
   = new StringParameter("ScalingFactor",
-                        "Reduce or enlarge the remote desktop image. "+
-                        "The value is interpreted as a scaling factor "+
-                        "in percent. If the parameter is set to "+
-                        "\"Auto\", then automatic scaling is "+
-                        "performed. Auto-scaling tries to choose a "+
-                        "scaling factor in such a way that the whole "+
-                        "remote desktop will fit on the local screen. "+
-                        "If the parameter is set to \"FixedRatio\", "+
-                        "then automatic scaling is performed, but the "+
-                        "original aspect ratio is preserved.",
-                        "100");
+    "Reduce or enlarge the remote desktop image. "+
+    "The value is interpreted as a scaling factor "+
+    "in percent. If the parameter is set to "+
+    "\"Auto\", then automatic scaling is "+
+    "performed. Auto-scaling tries to choose a "+
+    "scaling factor in such a way that the whole "+
+    "remote desktop will fit on the local screen. "+
+    "If the parameter is set to \"FixedRatio\", "+
+    "then automatic scaling is performed, but the "+
+    "original aspect ratio is preserved.",
+    "100");
 
   public static BoolParameter alwaysShowServerDialog
   = new BoolParameter("AlwaysShowServerDialog",
-                      "Always show the server dialog even if a server "+
-                      "has been specified in an applet parameter or on "+
-                      "the command line",
-                      false);
+    "Always show the server dialog even if a server has been "+
+    "specified in an applet parameter or on the command line",
+    false);
 
   public static StringParameter vncServerName
   = new StringParameter("Server",
-                        "The VNC server <host>[:<dpyNum>] or "+
-                        "<host>::<port>",
-                        "");
-
-  /*
-  public static IntParameter vncServerPort
-  = new IntParameter("Port",
-                     "The VNC server's port number, assuming it is on "+
-                     "the host from which the applet was downloaded",
-                     0);
-  */
+    "The VNC server <host>[:<dpyNum>] or <host>::<port>",
+    "");
 
   public static BoolParameter acceptBell
   = new BoolParameter("AcceptBell",
-                      "Produce a system beep when requested to by the server.",
-                      true);
+    "Produce a system beep when requested to by the server.",
+    true);
 
   public static StringParameter via
   = new StringParameter("Via",
@@ -271,28 +270,26 @@
 
   public static BoolParameter customCompressLevel
   = new BoolParameter("CustomCompressLevel",
-                      "Use custom compression level. "+
-                      "Default if CompressLevel is specified.",
-                      false);
+    "Use custom compression level. Default if CompressLevel is specified.",
+    false);
 
   public static IntParameter compressLevel
   = new IntParameter("CompressLevel",
-                     "Use specified compression level "+
-                     "0 = Low, 6 = High",
-                     1);
+    "Use specified compression level. 0 = Low, 6 = High",
+    1);
 
   public static BoolParameter noJpeg
   = new BoolParameter("NoJPEG",
-                      "Disable lossy JPEG compression in Tight encoding.",
-                      false);
+    "Disable lossy JPEG compression in Tight encoding.",
+    false);
 
   public static IntParameter qualityLevel
   = new IntParameter("QualityLevel",
-                     "JPEG quality level. "+
-                     "0 = Low, 9 = High",
-                     8);
+    "JPEG quality level. 0 = Low, 9 = High",
+    8);
 
-  private static final String IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0";
+  private static final String IDENTIFIER_STRING
+  = "TigerVNC Configuration file Version 1.0";
 
   static VoidParameter[] parameterArray = {
     CSecurityTLS.X509CA,
@@ -306,16 +303,17 @@
     compressLevel,
     noJpeg,
     qualityLevel,
+    maximize,
     fullScreen,
     fullScreenAllMonitors,
     desktopSize,
+    remoteResize,
     viewOnly,
     shared,
     acceptClipboard,
     sendClipboard,
     menuKey,
     noLionFS,
-    useLocalCursor,
     sendLocalUsername,
     maxCutText,
     scalingFactor,
@@ -333,7 +331,7 @@
   static LogWriter vlog = new LogWriter("Parameters");
 
 	public static void saveViewerParameters(String filename, String servername) {
-	
+
 	  // Write to the registry or a predefined file if no filename was specified.
     String filepath;
     if (filename == null || filename.isEmpty()) {
@@ -349,13 +347,13 @@
     } else {
       filepath = filename;
     }
-	
+
 	  /* Write parameters to file */
     File f = new File(filepath);
     if (f.exists() && !f.canWrite())
 	    throw new Exception(String.format("Failed to write configuration file,"+
                                         "can't open %s", filepath)); 
-	  
+
     PrintWriter pw = null;
     try {
       pw = new PrintWriter(f, "UTF-8");
@@ -365,12 +363,12 @@
 
     pw.println(IDENTIFIER_STRING);
     pw.println("");
-	
+
 	  if (servername != null && !servername.isEmpty()) {
 	    pw.println(String.format("ServerName=%s\n", servername));
       updateConnHistory(servername);
     }
-	  
+
     for (int i = 0; i < parameterArray.length; i++) {
       if (parameterArray[i] instanceof StringParameter) {
         //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
@@ -432,7 +430,7 @@
 
     int lineNr = 0;
     while (line != null) {
-      
+
       // Read the next line
       try {
         line = reader.readLine();
@@ -449,7 +447,7 @@
         if(line.equals(IDENTIFIER_STRING))
           continue;
         else
-          throw new Exception(String.format(new String("Configuration file %s is in an invalid format"), filename));
+          throw new Exception(String.format("Configuration file %s is in an invalid format", filename));
       }
 
       // Skip empty lines and comments
@@ -551,13 +549,13 @@
   }
 
   public static String loadFromReg() {
-  
+
     String hKey = "global";
-  
+
     String servername = UserPreferences.get(hKey, "ServerName");
     if (servername == null)
       servername = "";
-    
+
     for (int i = 0; i < parameterArray.length; i++) {
       if (parameterArray[i] instanceof StringParameter) {
         if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
@@ -582,7 +580,7 @@
                    parameterArray[i].getName()));
       }
     }
-  
+
     return servername;
   }
 
diff --git a/java/com/tigervnc/vncviewer/PlatformPixelBuffer.java b/java/com/tigervnc/vncviewer/PlatformPixelBuffer.java
index 8fc2760..564eb8e 100644
--- a/java/com/tigervnc/vncviewer/PlatformPixelBuffer.java
+++ b/java/com/tigervnc/vncviewer/PlatformPixelBuffer.java
@@ -24,84 +24,38 @@
 import java.nio.ByteOrder;
 
 import com.tigervnc.rfb.*;
+import com.tigervnc.rfb.Point;
 
-abstract public class PlatformPixelBuffer extends PixelBuffer
+public class PlatformPixelBuffer extends FullFramePixelBuffer
 {
-  public PlatformPixelBuffer(PixelFormat pf, int w, int h, DesktopWindow desktop_) {
-    desktop = desktop_;
-    PixelFormat nativePF = getNativePF();
-    if (nativePF.depth > pf.depth) {
-      setPF(pf);
-    } else {
-      setPF(nativePF);
-    }
-    resize(w, h);
+  public PlatformPixelBuffer(PixelFormat pf,
+                             int w, int h,
+                             WritableRaster data)
+  {
+    super(pf, w, h, data);
+    damage = new Rect(0, 0, w, h);
   }
 
-  // resize() resizes the image, preserving the image data where possible.
-  abstract public void resize(int w, int h);
-
-  public PixelFormat getNativePF() {
-    PixelFormat pf;
-    cm = tk.getColorModel();
-    if (cm.getColorSpace().getType() == java.awt.color.ColorSpace.TYPE_RGB) {
-      int depth = ((cm.getPixelSize() > 24) ? 24 : cm.getPixelSize());
-      int bpp = (depth > 16 ? 32 : (depth > 8 ? 16 : 8));
-      ByteOrder byteOrder = ByteOrder.nativeOrder();
-      boolean bigEndian = (byteOrder == ByteOrder.BIG_ENDIAN ? true : false);
-      boolean trueColour = (depth > 8 ? true : false);
-      int redShift    = cm.getComponentSize()[0] + cm.getComponentSize()[1];
-      int greenShift  = cm.getComponentSize()[0];
-      int blueShift   = 0;
-      pf = new PixelFormat(bpp, depth, bigEndian, trueColour,
-        (depth > 8 ? 0xff : 0),
-        (depth > 8 ? 0xff : 0),
-        (depth > 8 ? 0xff : 0),
-        (depth > 8 ? redShift : 0),
-        (depth > 8 ? greenShift : 0),
-        (depth > 8 ? blueShift : 0));
-    } else {
-      pf = new PixelFormat(8, 8, false, false, 7, 7, 3, 0, 3, 6);
-    }
-    vlog.debug("Native pixel format is "+pf.print());
-    return pf;
-  }
-
-  abstract public void imageRect(int x, int y, int w, int h, Object pix);
-
-  // setColourMapEntries() changes some of the entries in the colourmap.
-  // However these settings won't take effect until updateColourMap() is
-  // called.  This is because getting java to recalculate its internal
-  // translation table and redraw the screen is expensive.
-
-  public void setColourMapEntries(int firstColour, int nColours_,
-                                               int[] rgbs) {
-    nColours = nColours_;
-    reds = new byte[nColours];
-    blues = new byte[nColours];
-    greens = new byte[nColours];
-    for (int i = 0; i < nColours; i++) {
-      reds[firstColour+i] = (byte)(rgbs[i*3]   >> 8);
-      greens[firstColour+i] = (byte)(rgbs[i*3+1] >> 8);
-      blues[firstColour+i] = (byte)(rgbs[i*3+2] >> 8);
+  public void commitBufferRW(Rect r)
+  {
+    super.commitBufferRW(r);
+    synchronized(damage) {
+      Rect n = damage.union_boundary(r);
+      damage.setXYWH(n.tl.x, n.tl.y, n.width(), n.height());
     }
   }
 
-  public void updateColourMap() {
-    cm = new IndexColorModel(8, nColours, reds, greens, blues);
+  public Rect getDamage() {
+    Rect r = new Rect();
+
+    synchronized(damage) {
+      r.setXYWH(damage.tl.x, damage.tl.y, damage.width(), damage.height());
+      damage.clear();
+    }
+
+    return r;
   }
 
-  protected static Toolkit tk = Toolkit.getDefaultToolkit();
+  protected Rect damage;
 
-  abstract public Image getImage();
-
-  protected Image image;
-
-  int nColours;
-  byte[] reds;
-  byte[] greens;
-  byte[] blues;
-
-  DesktopWindow desktop;
-  static LogWriter vlog = new LogWriter("PlatformPixelBuffer");
 }
diff --git a/java/com/tigervnc/vncviewer/Viewport.java b/java/com/tigervnc/vncviewer/Viewport.java
index 3a5fb54..bf07d2d 100644
--- a/java/com/tigervnc/vncviewer/Viewport.java
+++ b/java/com/tigervnc/vncviewer/Viewport.java
@@ -1,6 +1,8 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright (C) 2011-2015 Brian P. Hinz
- * Copyright (C) 2012-2013 D. R. Commander.  All Rights Reserved.
+ * Copyright (C) 2006 Constantin Kaplinsky.  All Rights Reserved.
+ * Copyright (C) 2009 Paul Donohue.  All Rights Reserved.
+ * Copyright (C) 2010, 2012-2013 D. R. Commander.  All Rights Reserved.
+ * Copyright (C) 2011-2014 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,201 +20,443 @@
  * USA.
  */
 
-package com.tigervnc.vncviewer;
+//
+// DesktopWindow is an AWT Canvas representing a VNC desktop.
+//
+// Methods on DesktopWindow are called from both the GUI thread and the thread
+// which processes incoming RFB messages ("the RFB thread").  This means we
+// need to be careful with synchronization here.
+//
 
+package com.tigervnc.vncviewer;
+import java.awt.*;
 import java.awt.Color;
+import java.awt.color.ColorSpace;
 import java.awt.event.*;
-import java.awt.Dimension;
-import java.awt.Event;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Insets;
-import java.awt.Window;
-import java.lang.reflect.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.Clipboard;
+import java.io.BufferedReader;
+import java.nio.*;
 import javax.swing.*;
 
-import com.tigervnc.rfb.*;
-import java.lang.Exception;
-import java.awt.Rectangle;
+import javax.imageio.*;
+import java.io.*;
 
-import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
-import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER;
-import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
-import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
+import com.tigervnc.rfb.*;
+import com.tigervnc.rfb.Cursor;
+import com.tigervnc.rfb.Point;
 
 import static com.tigervnc.vncviewer.Parameters.*;
 
-public class Viewport extends JFrame
-{
-  public Viewport(String name, CConn cc_) {
+class Viewport extends JPanel implements MouseListener,
+  MouseMotionListener, MouseWheelListener, KeyListener {
+
+  static LogWriter vlog = new LogWriter("Viewport");
+
+  public Viewport(int w, int h, PixelFormat serverPF, CConn cc_)
+  {
     cc = cc_;
-    setTitle(name+" - TigerVNC");
-    setFocusable(false);
-    setFocusTraversalKeysEnabled(false);
-    if (!VncViewer.os.startsWith("mac os x"))
-      setIconImage(VncViewer.frameIcon);
-    UIManager.getDefaults().put("ScrollPane.ancestorInputMap",
-      new UIDefaults.LazyInputMap(new Object[]{}));
-    sp = new JScrollPane();
-    sp.getViewport().setBackground(Color.BLACK);
-    sp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
-    getContentPane().add(sp);
-    if (VncViewer.os.startsWith("mac os x")) {
-      if (!noLionFS.getValue())
-        enableLionFS();
-    }
-    addWindowFocusListener(new WindowAdapter() {
-      public void windowGainedFocus(WindowEvent e) {
-        if (isVisible())
-          sp.getViewport().getView().requestFocusInWindow();
+    setScaledSize(cc.cp.width, cc.cp.height);
+    frameBuffer = createFramebuffer(serverPF, w, h);
+    assert(frameBuffer != null);
+    setBackground(Color.BLACK);
+
+    cc.setFramebuffer(frameBuffer);
+    OptionsDialog.addCallback("handleOptions", this);
+
+    addMouseListener(this);
+    addMouseWheelListener(this);
+    addMouseMotionListener(this);
+    addKeyListener(this);
+    addFocusListener(new FocusAdapter() {
+      public void focusGained(FocusEvent e) {
+        ClipboardDialog.clientCutText();
       }
-      public void windowLostFocus(WindowEvent e) {
+      public void focusLost(FocusEvent e) {
         cc.releaseDownKeys();
       }
     });
-    addWindowListener(new WindowAdapter() {
-      public void windowClosing(WindowEvent e) {
-        cc.close();
-      }
-    });
-    addComponentListener(new ComponentAdapter() {
-      public void componentResized(ComponentEvent e) {
-        String scaleString = scalingFactor.getValue();
-        if (scaleString.equalsIgnoreCase("Auto") ||
-            scaleString.equalsIgnoreCase("FixedRatio")) {
-          if ((sp.getSize().width != cc.desktop.scaledWidth) ||
-              (sp.getSize().height != cc.desktop.scaledHeight)) {
-            cc.desktop.setScaledSize();
-            sp.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
-            sp.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);
-            sp.validate();
-            if (getExtendedState() != JFrame.MAXIMIZED_BOTH &&
-                !fullScreen.getValue()) {
-              sp.setSize(new Dimension(cc.desktop.scaledWidth,
-                                       cc.desktop.scaledHeight));
-              int w = cc.desktop.scaledWidth + getInsets().left +
-                      getInsets().right;
-              int h = cc.desktop.scaledHeight + getInsets().top +
-                      getInsets().bottom;
-              if (scaleString.equalsIgnoreCase("FixedRatio"))
-                setSize(w, h);
-            }
-          }
-        } else {
-          sp.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
-          sp.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
-          sp.validate();
-        }
-        if (cc.desktop.cursor != null) {
-          Cursor cursor = cc.desktop.cursor;
-          cc.setCursor(cursor.width(),cursor.height(),cursor.hotspot,
-                       cursor.data, cursor.mask);
-        }
-      }
-    });
+    setFocusTraversalKeysEnabled(false);
+    setFocusable(true);
+
+    // Send a fake pointer event so that the server will stop rendering
+    // a server-side cursor. Ideally we'd like to send the actual pointer
+    // position, but we can't really tell when the window manager is done
+    // placing us so we don't have a good time for that.
+    cc.writer().writePointerEvent(new Point(w/2, h/2), 0);
   }
 
-  public void setName(String name) {
-    setTitle(name + "- TigerVNC");
+  // Most efficient format (from Viewport's point of view)
+  public PixelFormat getPreferredPF()
+  {
+    return frameBuffer.getPF();
   }
 
-  boolean lionFSSupported() { return canDoLionFS; }
-
-  void enableLionFS() {
-    try {
-      String version = System.getProperty("os.version");
-      int firstDot = version.indexOf('.');
-      int lastDot = version.lastIndexOf('.');
-      if (lastDot > firstDot && lastDot >= 0) {
-        version = version.substring(0, version.indexOf('.', firstDot + 1));
+  // Copy the areas of the framebuffer that have been changed (damaged)
+  // to the displayed window.
+  public void updateWindow() {
+    Rect r = frameBuffer.getDamage();
+    if (!r.is_empty()) {
+      if (image == null)
+        image = (BufferedImage)createImage(frameBuffer.width(), frameBuffer.height());
+      image.getRaster().setDataElements(r.tl.x, r.tl.y, frameBuffer.getBuffer(r));
+      if (cc.cp.width != scaledWidth ||
+          cc.cp.height != scaledHeight) {
+        AffineTransform t = new AffineTransform(); 
+        t.scale((double)scaleRatioX, (double)scaleRatioY);
+        Rectangle s = new Rectangle(r.tl.x, r.tl.y, r.width(), r.height());
+        s = t.createTransformedShape(s).getBounds();
+        paintImmediately(s.x, s.y, s.width, s.height);
+      } else {
+        paintImmediately(r.tl.x, r.tl.y, r.width(), r.height());
       }
-      double v = Double.parseDouble(version);
-      if (v < 10.7)
-        throw new Exception("Operating system version is " + v);
-
-      Class fsuClass = Class.forName("com.apple.eawt.FullScreenUtilities");
-      Class argClasses[] = new Class[]{Window.class, Boolean.TYPE};
-      Method setWindowCanFullScreen =
-        fsuClass.getMethod("setWindowCanFullScreen", argClasses);
-      setWindowCanFullScreen.invoke(fsuClass, this, true);
-
-      canDoLionFS = true;
-    } catch (Exception e) {
-      vlog.debug("Could not enable OS X 10.7+ full-screen mode: " +
-                 e.getMessage());
     }
   }
 
-  public void toggleLionFS() {
-    try {
-      Class appClass = Class.forName("com.apple.eawt.Application");
-      Method getApplication = appClass.getMethod("getApplication",
-                                                 (Class[])null);
-      Object app = getApplication.invoke(appClass);
-      Method requestToggleFullScreen =
-        appClass.getMethod("requestToggleFullScreen", Window.class);
-      requestToggleFullScreen.invoke(app, this);
-    } catch (Exception e) {
-      vlog.debug("Could not toggle OS X 10.7+ full-screen mode: " +
-                 e.getMessage());
-    }
-  }
+  static final int[] dotcursor_xpm = {
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0xff000000, 0xff000000, 0xff000000, 0x00000000,
+    0x00000000, 0xff000000, 0xff000000, 0xff000000, 0x00000000,
+    0x00000000, 0xff000000, 0xff000000, 0xff000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+  };
 
-  public JViewport getViewport() {
-    return sp.getViewport();
-  }
+  public void setCursor(int width, int height, Point hotspot,
+                        byte[] data, byte[] mask)
+  {
 
-  public void setGeometry(int x, int y, int w, int h) {
-    pack();
-    if (!fullScreen.getValue())
-      setLocation(x, y);
-  }
+    int mask_len = ((width+7)/8) * height;
+    int i;
 
-  public Dimension getScreenSize() {
-    return getScreenBounds().getSize();
-  }
+    for (i = 0; i < mask_len; i++)
+      if ((mask[i] & 0xff) != 0) break;
 
-  public Rectangle getScreenBounds() {
-    GraphicsEnvironment ge =
-      GraphicsEnvironment.getLocalGraphicsEnvironment();
-    Rectangle r = new Rectangle();
-    setMaximizedBounds(null);
-    if (fullScreenAllMonitors.getValue()) {
-      for (GraphicsDevice gd : ge.getScreenDevices())
-        for (GraphicsConfiguration gc : gd.getConfigurations())
-          r = r.union(gc.getBounds());
-      Rectangle mb = new Rectangle(r);
-      mb.grow(getInsets().left, getInsets().bottom);
-      setMaximizedBounds(mb);
+    if ((i == mask_len) && dotWhenNoCursor.getValue()) {
+      vlog.debug("cursor is empty - using dot");
+      cursor = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB_PRE);
+      cursor.setRGB(0, 0, 5, 5, dotcursor_xpm, 0, 5);
+      cursorHotspot.x = cursorHotspot.y = 3;
     } else {
-      GraphicsDevice gd = ge.getDefaultScreenDevice();
-      GraphicsConfiguration gc = gd.getDefaultConfiguration();
-      r = gc.getBounds();
+      if ((width == 0) || (height == 0)) {
+        cursor = new BufferedImage(tk.getBestCursorSize(0, 0).width,
+                                   tk.getBestCursorSize(0, 0).height,
+                                   BufferedImage.TYPE_INT_ARGB_PRE);
+        cursorHotspot.x = cursorHotspot.y = 0;
+      } else {
+        ByteBuffer buffer = ByteBuffer.allocate(width*height*4);
+        ByteBuffer in, o, m;
+        int m_width;
+
+        PixelFormat pf;
+
+        pf = cc.cp.pf();
+
+        in = (ByteBuffer)ByteBuffer.wrap(data).mark();
+        o = (ByteBuffer)buffer.duplicate().mark();
+        m = ByteBuffer.wrap(mask);
+        m_width = (width+7)/8;
+
+        for (int y = 0; y < height; y++) {
+          for (int x = 0; x < width; x++) {
+            // NOTE: BufferedImage needs ARGB, rather than RGBA
+            if ((m.get((m_width*y)+(x/8)) & 0x80>>(x%8)) != 0)
+              o.put((byte)255);
+            else
+              o.put((byte)0);
+
+            pf.rgbFromBuffer(o, in.duplicate(), 1);
+
+            o.position(o.reset().position() + 4).mark();
+            in.position(in.position() + pf.bpp/8);
+          }
+        }
+
+        IntBuffer rgb =
+          IntBuffer.allocate(width*height).put(buffer.asIntBuffer());
+        cursor = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
+        cursor.setRGB(0, 0, width, height, rgb.array(), 0, width);
+
+        cursorHotspot = hotspot;
+
+      }
     }
-    return r;
+
+    int cw = (int)Math.floor((float)cursor.getWidth() * scaleRatioX);
+    int ch = (int)Math.floor((float)cursor.getHeight() * scaleRatioY);
+
+    int x = (int)Math.floor((float)cursorHotspot.x * scaleRatioX);
+    int y = (int)Math.floor((float)cursorHotspot.y * scaleRatioY);
+
+    java.awt.Cursor softCursor;
+
+    Dimension cs = tk.getBestCursorSize(cw, ch);
+    if (cs.width != cw && cs.height != ch) {
+      cw = Math.min(cw, cs.width);
+      ch = Math.min(ch, cs.height);
+      x = (int)Math.min(x, Math.max(cs.width - 1, 0));
+      y = (int)Math.min(y, Math.max(cs.height - 1, 0));
+      BufferedImage scaledImage = 
+        new BufferedImage(cs.width, cs.height, BufferedImage.TYPE_INT_ARGB);
+      Graphics2D g2 = scaledImage.createGraphics();
+      g2.setRenderingHint(RenderingHints.KEY_RENDERING,
+                          RenderingHints.VALUE_RENDER_QUALITY);
+      g2.drawImage(cursor,
+                   0, 0, cw, ch,
+                   0, 0, cursor.getWidth(), cursor.getHeight(), null);
+      g2.dispose();
+      java.awt.Point hs = new java.awt.Point(x, y);
+      softCursor = tk.createCustomCursor(scaledImage, hs, "softCursor");
+      scaledImage.flush();
+    } else {
+      java.awt.Point hs = new java.awt.Point(x, y);
+      softCursor = tk.createCustomCursor(cursor, hs, "softCursor");
+    }
+
+    cursor.flush();
+
+    setCursor(softCursor);
+
   }
 
-  public static Window getFullScreenWindow() {
-    GraphicsEnvironment ge =
-      GraphicsEnvironment.getLocalGraphicsEnvironment();
-    GraphicsDevice gd = ge.getDefaultScreenDevice();
-    Window fullScreenWindow = gd.getFullScreenWindow();
-    return fullScreenWindow;
+  public void resize(int x, int y, int w, int h) {
+    if ((w != frameBuffer.width()) || (h != frameBuffer.height())) {
+      vlog.debug("Resizing framebuffer from "+frameBuffer.width()+"x"+
+                 frameBuffer.height()+" to "+w+"x"+h);
+      frameBuffer = createFramebuffer(frameBuffer.getPF(), w, h);
+      assert(frameBuffer != null);
+      cc.setFramebuffer(frameBuffer);
+      image = null;
+    }
+    setScaledSize(w, h);
   }
 
-  public static void setFullScreenWindow(Window fullScreenWindow) {
-    GraphicsEnvironment ge =
-      GraphicsEnvironment.getLocalGraphicsEnvironment();
-    GraphicsDevice gd = ge.getDefaultScreenDevice();
-    if (gd.isFullScreenSupported())
-      gd.setFullScreenWindow(fullScreenWindow);
+  private PlatformPixelBuffer createFramebuffer(PixelFormat pf, int w, int h)
+  {
+    PlatformPixelBuffer fb;
+
+    fb = new JavaPixelBuffer(w, h);
+
+    return fb;
   }
 
-  CConn cc;
-  JScrollPane sp;
-  boolean canDoLionFS;
-  static LogWriter vlog = new LogWriter("Viewport");
+  //
+  // Callback methods to determine geometry of our Component.
+  //
+
+  public Dimension getPreferredSize() {
+    return new Dimension(scaledWidth, scaledHeight);
+  }
+
+  public Dimension getMinimumSize() {
+    return new Dimension(scaledWidth, scaledHeight);
+  }
+
+  public Dimension getMaximumSize() {
+    return new Dimension(scaledWidth, scaledHeight);
+  }
+
+  public void paintComponent(Graphics g) {
+    Graphics2D g2 = (Graphics2D)g;
+    if (cc.cp.width != scaledWidth ||
+        cc.cp.height != scaledHeight) {
+      g2.setRenderingHint(RenderingHints.KEY_RENDERING,
+                          RenderingHints.VALUE_RENDER_QUALITY);
+      g2.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
+    } else {
+      g2.drawImage(image, 0, 0, null);
+    }
+    g2.dispose();
+  }
+
+  // Mouse-Motion callback function
+  private void mouseMotionCB(MouseEvent e) {
+    if (!viewOnly.getValue() &&
+        e.getX() >= 0 && e.getX() <= scaledWidth &&
+        e.getY() >= 0 && e.getY() <= scaledHeight)
+      cc.writePointerEvent(translateMouseEvent(e));
+  }
+  public void mouseDragged(MouseEvent e) { mouseMotionCB(e); }
+  public void mouseMoved(MouseEvent e) { mouseMotionCB(e); }
+
+  // Mouse callback function
+  private void mouseCB(MouseEvent e) {
+    if (!viewOnly.getValue())
+      if ((e.getID() == MouseEvent.MOUSE_RELEASED) ||
+          (e.getX() >= 0 && e.getX() <= scaledWidth &&
+           e.getY() >= 0 && e.getY() <= scaledHeight))
+        cc.writePointerEvent(translateMouseEvent(e));
+  }
+  public void mouseReleased(MouseEvent e) { mouseCB(e); }
+  public void mousePressed(MouseEvent e) { mouseCB(e); }
+  public void mouseClicked(MouseEvent e) {}
+  public void mouseEntered(MouseEvent e) {
+    if (embed.getValue())
+      requestFocus();
+  }
+  public void mouseExited(MouseEvent e) {}
+
+  // MouseWheel callback function
+  private void mouseWheelCB(MouseWheelEvent e) {
+    if (!viewOnly.getValue())
+      cc.writeWheelEvent(e);
+  }
+
+  public void mouseWheelMoved(MouseWheelEvent e) {
+    mouseWheelCB(e);
+  }
+
+  private static final Integer keyEventLock = 0; 
+
+  // Handle the key-typed event.
+  public void keyTyped(KeyEvent e) { }
+
+  // Handle the key-released event.
+  public void keyReleased(KeyEvent e) {
+    synchronized(keyEventLock) {
+      cc.writeKeyEvent(e);
+    }
+  }
+
+  // Handle the key-pressed event.
+  public void keyPressed(KeyEvent e)
+  {
+    if (e.getKeyCode() == MenuKey.getMenuKeyCode()) {
+      java.awt.Point pt = e.getComponent().getMousePosition();
+      if (pt != null) {
+        F8Menu menu = new F8Menu(cc);
+        menu.show(e.getComponent(), (int)pt.getX(), (int)pt.getY());
+      }
+      return;
+    }
+    int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
+    if ((e.getModifiers() & ctrlAltShiftMask) == ctrlAltShiftMask) {
+      switch (e.getKeyCode()) {
+        case KeyEvent.VK_A:
+          VncViewer.showAbout(this);
+          return;
+        case KeyEvent.VK_F:
+          if (cc.desktop.fullscreen_active())
+            cc.desktop.fullscreen_on();
+          else
+            cc.desktop.fullscreen_off();
+          return;
+        case KeyEvent.VK_H:
+          cc.refresh();
+          return;
+        case KeyEvent.VK_I:
+          cc.showInfo();
+          return;
+        case KeyEvent.VK_O:
+            OptionsDialog.showDialog(this);
+          return;
+        case KeyEvent.VK_W:
+          VncViewer.newViewer();
+          return;
+        case KeyEvent.VK_LEFT:
+        case KeyEvent.VK_RIGHT:
+        case KeyEvent.VK_UP:
+        case KeyEvent.VK_DOWN:
+          return;
+      }
+    }
+    if ((e.getModifiers() & Event.META_MASK) == Event.META_MASK) {
+      switch (e.getKeyCode()) {
+        case KeyEvent.VK_COMMA:
+        case KeyEvent.VK_N:
+        case KeyEvent.VK_W:
+        case KeyEvent.VK_I:
+        case KeyEvent.VK_R:
+        case KeyEvent.VK_L:
+        case KeyEvent.VK_F:
+        case KeyEvent.VK_Z:
+        case KeyEvent.VK_T:
+          return;
+      }
+    }
+    synchronized(keyEventLock) {
+      cc.writeKeyEvent(e);
+    }
+  }
+
+  public void setScaledSize(int width, int height)
+  {
+    assert(width != 0 && height != 0);
+    String scaleString = scalingFactor.getValue();
+    if (remoteResize.getValue()) {
+      scaledWidth = width;
+      scaledHeight = height;
+      scaleRatioX = 1.00f;
+      scaleRatioY = 1.00f;
+    } else {
+      if (scaleString.matches("^[0-9]+$")) {
+        int scalingFactor = Integer.parseInt(scaleString);
+        scaledWidth =
+          (int)Math.floor((float)width * (float)scalingFactor/100.0);
+        scaledHeight =
+          (int)Math.floor((float)height * (float)scalingFactor/100.0);
+      } else if (scaleString.equalsIgnoreCase("Auto")) {
+        scaledWidth = width;
+        scaledHeight = height;
+      } else {
+        float widthRatio = (float)width / (float)cc.cp.width;
+        float heightRatio = (float)height / (float)cc.cp.height;
+        float ratio = Math.min(widthRatio, heightRatio);
+        scaledWidth = (int)Math.floor(cc.cp.width * ratio);
+        scaledHeight = (int)Math.floor(cc.cp.height * ratio);
+      }
+      scaleRatioX = (float)scaledWidth / (float)cc.cp.width;
+      scaleRatioY = (float)scaledHeight / (float)cc.cp.height;
+    }
+    if (scaledWidth != getWidth() || scaledHeight != getHeight())
+      setSize(new Dimension(scaledWidth, scaledHeight));
+  }
+
+  private MouseEvent translateMouseEvent(MouseEvent e)
+  {
+    if (cc.cp.width != scaledWidth ||
+        cc.cp.height != scaledHeight) {
+      int sx = (scaleRatioX == 1.00) ?
+        e.getX() : (int)Math.floor(e.getX() / scaleRatioX);
+      int sy = (scaleRatioY == 1.00) ?
+        e.getY() : (int)Math.floor(e.getY() / scaleRatioY);
+      e.translatePoint(sx - e.getX(), sy - e.getY());
+    }
+    return e;
+  }
+
+  public void handleOptions()
+  {
+    /*
+    setScaledSize(cc.cp.width, cc.cp.height);
+    if (!oldSize.equals(new Dimension(scaledWidth, scaledHeight))) {
+    // Re-layout the DesktopWindow when the scaled size changes.
+    // Ideally we'd do this with a ComponentListener, but unfortunately
+    // sometimes a spurious resize event is triggered on the viewport
+    // when the DesktopWindow is manually resized via the drag handles.
+    if (cc.desktop != null && cc.desktop.isVisible()) {
+      JScrollPane scroll = (JScrollPane)((JViewport)getParent()).getParent();
+      scroll.setViewportBorder(BorderFactory.createEmptyBorder(0,0,0,0));
+      cc.desktop.pack();
+    }
+    */
+  }
+
+  // access to cc by different threads is specified in CConn
+  private CConn cc;
+  private BufferedImage image;
+
+  // access to the following must be synchronized:
+  public PlatformPixelBuffer frameBuffer;
+
+  static Toolkit tk = Toolkit.getDefaultToolkit();
+
+  public int scaledWidth = 0, scaledHeight = 0;
+  float scaleRatioX, scaleRatioY;
+
+  BufferedImage cursor;
+  Point cursorHotspot = new Point();
+
 }
-
diff --git a/java/com/tigervnc/vncviewer/VncViewer.java b/java/com/tigervnc/vncviewer/VncViewer.java
index a3daef3..f5b3177 100644
--- a/java/com/tigervnc/vncviewer/VncViewer.java
+++ b/java/com/tigervnc/vncviewer/VncViewer.java
@@ -47,6 +47,7 @@
 import java.util.jar.Manifest;
 import java.util.*;
 import javax.swing.*;
+import javax.swing.border.*;
 import javax.swing.plaf.FontUIResource;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager.*;
@@ -60,10 +61,11 @@
 public class VncViewer extends javax.swing.JApplet 
   implements Runnable, ActionListener {
 
-  public static final String aboutText = new String("TigerVNC Java Viewer v%s (%s)%n"+
-                                                    "Built on %s at %s%n"+
-                                                    "Copyright (C) 1999-2016 TigerVNC Team and many others (see README.txt)%n"+
-                                                    "See http://www.tigervnc.org for information on TigerVNC.");
+  public static final String aboutText =
+    new String("TigerVNC Java Viewer v%s (%s)%n"+
+               "Built on %s at %s%n"+
+               "Copyright (C) 1999-2016 TigerVNC Team and many others (see README.txt)%n"+
+               "See http://www.tigervnc.org for information on TigerVNC.");
 
   public static String version = null;
   public static String build = null;
@@ -79,6 +81,7 @@
     VncViewer.class.getResourceAsStream("timestamp");
   public static final String os = 
     System.getProperty("os.name").toLowerCase();
+  private static VncViewer applet;
 
   public static void setLookAndFeel() {
     try {
@@ -140,8 +143,8 @@
   }
 
   public VncViewer() {
-    //this(new String[0]);
-    embed.setParam(true);
+    // Only called in applet mode
+    this(new String[0]);
   }
 
   public VncViewer(String[] argv) {
@@ -311,7 +314,7 @@
 
   public void appletDragStarted() {
     embed.setParam(false);
-    cc.recreateViewport();
+    //cc.recreateViewport();
     JFrame f = (JFrame)JOptionPane.getFrameForComponent(this);
     // The default JFrame created by the drag event will be
     // visible briefly between appletDragStarted and Finished.
@@ -333,20 +336,69 @@
     cc.setCloseListener(null);
   }
 
-  public void init() {
-    vlog.debug("init called");
-    Container parent = getParent();
-    while (!parent.isFocusCycleRoot()) {
-      parent = parent.getParent();
+  public static void setupEmbeddedFrame(JScrollPane sp) {
+    InputMap im = sp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+    int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
+    if (im != null) {
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, ctrlAltShiftMask),
+             "unitScrollUp");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ctrlAltShiftMask),
+             "unitScrollDown");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ctrlAltShiftMask),
+             "unitScrollLeft");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ctrlAltShiftMask),
+             "unitScrollRight");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, ctrlAltShiftMask),
+             "scrollUp");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, ctrlAltShiftMask),
+             "scrollDown");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, ctrlAltShiftMask),
+             "scrollLeft");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, ctrlAltShiftMask),
+             "scrollRight");
     }
-    ((Frame)parent).setModalExclusionType(null);
-    parent.setFocusable(false);
-    parent.setFocusTraversalKeysEnabled(false);
-    setLookAndFeel();
-    setBackground(Color.white);
+    applet.getContentPane().removeAll();
+    applet.getContentPane().add(sp);
+    applet.validate();
   }
 
-  private void getTimestamp() {
+  public void init() {
+    // Called right after zero-arg constructor in applet mode
+    setLookAndFeel();
+    setBackground(Color.white);
+    applet = this;
+    String servername = loadAppletParameters(applet);
+    vncServerName.setParam(servername);
+    alwaysShowServerDialog.setParam(false);
+    if (embed.getValue()) {
+      fullScreen.setParam(false);
+      remoteResize.setParam(false);
+      maximize.setParam(false);
+      scalingFactor.setParam("100");
+    }
+    setFocusTraversalKeysEnabled(false);
+    addFocusListener(new FocusAdapter() {
+      public void focusGained(FocusEvent e) {
+        if (cc != null && cc.desktop != null)
+          cc.desktop.viewport.requestFocusInWindow();
+      }
+    });
+    Frame frame = (Frame)getFocusCycleRootAncestor();
+    frame.setFocusTraversalKeysEnabled(false);
+    frame.addWindowListener(new WindowAdapter() {
+      // Transfer focus to scrollpane when browser receives it
+      public void windowActivated(WindowEvent e) {
+        if (cc != null && cc.desktop != null)
+          cc.desktop.viewport.requestFocusInWindow();
+      }
+      public void windowDeactivated(WindowEvent e) {
+        if (cc != null)
+          cc.releaseDownKeys();
+      }
+    });
+  }
+
+  private static void getTimestamp() {
     if (version == null || build == null) {
       try {
         Manifest manifest = new Manifest(timestamp);
@@ -369,9 +421,9 @@
       pkgTime = attributes.getValue("Package-Time");
     } catch (java.lang.Exception e) { }
 
-    Window fullScreenWindow = Viewport.getFullScreenWindow();
+    Window fullScreenWindow = DesktopWindow.getFullScreenWindow();
     if (fullScreenWindow != null)
-      Viewport.setFullScreenWindow(null);
+      DesktopWindow.setFullScreenWindow(null);
     String msg =
       String.format(VncViewer.aboutText, VncViewer.version, VncViewer.build,
                     VncViewer.buildDate, VncViewer.buildTime);
@@ -384,20 +436,10 @@
     dlg.setAlwaysOnTop(true);
     dlg.setVisible(true);
     if (fullScreenWindow != null)
-      Viewport.setFullScreenWindow(fullScreenWindow);
+      DesktopWindow.setFullScreenWindow(fullScreenWindow);
   }
 
   public void start() {
-    vlog.debug("start called");
-    getTimestamp();
-    if (embed.getValue()) {
-      setupEmbeddedFrame();
-      alwaysShowServerDialog.setParam(false);
-      String servername = loadAppletParameters(this);
-      vncServerName.setParam(servername);
-      fullScreen.setParam(false);
-      scalingFactor.setParam("100");
-    }
     thread = new Thread(this);
     thread.start();
   }
@@ -409,41 +451,6 @@
       System.exit(n);
   }
 
-  private void setupEmbeddedFrame() {
-    UIManager.getDefaults().put("ScrollPane.ancestorInputMap",
-      new UIDefaults.LazyInputMap(new Object[]{}));
-    sp = new JScrollPane();
-    sp.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
-    sp.getViewport().setBackground(Color.BLACK);
-    InputMap im = sp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
-    int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
-    if (im != null) {
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, ctrlAltShiftMask),
-             "unitScrollUp");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ctrlAltShiftMask),
-             "unitScrollDown");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ctrlAltShiftMask),
-             "unitScrollLeft");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ctrlAltShiftMask),
-             "unitScrollRight");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, ctrlAltShiftMask),
-             "scrollUp");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, ctrlAltShiftMask),
-             "scrollDown");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, ctrlAltShiftMask),
-             "scrollLeft");
-      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, ctrlAltShiftMask),
-             "scrollRight");
-    }
-    sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
-    sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
-    add(sp);
-  }
-
-  public static JViewport getViewport() {
-    return sp.getViewport();
-  }
-
   // If "Reconnect" button is pressed
   public void actionPerformed(ActionEvent e) {
     getContentPane().removeAll();
@@ -524,7 +531,7 @@
       if (cc == null || !cc.shuttingDown) {
         reportException(e);
         if (cc != null)
-          cc.deleteWindow();
+          cc.close();
       } else if (embed.getValue()) {
         reportException(new java.lang.Exception("Connection closed"));
         exit(0);
@@ -534,7 +541,6 @@
   }
 
   public static CConn cc;
-  private static JScrollPane sp;
   public static StringParameter config
   = new StringParameter("Config",
   "Specifies a configuration file to load.", null);
