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);
