diff --git a/java/src/com/tightvnc/rfbplayer/ButtonPanel.java b/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
deleted file mode 100644
index 56d8ad3..0000000
--- a/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-//  Copyright (C) 2002 HorizonLive.com, Inc.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-package com.tightvnc.rfbplayer;
-
-import java.awt.*;
-import java.awt.event.*;
-
-class ButtonPanel extends Panel implements ActionListener {
-
-  protected RfbPlayer player;
-  protected Button playButton;
-  protected TextField posText;
-  protected TextField timeScaleText;
-
-  protected int lastPosSeconds = -1;
-
-  ButtonPanel(RfbPlayer player) {
-    this.player = player;
-
-    setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-
-    playButton = new Button("Play");
-    playButton.setEnabled(false);
-    add(playButton);
-    playButton.addActionListener(this);
-
-    add(new Label(" Position:"));
-    posText = new TextField(5);
-    add(posText);
-    posText.addActionListener(this);
-
-    add(new Label(" Speed:"));
-    timeScaleText = new TextField(5);
-    timeScaleText.setText(String.valueOf(player.getSpeed()));
-    add(timeScaleText);
-    timeScaleText.addActionListener(this);
-  }
-
-  public void setPaused(boolean paused) {
-    if (paused) {
-      playButton.setLabel("Play");
-    } else {
-      playButton.setLabel("Pause");
-    }
-    playButton.setEnabled(true);
-  }
-
-  public void setPos(long pos) {
-    int seconds = (int)(pos / 1000);
-    if (seconds != lastPosSeconds) {
-      lastPosSeconds = seconds;
-      char[] zeroes = {'0', '0', '0', '0'};
-      String text = String.valueOf(seconds);
-      if (text.length() < 4) {
-        text = new String(zeroes, 0, 4 - text.length()) + text;
-      }
-      posText.setText(text);
-      posText.setCaretPosition(text.length());
-    }
-  }
-
-  //
-  // Event processing.
-  //
-  public void actionPerformed(ActionEvent evt) {
-    if (evt.getSource() == playButton) {
-      player.setPaused(playButton.getLabel().equals("Pause"));
-    } else if (evt.getSource() == posText) {
-      player.setPos(Long.parseLong(posText.getText()) * 1000);
-    } else if (evt.getSource() == timeScaleText) {
-      double speed = Double.valueOf(timeScaleText.getText()).doubleValue();
-      if (speed <= 0.0)
-        speed = 1.0;
-      timeScaleText.setText(String.valueOf(speed));
-      player.setSpeed(speed);
-    }
-  }
-
-}
-
diff --git a/java/src/com/tightvnc/rfbplayer/FbsConnection.java b/java/src/com/tightvnc/rfbplayer/FbsConnection.java
deleted file mode 100644
index 5bbf4e0..0000000
--- a/java/src/com/tightvnc/rfbplayer/FbsConnection.java
+++ /dev/null
@@ -1,274 +0,0 @@
-//
-//  Copyright (C) 2008 Wimba, Inc.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-//
-// FbsConnection.java
-//
-
-package com.tightvnc.rfbplayer;
-
-import java.io.*;
-import java.net.*;
-import java.applet.Applet;
-
-public class FbsConnection {
-
-  URL fbsURL;
-  URL fbiURL;
-  URL fbkURL;
-
-  /** Index data loaded from the .fbi file. */
-  FbsEntryPoint[] indexData;
-  int numIndexRecords;
-
-  /** RFB initialization data loaded from the .fbi file. */
-  byte[] rfbInitData;
-
-  FbsConnection(String fbsLocation, String indexLocationPrefix, Applet applet)
-      throws MalformedURLException {
-
-    // Construct URLs from strings.
-    URL base = null;
-    if (applet != null) {
-      base = applet.getCodeBase();
-    }
-    fbsURL = new URL(base, fbsLocation);
-    fbiURL = fbkURL = null;
-    if (indexLocationPrefix != null) {
-      try {
-        fbiURL = new URL(base, indexLocationPrefix + ".fbi");
-        fbkURL = new URL(base, indexLocationPrefix + ".fbk");
-      } catch (MalformedURLException e) {
-        fbiURL = fbkURL = null;
-      }
-    }
-
-    // Try to load the .fbi index file.
-    indexData = null;
-    numIndexRecords = 0;
-    rfbInitData = null;
-    loadIndex();
-  }
-
-  FbsInputStream connect(long timeOffset) throws IOException {
-    FbsInputStream fbs = null;
-
-    // Try efficient seeking first.
-    int i = indexForTimeOffset(timeOffset);
-    if (i >= 0) {
-      FbsEntryPoint entryPoint = indexData[i];
-      if (entryPoint.key_size < entryPoint.fbs_fpos) {
-        try {
-          fbs = openFbsFile(entryPoint);
-        } catch (IOException e) {
-          System.err.println(e);
-        }
-        if (fbs == null) {
-          System.err.println("Could not open FBS file at entry point " +
-                             entryPoint.timestamp + " ms");
-        }
-      }
-    }
-
-    // Fallback to the dumb version of openFbsFile().
-    if (fbs == null) {
-      fbs = openFbsFile();
-    }
-
-    // Seek to the specified position.
-    fbs.setTimeOffset(timeOffset, false);
-    return fbs;
-  }
-
-  /**
-   * Load index data from .fbi file to {@link #indexData}.
-   */
-  private void loadIndex() {
-    // Loading .fbi makes sense only if both .fbi and .fbk files are available.
-    if (fbiURL != null && fbkURL != null) {
-      FbsEntryPoint[] newIndex;
-      int numRecordsRead = 0;
-      byte[] newInitData;
-      try {
-        // Connect.
-        URLConnection connection = fbiURL.openConnection();
-        connection.connect();
-        DataInputStream is = new DataInputStream(connection.getInputStream());
-
-        // Check file signature.
-        byte[] b = new byte[12];
-        is.readFully(b);
-        if (b[0] != 'F' || b[1] != 'B' || b[2] != 'I' || b[3] != ' ' ||
-            b[4] != '0' || b[5] != '0' || b[6] != '1' || b[7] != '.' ||
-            b[8] < '0' || b[8] > '9' || b[9] < '0' || b[9] > '9' ||
-            b[10] < '0' || b[10] > '9' || b[11] != '\n') {
-          System.err.println("Could not load index: bad .fbi file signature");
-          return;
-        }
-
-        // Read the record counter and allocate index array.
-        int numRecords = is.readInt();
-        if (numRecords <= 0) {
-          System.err.println("Could not load index: bad .fbi record counter");
-          return;
-        }
-        newIndex = new FbsEntryPoint[numRecords];
-
-        // Read byte counter and allocate byte array for RFB initialization.
-        int initSize = is.readInt();
-        if (initSize <= 0) {
-          System.err.println("Could not load index: bad RFB init data size");
-          return;
-        }
-        newInitData = new byte[initSize];
-
-        // Load index from the .fbi file.
-        try {
-          for (int i = 0; i < numRecords; i++) {
-            FbsEntryPoint record = new FbsEntryPoint();
-            record.timestamp = (long)is.readInt() & 0xFFFFFFFFL;
-            record.key_fpos = (long)is.readInt() & 0xFFFFFFFFL;
-            record.key_size = (long)is.readInt() & 0xFFFFFFFFL;
-            record.fbs_fpos = (long)is.readInt() & 0xFFFFFFFFL;
-            record.fbs_skip = (long)is.readInt() & 0xFFFFFFFFL;
-            newIndex[i] = record;
-            numRecordsRead++;
-          }
-        } catch (EOFException e) {
-          System.err.println("Preliminary end of .fbi file");
-        } catch (IOException e) {
-          System.err.println("Ignored exception: " + e);
-        }
-        if (numRecordsRead == 0) {
-          System.err.println("Could not load index: failed to read .fbi data");
-          return;
-        } else if (numRecordsRead != numRecords) {
-          System.err.println("Warning: read not as much .fbi data as expected");
-        }
-        is.readFully(newInitData);
-      } catch (FileNotFoundException e) {
-        System.err.println("Could not load index: .fbi file not found: " +
-                           e.getMessage());
-        return;
-      } catch (IOException e) {
-        System.err.println(e);
-        System.err.println("Could not load index: failed to load .fbi file");
-        return;
-      }
-      // Check correctness of the data read.
-      for (int i = 1; i < numRecordsRead; i++) {
-        if (newIndex[i].timestamp <= newIndex[i - 1].timestamp) {
-          System.err.println("Could not load index: wrong .fbi file contents");
-          return;
-        }
-      }
-      // Loaded successfully.
-      indexData = newIndex;
-      numIndexRecords = numRecordsRead;
-      rfbInitData = newInitData;
-      System.err.println("Loaded index data, " + numRecordsRead + " records");
-    }
-  }
-
-  private int indexForTimeOffset(long timeOffset) {
-    if (timeOffset > 0 && indexData != null && numIndexRecords > 0) {
-      int i = 0;
-      while (i < numIndexRecords && indexData[i].timestamp <= timeOffset) {
-        i++;
-      }
-      return i - 1;
-    } else {
-      return -1;
-    }
-  }
-
-  /**
-   * Open FBS file identified by {@link #fbsURL}. The file is open at its very
-   * beginning, no seek is performed.
-   *
-   * @return a newly created FBS input stream.
-   * @throws java.io.IOException if an I/O exception occurs.
-   */
-  private FbsInputStream openFbsFile() throws IOException {
-    return new FbsInputStream(fbsURL.openStream());
-  }
-
-  /**
-   * Open FBS file identified by {@link #fbsURL}. The stream is
-   * positioned at the entry point described by <code>entryPoint</code>.
-   *
-   * @param entryPoint entry point information.
-   *
-   * @return a newly created FBS input stream on success, <code>null</code> if
-   *   any error occured and the FBS stream is not opened.
-   * @throws java.io.IOException if an I/O exception occurs.
-   */
-  private FbsInputStream openFbsFile(FbsEntryPoint entry)
-      throws IOException {
-
-    System.err.println("Entering FBS at " + entry.timestamp + " ms");
-
-    // Make sure the protocol is HTTP.
-    if (!fbkURL.getProtocol().equalsIgnoreCase("http") ||
-        !fbsURL.getProtocol().equalsIgnoreCase("http")) {
-      System.err.println("Indexed access requires HTTP protocol in URLs");
-      return null;
-    }
-
-    // Seek to the keyframe.
-    InputStream is = openHttpByteRange(fbkURL, entry.key_fpos, entry.key_size);
-    if (is == null) {
-      return null;
-    }
-
-    // Load keyframe data from the .fbk file, prepend RFB initialization data.
-    DataInputStream data = new DataInputStream(is);
-    byte[] keyData = new byte[rfbInitData.length + (int)entry.key_size];
-    System.arraycopy(rfbInitData, 0, keyData, 0, rfbInitData.length);
-    data.readFully(keyData, rfbInitData.length, (int)entry.key_size);
-    data.close();
-
-    // Open the FBS stream.
-    is = openHttpByteRange(fbsURL, entry.fbs_fpos, -1);
-    if (is == null) {
-      return null;
-    }
-    return new FbsInputStream(is, entry.timestamp, keyData, entry.fbs_skip);
-  }
-
-  private static InputStream openHttpByteRange(URL url, long offset, long len)
-      throws IOException {
-    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
-    String rangeSpec = "bytes=" + offset + "-";
-    if (len != -1) {
-      long lastByteOffset = offset + len - 1;
-      rangeSpec += lastByteOffset;
-    }
-    conn.setRequestProperty("Range", rangeSpec);
-    conn.connect();
-    InputStream is = conn.getInputStream();
-    if (conn.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) {
-      System.err.println("HTTP server does not support Range request headers");
-      is.close();
-      return null;
-    }
-    return is;
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/FbsEntryPoint.java b/java/src/com/tightvnc/rfbplayer/FbsEntryPoint.java
deleted file mode 100644
index 100933f..0000000
--- a/java/src/com/tightvnc/rfbplayer/FbsEntryPoint.java
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-//  Copyright (C) 2008 Wimba, Inc.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-//
-// FbsEntryPoint.java
-//
-
-package com.tightvnc.rfbplayer;
-
-/**
- * Representation of an individual record of the .fbi (FrameBuffer Index) file.
- * It includes data that constitutes an entry point to indexed framebuffer
- * stream at a particular time offset.
- *
- * @author Constantin Kaplinsky
- */
-public class FbsEntryPoint {
-
-  /**
-   * Timestamp in milliseconds corresponding to the keyframe data.
-   * 32-bit unsigned integer.
-   */
-  public long timestamp;
-
-  /**
-   * Keyframe position in the respective .fbk file, offset in bytes from the
-   * very beginning of the file. It should point to the byte counter of an FBS
-   * data block. 32-bit unsigned integer.
-   */
-  public long key_fpos;
-
-  /**
-   * Keyframe data size in the respective .fbk file, in bytes. 32-bit unsigned
-   * integer.
-   */
-  public long key_size;
-
-  /**
-   * Position of the next update in the .fbs file, offset in bytes from the
-   * very beginning of the file. It should point to the byte counter of an FBS
-   * data block. 32-bit unsigned integer.
-   */
-  public long fbs_fpos;
-
-  /**
-   * Offset in the FBS data block referenced by fbs_fpos. It allows addressing
-   * those updates that begin not on the data block boundary. 32-bit unsigned
-   * integer.
-   */
-  public long fbs_skip;
-
-  /**
-   * A replacement for {@link Object#toString()}.
-   *
-   * @return a string representation of the object.
-   */
-  public String toString() {
-    String s = "[ timestamp:" + timestamp;
-    s += " key_fpos:" + key_fpos;
-    s += " key_size:" + key_size;
-    s += " fbs_fpos:" + fbs_fpos;
-    s += " fbs_skip:" + fbs_skip + " ]";
-
-    return s;
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/FbsInputStream.java b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
deleted file mode 100644
index f5f4b39..0000000
--- a/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
+++ /dev/null
@@ -1,344 +0,0 @@
-//
-//  Copyright (C) 2002 HorizonLive.com, Inc.  All Rights Reserved.
-//  Copyright (C) 2008 Wimba, Inc.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-//
-// FbsInputStream.java
-//
-
-package com.tightvnc.rfbplayer;
-
-import java.io.*;
-import java.util.*;
-
-class FbsInputStream extends InputStream {
-
-  protected InputStream in;
-  protected long startTime;
-  protected long timeOffset;
-  protected long seekOffset;
-  protected boolean farSeeking;
-  protected boolean paused;
-  protected boolean isQuitting = false;
-  protected double playbackSpeed;
-
-  protected byte[] buffer;
-  protected int bufferSize;
-  protected int bufferPos;
-
-  /** The number of bytes to skip in the beginning of the next data block. */
-  protected long nextBlockOffset;
-
-  protected Observer obs;
-
-  /**
-   * Construct FbsInputStream object based on the given InputStream, positioned
-   * at the very beginning of the corresponding FBS file. This constructor
-   * reads and checks FBS file signature which would look like "FBS 001.000\n",
-   * but any decimal number is allowed after the dot.
-   *
-   * @param in the InputStream object that will be used as a base for this new
-   * FbsInputStream instance. It should be positioned at the very beginning of
-   * the corresponding FBS file, so that first 12 bytes read from the stream
-   * should form FBS file signature.
-   * @throws java.io.IOException thrown on read error or on incorrect FBS file
-   * signature.
-   */
-  FbsInputStream(InputStream in) throws IOException {
-    this(in, 0, null, 0);
-
-    byte[] b = new byte[12];
-    readFully(b);
-
-    if (b[0] != 'F' || b[1] != 'B' || b[2] != 'S' || b[3] != ' ' ||
-        b[4] != '0' || b[5] != '0' || b[6] != '1' || b[7] != '.' ||
-        b[8] < '0' || b[8] > '9' || b[9] < '0' || b[9] > '9' ||
-        b[10] < '0' || b[10] > '9' || b[11] != '\n') {
-      throw new IOException("Incorrect FBS file signature");
-    }
-  }
-
-  /**
-   * Construct FbsInputStream object based on the given byte array and
-   * continued in the specified InputStream. Arbitrary position in the FBS file
-   * is allowed.
-   *
-   * @param in
-   *    the input stream for reading future data, after <code>buffer</code>
-   *    will be exhausted. The stream should be positioned at any data block
-   *    boundary (byte counter should follow in next four bytes).
-   * @param timeOffset
-   *    time position corresponding the the data block provided in
-   *    <code>buffer</code>.
-   * @param buffer
-   *    the data block that will be treated as the beginning of this FBS data
-   *    stream. This byte array is not copied into the new object so it should
-   *    not be altered by the caller afterwards.
-   * @param nextBlockOffset
-   *    the number of bytes that should be skipped in first data block read
-   *    from <code>in</code>.
-   */
-  FbsInputStream(InputStream in, long timeOffset, byte[] buffer,
-                 long nextBlockOffset) {
-
-    this.in = in;
-    startTime = System.currentTimeMillis() - timeOffset;
-    this.timeOffset = timeOffset;
-    seekOffset = -1;
-    farSeeking = false;
-    paused = false;
-    playbackSpeed = 1.0;
-
-    this.buffer = buffer;
-    bufferSize = (buffer != null) ? buffer.length : 0;
-    bufferPos = 0;
-
-    this.nextBlockOffset = nextBlockOffset;
-  }
-
-  // Force stream to finish any wait.
-  public void quit() {
-    isQuitting = true;
-    synchronized(this) {
-      notify();
-    }
-  }
-
-  //
-  // Basic methods overriding InputStream's methods.
-  //
-  public int read() throws IOException {
-    while (bufferSize == 0) {
-      if (!fillBuffer())
-        return -1;
-    }
-    bufferSize--;
-    return buffer[bufferPos++] & 0xFF;
-  }
-
-  public int available() throws IOException {
-    // FIXME: This will work incorrectly if our caller will wait until
-    // some amount of data is available when the buffer contains less
-    // data than then that. Current implementation never reads more
-    // data until the buffer is fully exhausted.
-    return bufferSize;
-  }
-
-  public synchronized void close() throws IOException {
-    if (in != null)
-      in.close();
-    in = null;
-    startTime = -1;
-    timeOffset = 0;
-    seekOffset = -1;
-    farSeeking = false;
-    paused = false;
-    playbackSpeed = 1.0;
-
-    buffer = null;
-    bufferSize = 0;
-    bufferPos = 0;
-
-    nextBlockOffset = 0;
-    obs = null;
-  }
-
-  //
-  // Methods providing additional functionality.
-  //
-  public synchronized long getTimeOffset() {
-    long off = Math.max(seekOffset, timeOffset);
-    return (long)(off * playbackSpeed);
-  }
-
-  public synchronized void setTimeOffset(long pos, boolean allowJump) {
-    seekOffset = (long)(pos / playbackSpeed);
-    if (allowJump) {
-      long minJumpForwardOffset = timeOffset + (long)(10000 / playbackSpeed);
-      if (seekOffset < timeOffset || seekOffset > minJumpForwardOffset) {
-        farSeeking = true;
-      }
-    }
-    notify();
-  }
-
-  public synchronized void setSpeed(double newSpeed) {
-    long newOffset = (long)(timeOffset * playbackSpeed / newSpeed);
-    startTime += timeOffset - newOffset;
-    timeOffset = newOffset;
-    if (isSeeking()) {
-      seekOffset = (long)(seekOffset * playbackSpeed / newSpeed);
-    }
-    playbackSpeed = newSpeed;
-  }
-
-  public boolean isSeeking() {
-    return (seekOffset >= 0);
-  }
-
-  public long getSeekOffset() {
-    return (long)(seekOffset * playbackSpeed);
-  }
-
-  public boolean isPaused() {
-    return paused;
-  }
-
-  public synchronized void pausePlayback() {
-    paused = true;
-    notify();
-  }
-
-  public synchronized void resumePlayback() {
-    paused = false;
-    startTime = System.currentTimeMillis() - timeOffset;
-    notify();
-  }
-
-  public void addObserver(Observer target) {
-    obs = target;
-  }
-
-  //
-  // Methods for internal use.
-  //
-  private synchronized boolean fillBuffer() throws IOException {
-    // The reading thread should be interrupted on far seeking.
-    if (farSeeking)
-      throw new EOFException("[JUMP]");
-
-    // Just wait unless we are performing playback OR seeking.
-    waitWhilePaused();
-
-    if (!readDataBlock()) {
-      return false;
-    }
-
-    if (seekOffset >= 0) {
-      if (timeOffset >= seekOffset) {
-        startTime = System.currentTimeMillis() - seekOffset;
-        seekOffset = -1;
-      } else {
-        return true;
-      }
-    }
-
-    while (!isQuitting) {
-      long timeDiff = startTime + timeOffset - System.currentTimeMillis();
-      if (timeDiff <= 0) {
-        break;
-      }
-      try {
-        wait(timeDiff);
-      } catch (InterruptedException e) {
-      }
-      waitWhilePaused();
-    }
-
-    return true;
-  }
-
-  /**
-   * Read FBS data block into the buffer.
-   * If {@link #nextBlockOffset} is not zero, that number of bytes will be
-   * skipped in the beginning of the data block.
-   *
-   * @return true on success, false if end of file was reached.
-   * @throws java.io.IOException can be thrown while reading from the
-   *   underlying input stream, or as a result of bad FBS file data.
-   */
-  private boolean readDataBlock() throws IOException {
-    // Read byte counter, check for EOF condition.
-    long readResult = readUnsigned32();
-    if (readResult < 0) {
-      return false;
-    }
-
-    bufferSize = (int)readResult;
-    int alignedSize = (bufferSize + 3) & 0xFFFFFFFC;
-
-    if (nextBlockOffset > 0) {
-      in.skip(nextBlockOffset);
-      bufferSize -= nextBlockOffset;
-      alignedSize -= nextBlockOffset;
-      nextBlockOffset = 0;
-    }
-
-    if (bufferSize >= 0) {
-      buffer = new byte[alignedSize];
-      readFully(buffer);
-      bufferPos = 0;
-      timeOffset = (long)(readUnsigned32() / playbackSpeed);
-    }
-
-    if (bufferSize < 0 || timeOffset < 0 || bufferPos >= bufferSize) {
-      buffer = null;
-      bufferSize = 0;
-      bufferPos = 0;
-      throw new IOException("Invalid FBS file data");
-    }
-
-    return true;
-  }
-
-  //
-  // In paused mode, wait for external notification on this object.
-  //
-  private void waitWhilePaused() {
-    while (paused && !isSeeking() && !isQuitting) {
-      synchronized(this) {
-        try {
-          // Note: we call Observer.update(Observable,Object) method
-          // directly instead of maintaining an Observable object.
-          obs.update(null, null);
-          wait();
-        } catch (InterruptedException e) {
-        }
-      }
-    }
-  }
-
-  private long readUnsigned32() throws IOException {
-    byte[] buf = new byte[4];
-    if (!readFully(buf))
-      return -1;
-
-    return ((long)(buf[0] & 0xFF) << 24 |
-        (buf[1] & 0xFF) << 16 |
-        (buf[2] & 0xFF) << 8 |
-        (buf[3] & 0xFF));
-  }
-
-  private boolean readFully(byte[] b) throws IOException {
-    int off = 0;
-    int len = b.length;
-
-    while (off != len) {
-      int count = in.read(b, off, len - off);
-      if (count < 0) {
-        return false;
-      }
-      off += count;
-    }
-
-    return true;
-  }
-
-}
-
diff --git a/java/src/com/tightvnc/rfbplayer/LICENCE.TXT b/java/src/com/tightvnc/rfbplayer/LICENCE.TXT
deleted file mode 100644
index ae3b531..0000000
--- a/java/src/com/tightvnc/rfbplayer/LICENCE.TXT
+++ /dev/null
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
-	  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-	 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	Appendix: How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program 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 program 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 program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-    USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/java/src/com/tightvnc/rfbplayer/LWScrollPane.java b/java/src/com/tightvnc/rfbplayer/LWScrollPane.java
deleted file mode 100644
index 7325c8c..0000000
--- a/java/src/com/tightvnc/rfbplayer/LWScrollPane.java
+++ /dev/null
@@ -1,260 +0,0 @@
-
-package com.tightvnc.rfbplayer;
-
-import java.awt.*;
-import java.awt.event.*;
-
-class LWScrollPane extends Container implements AdjustmentListener {
-
-  /** position info */
-  private Point scrollPosition = new Point(0, 0);
-
-  /** panel to hold component to scroll */
-  private Panel innerPanel = new Panel() {
-
-    public void update(Graphics g) {
-      if (needClear) {
-        super.update(g);
-        needClear = false;
-      } else
-        this.paint(g);
-    }
-
-  };
-
-  /** component to display */
-  private Component containedComp;
-
-  /** layout info */
-  private GridBagLayout gb;
-  private GridBagConstraints gbc;
-
-  /** scroll bars */
-  private Scrollbar xScroller;
-  private Scrollbar yScroller;
-
-  /** flags indicating which scollbars are visible */
-  private boolean showingXScroll = false;
-  private boolean showingYScroll = false;
-
-  /** flag indicating when innerpanel needs to repaint background */
-  private boolean needClear = false;
-
-  /** dimensions for our preferred size */
-  private int width = 0;
-  private int height = 0;
-
-  /** c'tor for a new scroll pane */
-  public LWScrollPane() {
-    // create scroll bars
-    xScroller = new Scrollbar(Scrollbar.HORIZONTAL) {
-
-      public boolean isFocusable() {
-        return false;
-      }
-
-    };
-    yScroller = new Scrollbar(Scrollbar.VERTICAL) {
-
-      public boolean isFocusable() {
-        return false;
-      }
-
-    };
-    xScroller.addAdjustmentListener(this);
-    yScroller.addAdjustmentListener(this);
-
-    // layout info 
-    gb = new GridBagLayout();
-    gbc = new GridBagConstraints();
-    setLayout(gb);
-    setBackground(Color.white);
-
-    // added inner panel
-    //innerPanel.setBackground(Color.blue);
-    gbc.fill = GridBagConstraints.BOTH;
-    gbc.gridx = 0;
-    gbc.gridy = 0;
-    gbc.weightx = 100;
-    gbc.weighty = 100;
-    gb.setConstraints(innerPanel, gbc);
-    add(innerPanel);
-    innerPanel.setLayout(null);
-  }
-  /*
-  public void update(Graphics g) {
-  paint(g);
-  }
-   */
-  /*
-  public void paint(Graphics g) {
-  super.paint(g);
-  }
-   */
-
-  /**
-   * Provided to allow the containing frame to resize.
-   * OS X JVM 1.3 would not allow a frame to be made
-   * smaller without overriding getMinimumSize.
-   */
-  public Dimension getMinimumSize() {
-    return new Dimension(0, 0);
-  }
-
-  public Dimension getPreferredSize() {
-    return new Dimension(width, height);
-  }
-
-  public void setSize(int width, int height) {
-    this.width = width;
-    this.height = height;
-    super.setSize(width, height);
-  }
-
-  public void setSize(Dimension d) {
-    setSize(d.width, d.height);
-  }
-
-  /** 
-   * Force component to clear itself before repainting. 
-   * Primarily useful if the contained component shrinks
-   * without the scroll pane reducing in size.
-   */
-  public void clearAndRepaint() {
-    needClear = true;
-    innerPanel.repaint();
-  }
-
-  /** Add the component to be scrolled by scroll pane */
-  void addComp(Component comp) {
-    containedComp = comp;
-    innerPanel.add(containedComp);
-  }
-
-  /** 
-   * Set the point of the component to display in the
-   * upper left corner of the viewport.
-   */
-  void setScrollPosition(int x, int y) {
-    Dimension vps = getViewportSize();
-    Dimension ccs = containedComp.getPreferredSize();
-
-    // skip entirely if component smaller than viewer
-    if (ccs.width <= vps.width && ccs.height <= vps.height)
-      return;
-
-    // don't scroll too far left or up 
-    if (x < 0)
-      x = 0;
-    if (y < 0)
-      y = 0;
-
-    // don't scroll too far right or down 
-    if (ccs.width <= vps.width)
-      x = 0;
-    else if (x > (ccs.width - vps.width))
-      x = ccs.width - vps.width;
-    if (ccs.height <= vps.height)
-      y = 0;
-    else if (y > (ccs.height - vps.height))
-      y = ccs.height - vps.height;
-
-    scrollPosition = new Point(x, y);
-    containedComp.setLocation(-scrollPosition.x, -scrollPosition.y);
-    xScroller.setValue(scrollPosition.x);
-    yScroller.setValue(scrollPosition.y);
-  }
-
-  /** Returns the point at the upper left corner of viewport */
-  Point getScrollPosition() {
-    return new Point(scrollPosition);
-  }
-
-  /** Return the dimensions of the viewport */
-  public Dimension getViewportSize() {
-    int vpW, vpH;
-    Dimension size = getSize();
-    vpW = size.width;
-    vpH = size.height;
-    if (showingYScroll)
-      vpW -= yScroller.getSize().width;
-    if (showingXScroll)
-      vpH -= xScroller.getSize().height;
-
-    return new Dimension(vpW, vpH);
-  }
-
-  /** 
-   * Ensure that the scroll pane is properly arranged after
-   * a component is added, the pane is resized, etc.
-   */
-  public void doLayout() {
-    /** Add scroll bars as necessary */
-    boolean needX = false, needY = false;
-    Dimension innerSize = containedComp.getPreferredSize();
-    Dimension scrollDimension = getSize();
-
-    if (innerSize.width > scrollDimension.width)
-      needX = true;
-    if (innerSize.height > scrollDimension.height)
-      needY = true;
-
-    showingXScroll = false;
-    showingYScroll = false;
-    remove(yScroller);
-    remove(xScroller);
-
-    if (needY) {
-      gbc.gridy = 0;
-      gbc.gridx = 1;
-      gbc.weightx = 0;
-      gb.setConstraints(yScroller, gbc);
-      add(yScroller);
-      showingYScroll = true;
-    }
-
-    if (needX) {
-      gbc.gridy = 1;
-      gbc.gridx = 0;
-      gbc.weightx = 100;
-      gbc.weighty = 0;
-      gb.setConstraints(xScroller, gbc);
-      add(xScroller);
-      showingXScroll = true;
-    }
-
-    /* set scroll bar values */
-    int vpW, vpH;
-    vpW = scrollDimension.width;
-    vpH = scrollDimension.height;
-    if (showingYScroll)
-      vpW -= yScroller.getSize().width;
-    if (showingXScroll)
-      vpH -= xScroller.getSize().height;
-    yScroller.setValues(0, vpH, 0, innerSize.height);
-    xScroller.setValues(0, vpW, 0, innerSize.width);
-
-    containedComp.setLocation(0, 0);
-    super.doLayout();
-  }
-
-  /**
-   * Adjustment listener method for receiving callbacks
-   * from scroll actions. 
-   *	
-   * @param e the AdjustmentEvent
-   * @return void
-   */
-  public void adjustmentValueChanged(AdjustmentEvent e) {
-    Point p = containedComp.getLocation();
-    if (e.getAdjustable() == xScroller) {
-      p.x = -e.getValue();
-      scrollPosition.x = e.getValue();
-    } else {
-      p.y = -e.getValue();
-      scrollPosition.y = e.getValue();
-    }
-    containedComp.setLocation(p);
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/Makefile b/java/src/com/tightvnc/rfbplayer/Makefile
deleted file mode 100644
index 42d1047..0000000
--- a/java/src/com/tightvnc/rfbplayer/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Making the VNC applet.
-#
-
-CP = cp
-RM = rm
-JC = javac
-JAR = jar
-ARCHIVE = RfbPlayer.jar
-PAGES = index.html
-INSTALL_DIR = ./classes
-
-CLASSES = RfbPlayer.class RfbProto.class ButtonPanel.class VncCanvas.class \
-	  FbsInputStream.class
-
-SOURCES = RfbPlayer.java RfbProto.java ButtonPanel.java VncCanvas.java \
-	  FbsInputStream.java
-
-all: $(CLASSES) $(ARCHIVE)
-
-$(CLASSES): $(SOURCES)
-	$(JC) -g $(SOURCES)
-
-$(ARCHIVE): $(CLASSES)
-	$(JAR) cf $(ARCHIVE) $(CLASSES)
-
-install: $(CLASSES) $(ARCHIVE)
-	$(CP) $(CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR)
-
-clean::
-	$(RM) *.class *.jar
diff --git a/java/src/com/tightvnc/rfbplayer/PARfbSender.java b/java/src/com/tightvnc/rfbplayer/PARfbSender.java
deleted file mode 100644
index 73d09fb..0000000
--- a/java/src/com/tightvnc/rfbplayer/PARfbSender.java
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package com.tightvnc.rfbplayer;
-
-import java.applet.*;
-
-public class PARfbSender extends Applet {
-
-  public void init() {
-    Applet receiver = null;
-    receiver = RfbSharedStatic.refApplet;
-    long time = Long.valueOf(getParameter("time")).longValue();
-    boolean pause = (Integer.parseInt(getParameter("pause")) != 0);
-    boolean unpause = (Integer.parseInt(getParameter("unpause")) != 0);
-
-    if (receiver != null) {
-
-      if (pause) {
-        ((RfbPlayer)receiver).setPaused(true);
-      } else if (unpause) {
-        ((RfbPlayer)receiver).setPaused(false);
-      } else {
-        ((RfbPlayer)receiver).jumpTo(time);
-      }
-    } else
-      System.err.println("Couldn't jump to time: " + time + " in RfbPlayer.");
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/README b/java/src/com/tightvnc/rfbplayer/README
deleted file mode 100644
index b9bb52b..0000000
--- a/java/src/com/tightvnc/rfbplayer/README
+++ /dev/null
@@ -1,99 +0,0 @@
-
-RFB Session Player 1.0.1
-========================
-
-RFB Session Player is a Java application/applet for playing back RFB session
-files in FBS format saved by such programs as VNC Reflector or rfbproxy.
-
-Usage:  java RfbPlayer URL file:test.fbs position 5000
-        java RfbPlayer URL http://remote.host/sessions/test.fbs
-
-
-Applet Parameters
-=================
-
---> "URL"
-
-    Value: URL of the session file to play.
-    Default: none (required parameter).
-
-    This parameter tells the player which session file to play. The URL can
-    be either a complete one (e.g. "file:/your/path/session.fbs") or relative
-    (e.g. "session.fbs"). Please note that if the player operates as an
-    unsigned applet, it is able to play only files from the host where the
-    applet was loaded from. It's a usual JVM security limitation.
-
---> "Position"
-
-    Value: time in milliseconds.
-    Default: 0.
-
-    Set initial time position in the session file, in milliseconds.
-
---> "Autoplay"
-
-    Values: "Yes", "No".
-    Default: "No".
-
-    If set to "Yes", then start in the playback mode. By default, the
-    player starts in the paused state.
-
---> "Open new window" (applicable only in the applet mode)
-
-    Values: "Yes", "No".
-    Default: "No".
-
-    Operate in a separate window. This makes possible resizing the desktop,
-    and adds scroll bars when necessary. If the server supports variable
-    desktop size, the window will resize automatically when remote desktop
-    size changes.
-
---> "Show controls"
-
-    Values: "Yes", "No".
-    Default: "Yes".
-
-    Set to "No" if you want to get rid of the control panel at the top. 
-    Please note that hiding the panel in current version makes playback
-    impossible. :-)
-
---> "Defer screen updates"
-
-    Value: time in milliseconds.
-    Default: "20".
-
-    When updating the desktop contents after reading each update, schedule
-    repaint within the specified number of milliseconds. Small delay helps to
-    coalesce several small updates into one drawing operation, improving CPU
-    usage. Set this parameter to 0 to disable deferred updates.
-
---> "Speed"
-
-    Value: positive fixed-point or floating-point number.
-    Default: "1.0".
-
-    Sets playback speed where 1 is normal speed, 2 is double speed,
-    and 0.5 is half speed etc. Both number formats like 0.2 and 2e-1
-    are acceptable.
-
-
-Licensing Terms
-===============
-
-RFB Session Player is
-
-  Copyright (C) 2002 HorizonLive.com, Inc.  All Rights Reserved.
-
-This software is based on the TightVNC Java viewer which is
-
-  Copyright (C) 2001,2002 HorizonLive.com, Inc.  All Rights Reserved.
-  Copyright (C) 2001 Constantin Kaplinsky.  All Rights Reserved.
-  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
-
-This software is distributed under the GNU General Public Licence as
-published by the Free Software Foundation. See the file LICENCE.TXT
-for the conditions under which this software is made available. VNC
-also contains code from other sources. See the Acknowledgements
-section below, and the individual files for details of the conditions
-under which they are made available.
-
diff --git a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
deleted file mode 100644
index e696d95..0000000
--- a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
+++ /dev/null
@@ -1,472 +0,0 @@
-//
-//  Copyright (C) 2001,2002 HorizonLive.com, Inc.  All Rights Reserved.
-//  Copyright (C) 1999 AT&T Laboratories Cambridge.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-package com.tightvnc.rfbplayer;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-
-public class RfbPlayer extends java.applet.Applet
-    implements java.lang.Runnable, WindowListener {
-
-  boolean inAnApplet = true;
-  boolean inSeparateFrame = false;
-
-  /** current applet width */
-  int dispW = 300;
-  /** current applet height */
-  int dispH = 200;
-
-  //
-  // main() is called when run as a java program from the command line.
-  // It simply runs the applet inside a newly-created frame.
-  //
-  public static void main(String[] argv) {
-    RfbPlayer p = new RfbPlayer();
-    p.mainArgs = argv;
-    p.inAnApplet = false;
-    p.inSeparateFrame = true;
-
-    p.init();
-    p.start();
-  }
-
-  String[] mainArgs;
-
-  FbsInputStream fbs;
-  RfbProto rfb;
-  Thread rfbThread;
-
-  Frame vncFrame;
-  Container vncContainer;
-  //ScrollPane desktopScrollPane;
-  LWScrollPane desktopScrollPane;
-  GridBagLayout gridbag;
-  ButtonPanel buttonPanel;
-  VncCanvas vc;
-
-  String sessionURL;
-  String idxPrefix;
-  long initialTimeOffset;
-  double playbackSpeed;
-  boolean autoPlay;
-  boolean showControls;
-  boolean isQuitting = false;
-  int deferScreenUpdates;
-
-  //
-  // init()
-  //
-  public void init() {
-
-    // LiveConnect work-a-round
-    RfbSharedStatic.refApplet = this;
-
-    readParameters();
-
-    if (inSeparateFrame) {
-      vncFrame = new Frame("RFB Session Player");
-      if (!inAnApplet) {
-        vncFrame.add("Center", this);
-      }
-      vncContainer = vncFrame;
-    } else {
-      vncContainer = this;
-    }
-
-    if (inSeparateFrame)
-      vncFrame.addWindowListener(this);
-
-    rfbThread = new Thread(this, "RfbThread");
-    rfbThread.start();
-  }
-
-  public void update(Graphics g) {
-  }
-
-  //
-  // run() - executed by the rfbThread to read RFB data.
-  //
-  public void run() {
-
-    gridbag = new GridBagLayout();
-    vncContainer.setLayout(gridbag);
-
-    GridBagConstraints gbc = new GridBagConstraints();
-    gbc.gridwidth = GridBagConstraints.REMAINDER;
-    gbc.anchor = GridBagConstraints.NORTHWEST;
-
-    if (showControls) {
-      buttonPanel = new ButtonPanel(this);
-      buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-      gridbag.setConstraints(buttonPanel, gbc);
-      vncContainer.add(buttonPanel);
-    }
-
-    if (inSeparateFrame) {
-      vncFrame.pack();
-      vncFrame.setVisible(true);
-    } else {
-      validate();
-    }
-
-    try {
-      java.applet.Applet applet = (inAnApplet) ? this : null;
-      FbsConnection conn = new FbsConnection(sessionURL, idxPrefix, applet);
-      fbs = conn.connect(initialTimeOffset);
-      rfb = new RfbProto(fbs);
-
-      vc = new VncCanvas(this);
-      gbc.weightx = 1.0;
-      gbc.weighty = 1.0;
-
-      // Create a panel which itself is resizeable and can hold
-      // non-resizeable VncCanvas component at the top left corner.
-      //Panel canvasPanel = new Panel();
-      //canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-      //canvasPanel.add(vc);
-
-      // Create a ScrollPane which will hold a panel with VncCanvas
-      // inside.
-      //desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
-      desktopScrollPane = new LWScrollPane();
-      gbc.fill = GridBagConstraints.BOTH;
-      gridbag.setConstraints(vc, gbc);
-      //gridbag.setConstraints(canvasPanel, gbc);
-      desktopScrollPane.addComp(vc);
-      desktopScrollPane.setSize(dispW, dispH);
-      //desktopScrollPane.add(canvasPanel);
-
-      // Now add the scroll bar to the container.
-      if (inSeparateFrame) {
-        gridbag.setConstraints(desktopScrollPane, gbc);
-        vncFrame.add(desktopScrollPane);
-        vncFrame.setTitle(rfb.desktopName);
-        vc.resizeDesktopFrame();
-      } else {
-        // Size the scroll pane to display size.
-        desktopScrollPane.setSize(dispW, dispH);
-
-        // Just add the VncCanvas component to the Applet.
-        gbc.fill = GridBagConstraints.NONE;
-        gridbag.setConstraints(desktopScrollPane, gbc);
-        add(desktopScrollPane);
-        validate();
-        vc.resizeEmbeddedApplet();
-      }
-
-      while (!isQuitting) {
-        try {
-          setPaused(!autoPlay);
-          fbs.setSpeed(playbackSpeed);
-          vc.processNormalProtocol();
-        } catch (EOFException e) {
-          long newTimeOffset;
-          if (e.getMessage() != null && e.getMessage().equals("[JUMP]")) {
-            // A special type of EOFException allowing us to close FBS stream
-            // and then re-open it for jumping to a different time offset.
-            newTimeOffset = fbs.getSeekOffset();
-            autoPlay = !fbs.isPaused();
-          } else {
-            // Return to the beginning after the playback is finished.
-            newTimeOffset = 0;
-            autoPlay = false;
-          }
-          fbs.close();
-          fbs = conn.connect(newTimeOffset);
-          rfb.newSession(fbs);
-          vc.updateFramebufferSize();
-        } catch (NullPointerException e) {
-          // catching this causes a hang with 1.4.1 JVM's under Win32 IE
-          throw e;
-        }
-      }
-
-    } catch (FileNotFoundException e) {
-      fatalError(e.toString());
-    } catch (Exception e) {
-      e.printStackTrace();
-      fatalError(e.toString());
-    }
-
-  }
-
-  public void setPausedInt(String paused) {
-    // default to true (pause)
-    int pause = 1;
-
-    try {
-      pause = Integer.parseInt(paused);
-    } catch (NumberFormatException e) {
-    }
-
-    if (pause == 0) {
-      setPaused(false);
-    } else {
-      setPaused(true);
-    }
-  }
-
-  public void setPaused(boolean paused) {
-    if (showControls)
-      buttonPanel.setPaused(paused);
-    if (paused) {
-      fbs.pausePlayback();
-    } else {
-      fbs.resumePlayback();
-    }
-  }
-
-  public double getSpeed() {
-    return playbackSpeed;
-  }
-
-  public void setSpeed(double speed) {
-    playbackSpeed = speed;
-    fbs.setSpeed(speed);
-  }
-
-  public void jumpTo(long pos) {
-    long diff = Math.abs(pos - fbs.getTimeOffset());
-
-    // Current threshold is 5 seconds
-    if (diff > 5000) {
-      fbs.pausePlayback();
-      setPos(pos);
-      fbs.resumePlayback();
-    }
-  }
-
-  public void setPos(long pos) {
-    fbs.setTimeOffset(pos, true);
-  }
-
-  public void updatePos() {
-    if (showControls && buttonPanel != null)
-      buttonPanel.setPos(fbs.getTimeOffset());
-  }
-
-  //
-  // readParameters() - read parameters from the html source or from the
-  // command line.  On the command line, the arguments are just a sequence of
-  // param_name/param_value pairs where the names and values correspond to
-  // those expected in the html applet tag source.
-  //
-  public void readParameters() {
-
-    sessionURL = readParameter("URL", true);
-    idxPrefix = readParameter("Index", false);
-
-    initialTimeOffset = readLongParameter("Position", 0);
-    if (initialTimeOffset < 0)
-      initialTimeOffset = 0;
-
-    playbackSpeed = readDoubleParameter("Speed", 1.0);
-    if (playbackSpeed <= 0.0)
-      playbackSpeed = 1.0;
-
-    autoPlay = false;
-    String str = readParameter("Autoplay", false);
-    if (str != null && str.equalsIgnoreCase("Yes"))
-      autoPlay = true;
-
-    showControls = true;
-    str = readParameter("Show_Controls", false);
-    if (str != null && str.equalsIgnoreCase("No"))
-      showControls = false;
-
-    if (inAnApplet) {
-      str = readParameter("Open_New_Window", false);
-      if (str != null && str.equalsIgnoreCase("Yes"))
-        inSeparateFrame = true;
-    }
-
-    // Fine tuning options.
-    deferScreenUpdates = (int)readLongParameter("Defer_screen_updates", 20);
-    if (deferScreenUpdates < 0)
-      deferScreenUpdates = 0;	// Just in case.
-
-    // Display width and height.
-    dispW = readIntParameter("DISPLAY_WIDTH", dispW);
-    dispH = readIntParameter("DISPLAY_HEIGHT", dispH);
-  }
-
-  public String readParameter(String name, boolean required) {
-    if (inAnApplet) {
-      String s = getParameter(name);
-      if ((s == null) && required) {
-        fatalError(name + " parameter not specified");
-      }
-      return s;
-    }
-
-    for (int i = 0; i < mainArgs.length; i += 2) {
-      if (mainArgs[i].equalsIgnoreCase(name)) {
-        try {
-          return mainArgs[i + 1];
-        } catch (Exception e) {
-          if (required) {
-            fatalError(name + " parameter not specified");
-          }
-          return null;
-        }
-      }
-    }
-    if (required) {
-      fatalError(name + " parameter not specified");
-    }
-    return null;
-  }
-
-  long readLongParameter(String name, long defaultValue) {
-    String str = readParameter(name, false);
-    long result = defaultValue;
-    if (str != null) {
-      try {
-        result = Long.parseLong(str);
-      } catch (NumberFormatException e) {
-      }
-    }
-    return result;
-  }
-
-  double readDoubleParameter(String name, double defaultValue) {
-    String str = readParameter(name, false);
-    double result = defaultValue;
-    if (str != null) {
-      try {
-        result = Double.valueOf(str).doubleValue();
-      } catch (NumberFormatException e) {
-      }
-    }
-    return result;
-  }
-
-  int readIntParameter(String name, int defaultValue) {
-    String str = readParameter(name, false);
-    int result = defaultValue;
-    if (str != null) {
-      try {
-        result = Integer.parseInt(str);
-      } catch (NumberFormatException e) {
-      }
-    }
-    return result;
-  }
-
-  //
-  // fatalError() - print out a fatal error message.
-  //
-  public void fatalError(String str) {
-    System.err.println(str);
-
-    if (inAnApplet) {
-      vncContainer.removeAll();
-      if (rfb != null) {
-        rfb = null;
-      }
-      Label errLabel = new Label(str);
-      errLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
-      vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30));
-      vncContainer.add(errLabel);
-      if (inSeparateFrame) {
-        vncFrame.pack();
-      } else {
-        validate();
-      }
-      Thread.currentThread().stop();
-    } else {
-      System.exit(1);
-    }
-  }
-
-
-  //
-  // This method is called before the applet is destroyed.
-  //
-  public void destroy() {
-    isQuitting = true;
-    vncContainer.removeAll();
-    if (fbs != null) {
-      fbs.quit();
-      try {
-        fbs.close();
-      } catch (IOException e) {
-      }
-    }
-    try {
-      rfbThread.join();
-    } catch (InterruptedException e) {
-    }
-    if (inSeparateFrame) {
-      vncFrame.removeWindowListener(this);
-      vncFrame.dispose();
-    }
-  }
-
-  //
-  // Set the new width and height of the applet. Call when browser is resized to 
-  // resize the viewer.
-  //
-  public void displaySize(int width, int height) {
-    dispW = width;
-    dispH = height;
-    if (!inSeparateFrame) {
-      vc.resizeEmbeddedApplet();
-    }
-  }
-
-  //
-  // Close application properly on window close event.
-  //
-  public void windowClosing(WindowEvent evt) {
-    vncContainer.removeAll();
-    if (rfb != null)
-      rfb = null;
-
-    vncFrame.dispose();
-    if (!inAnApplet) {
-      System.exit(0);
-    }
-  }
-
-  //
-  // Ignore window events we're not interested in.
-  //
-  public void windowActivated(WindowEvent evt) {
-  }
-
-  public void windowDeactivated(WindowEvent evt) {
-  }
-
-  public void windowOpened(WindowEvent evt) {
-  }
-
-  public void windowClosed(WindowEvent evt) {
-  }
-
-  public void windowIconified(WindowEvent evt) {
-  }
-
-  public void windowDeiconified(WindowEvent evt) {
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/RfbPlayerSetDisplaySize.java b/java/src/com/tightvnc/rfbplayer/RfbPlayerSetDisplaySize.java
deleted file mode 100644
index f78770f..0000000
--- a/java/src/com/tightvnc/rfbplayer/RfbPlayerSetDisplaySize.java
+++ /dev/null
@@ -1,20 +0,0 @@
-
-package com.tightvnc.rfbplayer;
-
-import java.applet.*;
-
-public class RfbPlayerSetDisplaySize extends Applet {
-
-  public void init() {
-    Applet receiver = null;
-    receiver = RfbSharedStatic.refApplet;
-    int width = Integer.valueOf(getParameter("DISPLAY_WIDTH")).intValue();
-    int height = Integer.valueOf(getParameter("DISPLAY_HEIGHT")).intValue();
-
-    if (receiver != null) {
-      ((RfbPlayer)receiver).displaySize(width, height);
-    } else
-      System.err.println("Couldn't resize RfbPlayer.");
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/RfbProto.java b/java/src/com/tightvnc/rfbplayer/RfbProto.java
deleted file mode 100644
index 191173e..0000000
--- a/java/src/com/tightvnc/rfbplayer/RfbProto.java
+++ /dev/null
@@ -1,292 +0,0 @@
-//
-//  Copyright (C) 2008 Wimba, Inc.  All Rights Reserved.
-//  Copyright (C) 2001,2002 HorizonLive.com, Inc.  All Rights Reserved.
-//  Copyright (C) 2001 Constantin Kaplinsky.  All Rights Reserved.
-//  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
-//  Copyright (C) 1999 AT&T Laboratories Cambridge.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-//
-// RfbProto.java
-//
-
-package com.tightvnc.rfbplayer;
-
-import java.io.*;
-
-class RfbProto {
-
-  final static String versionMsg = "RFB 003.003\n";
-
-  final static int ConnFailed = 0;
-  final static int NoAuth = 1;
-  final static int VncAuth = 2;
-
-  final static int VncAuthOK = 0;
-  final static int VncAuthFailed = 1;
-  final static int VncAuthTooMany = 2;
-
-  final static int FramebufferUpdate = 0;
-  final static int SetColourMapEntries = 1;
-  final static int Bell = 2;
-  final static int ServerCutText = 3;
-
-  final static int SetPixelFormat = 0;
-  final static int FixColourMapEntries = 1;
-  final static int SetEncodings = 2;
-  final static int FramebufferUpdateRequest = 3;
-  final static int KeyboardEvent = 4;
-  final static int PointerEvent = 5;
-  final static int ClientCutText = 6;
-
-  final static int EncodingRaw = 0;
-  final static int EncodingCopyRect = 1;
-  final static int EncodingRRE = 2;
-  final static int EncodingCoRRE = 4;
-  final static int EncodingHextile = 5;
-  final static int EncodingZlib = 6;
-  final static int EncodingTight = 7;
-  final static int EncodingCompressLevel0 = 0xFFFFFF00;
-  final static int EncodingQualityLevel0 = 0xFFFFFFE0;
-  final static int EncodingXCursor = 0xFFFFFF10;
-  final static int EncodingRichCursor = 0xFFFFFF11;
-  final static int EncodingPointerPos = 0xFFFFFF18;
-  final static int EncodingLastRect = 0xFFFFFF20;
-  final static int EncodingNewFBSize = 0xFFFFFF21;
-
-  final static int MaxNormalEncoding = 7;
-
-  final static int HextileRaw = (1 << 0);
-  final static int HextileBackgroundSpecified = (1 << 1);
-  final static int HextileForegroundSpecified = (1 << 2);
-  final static int HextileAnySubrects = (1 << 3);
-  final static int HextileSubrectsColoured = (1 << 4);
-
-  final static int TightExplicitFilter = 0x04;
-  final static int TightFill = 0x08;
-  final static int TightJpeg = 0x09;
-  final static int TightMaxSubencoding = 0x09;
-  final static int TightFilterCopy = 0x00;
-  final static int TightFilterPalette = 0x01;
-  final static int TightFilterGradient = 0x02;
-
-  final static int TightMinToCompress = 12;
-
-  DataInputStream is;
-
-  /**
-   * Constructor. It calls <code>{@link #newSession(InputStream)}</code> to open
-   * new session.
-   *
-   * @param is the input stream from which RFB data will be read.
-   * @throws java.lang.Exception
-   * @throws java.io.IOException
-   */
-  RfbProto(InputStream is) throws Exception {
-    newSession(is);
-  }
-
-  /**
-   * Open new session that can be read from the specified InputStream.
-   *
-   * @param is the input stream.
-   * @throws java.lang.Exception
-   * @throws java.io.IOException
-   */
-  public void newSession(InputStream is) throws Exception {
-
-    this.is = new DataInputStream(is);
-
-    readVersionMsg();
-    if (readAuthScheme() != NoAuth) {
-      throw new Exception("Wrong authentication type in the session file");
-    }
-    readServerInit();
-  }
-
-  //
-  // Read server's protocol version message.
-  //
-  int serverMajor, serverMinor;
-
-  void readVersionMsg() throws IOException {
-
-    byte[] b = new byte[12];
-
-    for (int i = 0; i < b.length; i++)
-      b[i] = (byte)'0';
-
-    is.readFully(b);
-
-    if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') ||
-        (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') || (b[6] <
-        '0') || (b[6] > '9') || (b[7] != '.') || (b[8] < '0') || (b[8] > '9') ||
-        (b[9] < '0') || (b[9] > '9') || (b[10] < '0') || (b[10] > '9') ||
-        (b[11] != '\n')) {
-      throw new IOException("Incorrect protocol version");
-    }
-
-    serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
-    serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');
-  }
-
-
-  //
-  // Find out the authentication scheme.
-  //
-  int readAuthScheme() throws IOException {
-    int authScheme = is.readInt();
-
-    switch (authScheme) {
-
-    case ConnFailed:
-      int reasonLen = is.readInt();
-      byte[] reason = new byte[reasonLen];
-      is.readFully(reason);
-      throw new IOException(new String(reason));
-
-    case NoAuth:
-    case VncAuth:
-      return authScheme;
-
-    default:
-      throw new IOException("Unknown authentication scheme " + authScheme);
-
-    }
-  }
-
-
-  //
-  // Read the server initialisation message
-  //
-  String desktopName;
-  int framebufferWidth, framebufferHeight;
-  int bitsPerPixel, depth;
-  boolean bigEndian, trueColour;
-  int redMax, greenMax, blueMax, redShift, greenShift, blueShift;
-
-  void readServerInit() throws Exception {
-    framebufferWidth = is.readUnsignedShort();
-    framebufferHeight = is.readUnsignedShort();
-    bitsPerPixel = is.readUnsignedByte();
-    depth = is.readUnsignedByte();
-    bigEndian = (is.readUnsignedByte() != 0);
-    trueColour = (is.readUnsignedByte() != 0);
-    redMax = is.readUnsignedShort();
-    greenMax = is.readUnsignedShort();
-    blueMax = is.readUnsignedShort();
-    redShift = is.readUnsignedByte();
-    greenShift = is.readUnsignedByte();
-    blueShift = is.readUnsignedByte();
-    byte[] pad = new byte[3];
-    is.readFully(pad);
-    int nameLength = is.readInt();
-    byte[] name = new byte[nameLength];
-    is.readFully(name);
-    desktopName = new String(name);
-  }
-
-
-  //
-  // Set new framebuffer size
-  //
-  void setFramebufferSize(int width, int height) {
-    framebufferWidth = width;
-    framebufferHeight = height;
-  }
-
-
-  //
-  // Read the server message type
-  //
-  int readServerMessageType() throws IOException {
-    return is.readUnsignedByte();
-  }
-
-
-  //
-  // Read a FramebufferUpdate message
-  //
-  int updateNRects;
-
-  void readFramebufferUpdate() throws IOException {
-    is.readByte();
-    updateNRects = is.readUnsignedShort();
-  }
-
-  // Read a FramebufferUpdate rectangle header
-  int updateRectX, updateRectY, updateRectW, updateRectH, updateRectEncoding;
-
-  void readFramebufferUpdateRectHdr() throws IOException {
-    updateRectX = is.readUnsignedShort();
-    updateRectY = is.readUnsignedShort();
-    updateRectW = is.readUnsignedShort();
-    updateRectH = is.readUnsignedShort();
-    updateRectEncoding = is.readInt();
-
-    if (updateRectEncoding < 0 || updateRectEncoding > MaxNormalEncoding)
-      return;
-
-    if ((updateRectX + updateRectW > framebufferWidth) ||
-        (updateRectY + updateRectH > framebufferHeight)) {
-      throw new IOException("Framebuffer update rectangle too large: " +
-                            updateRectW + "x" + updateRectH + " at (" +
-                            updateRectX + "," + updateRectY + ")");
-    }
-  }
-
-  // Read CopyRect source X and Y.
-  int copyRectSrcX, copyRectSrcY;
-
-  void readCopyRect() throws IOException {
-    copyRectSrcX = is.readUnsignedShort();
-    copyRectSrcY = is.readUnsignedShort();
-  }
-
-
-  //
-  // Read a ServerCutText message
-  //
-  String readServerCutText() throws IOException {
-    byte[] pad = new byte[3];
-    is.readFully(pad);
-    int len = is.readInt();
-    byte[] text = new byte[len];
-    is.readFully(text);
-    return new String(text);
-  }
-
-
-  //
-  // Read integer in compact representation
-  //
-  int readCompactLen() throws IOException {
-    int portion = is.readUnsignedByte();
-    int len = portion & 0x7F;
-    if ((portion & 0x80) != 0) {
-      portion = is.readUnsignedByte();
-      len |= (portion & 0x7F) << 7;
-      if ((portion & 0x80) != 0) {
-        portion = is.readUnsignedByte();
-        len |= (portion & 0xFF) << 14;
-      }
-    }
-    return len;
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/RfbSharedStatic.java b/java/src/com/tightvnc/rfbplayer/RfbSharedStatic.java
deleted file mode 100644
index 7cf9cf1..0000000
--- a/java/src/com/tightvnc/rfbplayer/RfbSharedStatic.java
+++ /dev/null
@@ -1,9 +0,0 @@
-
-package com.tightvnc.rfbplayer;
-
-import java.applet.*;
-
-public class RfbSharedStatic {
-
-  public static Applet refApplet;
-}
diff --git a/java/src/com/tightvnc/rfbplayer/VncCanvas.java b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
deleted file mode 100644
index 7bb8d29..0000000
--- a/java/src/com/tightvnc/rfbplayer/VncCanvas.java
+++ /dev/null
@@ -1,1336 +0,0 @@
-//
-//  Copyright (C) 2004 Horizon Wimba.  All Rights Reserved.
-//  Copyright (C) 2001-2003 HorizonLive.com, Inc.  All Rights Reserved.
-//  Copyright (C) 2001 Constantin Kaplinsky.  All Rights Reserved.
-//  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
-//  Copyright (C) 1999 AT&T Laboratories Cambridge.  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
-//  USA.
-//
-
-package com.tightvnc.rfbplayer;
-
-import java.awt.*;
-import java.awt.image.*;
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-
-//
-// VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
-//
-class VncCanvas extends Component
-    implements Observer {
-
-  RfbPlayer appClass;
-  RfbProto rfb;
-  ColorModel cm8, cm24;
-  int bytesPixel;
-
-  Image memImage;
-  Graphics memGraphics;
-
-  Image offImage;
-  Graphics offGraphics;
-
-  Image rawPixelsImage;
-  MemoryImageSource pixelsSource;
-  byte[] pixels8;
-  int[] pixels24;
-
-  // Zlib encoder's data.
-  byte[] zlibBuf;
-  int zlibBufLen = 0;
-  Inflater zlibInflater;
-
-  // Tight encoder's data.
-  final static int tightZlibBufferSize = 512;
-  Inflater[] tightInflaters;
-
-  // Since JPEG images are loaded asynchronously, we have to remember
-  // their position in the framebuffer. Also, this jpegRect object is
-  // used for synchronization between the rfbThread and a JVM's thread
-  // which decodes and loads JPEG images.
-  Rectangle jpegRect;
-
-  // When we're in the seeking mode, we should not update the desktop. 
-  // This variable helps us to remember that repainting the desktop at
-  // once is necessary when the seek operation is finished.
-  boolean seekMode;
-
-  // Distance of mouse from viewer border to trigger automatic scrolling
-  final static int SCROLL_MARGIN = 50;
-
-  // Color for border around small shared area
-  static final Color DARK_GRAY = new Color(132, 138, 156);
-
-  //
-  // The constructor.
-  //
-  VncCanvas(RfbPlayer player) throws IOException {
-    this.appClass = player;
-    rfb = appClass.rfb;
-    seekMode = false;
-
-    cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
-
-    setPixelFormat();
-
-    // Style canvas.
-    setBackground(Color.white);
-
-  }
-
-  //
-  // Override the 1.4 focus traversal keys accesor to allow
-  // our keyListener to receive tab presses.
-  //
-  public boolean getFocusTraversalKeysEnabled() {
-    return false;
-  }
-
-  //
-  // Callback methods to determine geometry of our Component.
-  //
-  public Dimension getPreferredSize() {
-    Dimension d = appClass.desktopScrollPane.getViewportSize();
-    Dimension sz = new Dimension(rfb.framebufferWidth, rfb.framebufferHeight);
-    if (d.width > sz.width)
-      sz.width = d.width;
-    if (d.height > sz.height)
-      sz.height = d.height;
-    return sz;
-  }
-
-  public Dimension getMinimumSize() {
-    return getPreferredSize();
-  }
-
-  public Dimension getMaximumSize() {
-    return getPreferredSize();
-  }
-
-  Point getImageOrigin() {
-    int x = 0, y = 0;
-    Dimension d = appClass.desktopScrollPane.getViewportSize();
-    if (rfb.framebufferWidth < d.width)
-      x = d.width / 2 - rfb.framebufferWidth / 2;
-    if (rfb.framebufferHeight < d.height)
-      y = d.height / 2 - rfb.framebufferHeight / 2;
-    return new Point(x, y);
-  }
-
-  //
-  // All painting is performed here.
-  //
-  public void update(Graphics g) {
-    paint(g);
-  }
-
-  public void paint(Graphics g) {
-    Point o = getImageOrigin();
-    Dimension d = getPreferredSize();
-
-    // create new offscreen
-    if (offImage == null) {
-      offImage = createImage(d.width, d.height);
-      offGraphics = offImage.getGraphics();
-    } else if (offImage.getWidth(null) != d.width ||
-        offImage.getHeight(null) != d.height) {
-      offGraphics.dispose();
-      offGraphics = null;
-      offImage.flush();
-      offImage = null;
-      offImage = createImage(d.width, d.height);
-      offGraphics = offImage.getGraphics();
-    }
-
-    synchronized(memImage) {
-      offGraphics.drawImage(memImage, o.x, o.y, null);
-    }
-
-    // fill in background
-    if (o.x > 0 || o.y > 0) {
-      // left, right, top, bottom
-      Color c = g.getColor();
-      offGraphics.setColor(Color.white);
-      offGraphics.fillRect(0, 0, o.x, d.height);
-      offGraphics.fillRect(o.x + rfb.framebufferWidth, 0, d.width - (o.x +
-                           rfb.framebufferWidth), d.height);
-      offGraphics.fillRect(o.x, 0, rfb.framebufferWidth, o.y);
-      offGraphics.fillRect(o.x, o.y + rfb.framebufferHeight,
-                           rfb.framebufferWidth, d.height - (o.y +
-                           rfb.framebufferHeight));
-      offGraphics.setColor(c);
-    }
-
-    // draw border
-    Color oc = g.getColor();
-    offGraphics.setColor(DARK_GRAY);
-    offGraphics.drawRect(o.x - 1, o.y - 1, rfb.framebufferWidth + 1,
-                         rfb.framebufferHeight + 1);
-    offGraphics.setColor(oc);
-
-    // draw cursor
-    if (showSoftCursor) {
-      int x0 = cursorX - hotX, y0 = cursorY - hotY;
-      x0 += o.x;
-      y0 += o.y;
-      Rectangle r = new Rectangle(x0, y0, cursorWidth, cursorHeight);
-      if (r.intersects(g.getClipBounds())) {
-        offGraphics.setClip(o.x, o.y, rfb.framebufferWidth,
-                            rfb.framebufferHeight);
-        offGraphics.drawImage(softCursor, x0, y0, null);
-        offGraphics.setClip(null);
-      }
-    }
-
-    // draw offscreen
-    g.drawImage(offImage, 0, 0, null);
-  }
-
-  //
-  // Override the ImageObserver interface method to handle drawing of
-  // JPEG-encoded data.
-  //
-  public boolean imageUpdate(Image img, int infoflags,
-                              int x, int y, int width, int height) {
-    if ((infoflags & (ALLBITS | ABORT)) == 0) {
-      return true;		// We need more image data.
-    } else {
-      // If the whole image is available, draw it now.
-      if ((infoflags & ALLBITS) != 0) {
-        if (jpegRect != null) {
-          synchronized(jpegRect) {
-            memGraphics.drawImage(img, jpegRect.x, jpegRect.y, null);
-            scheduleRepaint(jpegRect.x, jpegRect.y,
-                            jpegRect.width, jpegRect.height);
-            jpegRect.notify();
-          }
-        }
-      }
-      return false;		// All image data was processed.
-    }
-  }
-
-  private void setPixelFormat() throws IOException {
-    bytesPixel = 4;
-    updateFramebufferSize();
-  }
-
-  void updateFramebufferSize() {
-
-    // Useful shortcuts.
-    int fbWidth = rfb.framebufferWidth;
-    int fbHeight = rfb.framebufferHeight;
-
-    // Create new off-screen image either if it does not exist, or if
-    // its geometry should be changed. It's not necessary to replace
-    // existing image if only pixel format should be changed.
-    if (memImage == null) {
-      memImage = appClass.createImage(fbWidth, fbHeight);
-      memGraphics = memImage.getGraphics();
-    } else if (memImage.getWidth(null) != fbWidth ||
-        memImage.getHeight(null) != fbHeight) {
-      synchronized(memImage) {
-        memImage = appClass.createImage(fbWidth, fbHeight);
-        memGraphics = memImage.getGraphics();
-      }
-    }
-
-    // Images with raw pixels should be re-allocated on every change
-    // of geometry or pixel format.
-    if (bytesPixel == 1) {
-      pixels24 = null;
-      pixels8 = new byte[fbWidth * fbHeight];
-
-      pixelsSource =
-          new MemoryImageSource(fbWidth, fbHeight, cm8, pixels8, 0, fbWidth);
-    } else {
-      pixels8 = null;
-      pixels24 = new int[fbWidth * fbHeight];
-
-      pixelsSource =
-          new MemoryImageSource(fbWidth, fbHeight, cm24, pixels24, 0, fbWidth);
-    }
-    pixelsSource.setAnimated(true);
-    rawPixelsImage = createImage(pixelsSource);
-
-    // Update the size of desktop containers unless seeking 
-    if (!seekMode && appClass.desktopScrollPane != null) {
-      if (appClass.inSeparateFrame) {
-        resizeDesktopFrame();
-      } else {
-        resizeEmbeddedApplet();
-        // if the framebuffer shrunk, need to clear and repaint
-        appClass.desktopScrollPane.clearAndRepaint();
-      }
-    }
-  }
-
-  void resizeDesktopFrame() {
-    // determine screen size
-    Dimension screenSize = appClass.vncFrame.getToolkit().getScreenSize();
-    Dimension scrollSize = appClass.desktopScrollPane.getSize();
-
-    // Reduce Screen Size by 30 pixels in each direction;
-    // This is a (poor) attempt to account for
-    //     1) Menu bar on Macintosh (should really also account for
-    //        Dock on OSX).  Usually 22px on top of screen.
-    //     2) Taxkbar on Windows (usually about 28 px on bottom)
-    //     3) Other obstructions.
-    screenSize.height -= 30;
-    screenSize.width -= 30;
-
-    // Further reduce the screen size to account for the
-    // scroll pane's insets.
-    Insets insets = appClass.desktopScrollPane.getInsets();
-    screenSize.height -= insets.top + insets.bottom;
-    screenSize.width -= insets.left + insets.right;
-
-    // Limit pane size to fit on screen. 
-    boolean needResize = false;
-    if (scrollSize.width != rfb.framebufferWidth ||
-        scrollSize.height != rfb.framebufferHeight)
-      needResize = true;
-    int w = rfb.framebufferWidth, h = rfb.framebufferHeight;
-    if (w > screenSize.width) {
-      w = screenSize.width;
-      needResize = true;
-    }
-    if (h > screenSize.height) {
-      h = screenSize.height;
-      needResize = true;
-    }
-    if (needResize) {
-      appClass.desktopScrollPane.setSize(w, h);
-      appClass.desktopScrollPane.validate();
-    }
-
-    // size the canvas
-    setSize(getPreferredSize());
-
-    appClass.vncFrame.pack();
-  }
-
-  void resizeEmbeddedApplet() {
-    // resize scroll pane if necessary
-    Dimension scrollSize = appClass.desktopScrollPane.getSize();
-    if (scrollSize.width != appClass.dispW ||
-        scrollSize.height != appClass.dispH) {
-      appClass.desktopScrollPane.setSize(appClass.dispW, appClass.dispH);
-    }
-    appClass.desktopScrollPane.validate();
-    // size the canvas
-    setSize(getPreferredSize());
-  }
-
-  //
-  // processNormalProtocol() - executed by the rfbThread to deal with
-  // the RFB data.
-  //
-  public void processNormalProtocol() throws Exception {
-
-    zlibInflater = new Inflater();
-    tightInflaters = new Inflater[4];
-
-    // Show current time position in the control panel.
-    appClass.updatePos();
-
-    // Tell our FbsInputStream object to notify us when it goes to the
-    // `paused' mode.
-    appClass.fbs.addObserver(this);
-
-    //
-    // main dispatch loop
-    //
-
-    while (true) {
-
-      int msgType = rfb.readServerMessageType();
-
-      // Process the message depending on its type.
-      switch (msgType) {
-      case RfbProto.FramebufferUpdate:
-        rfb.readFramebufferUpdate();
-
-        for (int i = 0; i < rfb.updateNRects; i++) {
-          rfb.readFramebufferUpdateRectHdr();
-          int rx = rfb.updateRectX, ry = rfb.updateRectY;
-          int rw = rfb.updateRectW, rh = rfb.updateRectH;
-
-          if (rfb.updateRectEncoding == rfb.EncodingLastRect)
-            break;
-
-          if (rfb.updateRectEncoding == rfb.EncodingNewFBSize) {
-            if (rw != 0 && rh != 0) {
-              rfb.setFramebufferSize(rw, rh);
-              updateFramebufferSize();
-            }
-            break;
-          }
-
-          if (rfb.updateRectEncoding == rfb.EncodingXCursor ||
-              rfb.updateRectEncoding == rfb.EncodingRichCursor) {
-            handleCursorShapeUpdate(rfb.updateRectEncoding, rx, ry, rw, rh);
-            continue;
-          }
-
-          if (rfb.updateRectEncoding == rfb.EncodingPointerPos) {
-            softCursorMove(rx, ry);
-            continue;
-          }
-
-          switch (rfb.updateRectEncoding) {
-          case RfbProto.EncodingRaw:
-            handleRawRect(rx, ry, rw, rh);
-            break;
-          case RfbProto.EncodingCopyRect:
-            handleCopyRect(rx, ry, rw, rh);
-            break;
-          case RfbProto.EncodingRRE:
-            handleRRERect(rx, ry, rw, rh);
-            break;
-          case RfbProto.EncodingCoRRE:
-            handleCoRRERect(rx, ry, rw, rh);
-            break;
-          case RfbProto.EncodingHextile:
-            handleHextileRect(rx, ry, rw, rh);
-            break;
-          case RfbProto.EncodingZlib:
-            handleZlibRect(rx, ry, rw, rh);
-            break;
-          case RfbProto.EncodingTight:
-            handleTightRect(rx, ry, rw, rh);
-            break;
-          default:
-            throw new Exception("Unknown RFB rectangle encoding " +
-                                Integer.toString(rfb.updateRectEncoding, 16));
-          }
-        }
-        break;
-
-      case RfbProto.SetColourMapEntries:
-        throw new Exception("Can't handle SetColourMapEntries message");
-
-      case RfbProto.Bell:
-        Toolkit.getDefaultToolkit().beep();
-        break;
-
-      case RfbProto.ServerCutText:
-        rfb.readServerCutText();
-        break;
-
-      default:
-        throw new Exception("Unknown RFB message type " + msgType);
-      }
-
-      appClass.updatePos();
-    }
-  }
-
-
-  //
-  // Handle a raw rectangle. The second form with paint==false is used
-  // by the Hextile decoder for raw-encoded tiles.
-  //
-  void handleRawRect(int x, int y, int w, int h) throws IOException {
-    handleRawRect(x, y, w, h, true);
-  }
-
-  void handleRawRect(int x, int y, int w, int h, boolean paint)
-      throws IOException {
-
-    if (bytesPixel == 1) {
-      for (int dy = y; dy < y + h; dy++) {
-        rfb.is.readFully(pixels8, dy * rfb.framebufferWidth + x, w);
-      //if (rfb.rec != null) {
-      //  rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w);
-      //}
-      }
-    } else {
-      byte[] buf = new byte[w * 4];
-      int i, offset;
-      for (int dy = y; dy < y + h; dy++) {
-        rfb.is.readFully(buf);
-        //if (rfb.rec != null) {
-        //  rfb.rec.write(buf);
-        //}
-        offset = dy * rfb.framebufferWidth + x;
-        for (i = 0; i < w; i++) {
-          pixels24[offset + i] =
-              (buf[i * 4 + 2] & 0xFF) << 16 |
-              (buf[i * 4 + 1] & 0xFF) << 8 |
-              (buf[i * 4] & 0xFF);
-        }
-      }
-    }
-
-    handleUpdatedPixels(x, y, w, h);
-    if (paint)
-      scheduleRepaint(x, y, w, h);
-  }
-
-  //
-  // Handle a CopyRect rectangle.
-  //
-  void handleCopyRect(int x, int y, int w, int h) throws IOException {
-
-    rfb.readCopyRect();
-    memGraphics.copyArea(rfb.copyRectSrcX, rfb.copyRectSrcY, w, h,
-                         x - rfb.copyRectSrcX, y - rfb.copyRectSrcY);
-
-    scheduleRepaint(x, y, w, h);
-  }
-
-  //
-  // Handle an RRE-encoded rectangle.
-  //
-  void handleRRERect(int x, int y, int w, int h) throws IOException {
-
-    int nSubrects = rfb.is.readInt();
-    int sx, sy, sw, sh;
-
-    byte[] buf = new byte[4];
-    rfb.is.readFully(buf);
-    Color pixel = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-    memGraphics.setColor(pixel);
-    memGraphics.fillRect(x, y, w, h);
-
-    for (int j = 0; j < nSubrects; j++) {
-      rfb.is.readFully(buf);
-      pixel = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-      sx = x + rfb.is.readUnsignedShort();
-      sy = y + rfb.is.readUnsignedShort();
-      sw = rfb.is.readUnsignedShort();
-      sh = rfb.is.readUnsignedShort();
-
-      memGraphics.setColor(pixel);
-      memGraphics.fillRect(sx, sy, sw, sh);
-    }
-
-    scheduleRepaint(x, y, w, h);
-  }
-
-  //
-  // Handle a CoRRE-encoded rectangle.
-  //
-  void handleCoRRERect(int x, int y, int w, int h) throws IOException {
-    int nSubrects = rfb.is.readInt();
-    int sx, sy, sw, sh;
-
-    byte[] buf = new byte[4];
-    rfb.is.readFully(buf);
-    Color pixel = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-    memGraphics.setColor(pixel);
-    memGraphics.fillRect(x, y, w, h);
-
-    for (int j = 0; j < nSubrects; j++) {
-      rfb.is.readFully(buf);
-      pixel = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-      sx = x + rfb.is.readUnsignedByte();
-      sy = y + rfb.is.readUnsignedByte();
-      sw = rfb.is.readUnsignedByte();
-      sh = rfb.is.readUnsignedByte();
-
-      memGraphics.setColor(pixel);
-      memGraphics.fillRect(sx, sy, sw, sh);
-    }
-
-    scheduleRepaint(x, y, w, h);
-  }
-
-  //
-  // Handle a Hextile-encoded rectangle.
-  //
-
-  // These colors should be kept between handleHextileSubrect() calls.
-  private Color hextile_bg,  hextile_fg;
-
-  void handleHextileRect(int x, int y, int w, int h) throws IOException {
-
-    hextile_bg = new Color(0);
-    hextile_fg = new Color(0);
-
-    for (int ty = y; ty < y + h; ty += 16) {
-      int th = 16;
-      if (y + h - ty < 16)
-        th = y + h - ty;
-
-      for (int tx = x; tx < x + w; tx += 16) {
-        int tw = 16;
-        if (x + w - tx < 16)
-          tw = x + w - tx;
-
-        handleHextileSubrect(tx, ty, tw, th);
-      }
-
-      // Finished with a row of tiles, now let's show it.
-      scheduleRepaint(x, y, w, h);
-    }
-  }
-
-  //
-  // Handle one tile in the Hextile-encoded data.
-  //
-  void handleHextileSubrect(int tx, int ty, int tw, int th)
-      throws IOException {
-
-    byte[] buf = new byte[256 * 4];
-
-    int subencoding = rfb.is.readUnsignedByte();
-
-    // Is it a raw-encoded sub-rectangle?
-    if ((subencoding & rfb.HextileRaw) != 0) {
-      int count, offset;
-      for (int j = ty; j < ty + th; j++) {
-        rfb.is.readFully(buf, 0, tw * 4);
-        offset = j * rfb.framebufferWidth + tx;
-        for (count = 0; count < tw; count++) {
-          pixels24[offset + count] =
-              (buf[count * 4 + 2] & 0xFF) << 16 |
-              (buf[count * 4 + 1] & 0xFF) << 8 |
-              (buf[count * 4] & 0xFF);
-        }
-      }
-      handleUpdatedPixels(tx, ty, tw, th);
-      return;
-    }
-
-    // Read and draw the background if specified.
-    if ((subencoding & rfb.HextileBackgroundSpecified) != 0) {
-      rfb.is.readFully(buf, 0, 4);
-      hextile_bg = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-    }
-    memGraphics.setColor(hextile_bg);
-    memGraphics.fillRect(tx, ty, tw, th);
-
-    // Read the foreground color if specified.
-    if ((subencoding & rfb.HextileForegroundSpecified) != 0) {
-      rfb.is.readFully(buf, 0, 4);
-      hextile_fg = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-    }
-
-    // Done with this tile if there is no sub-rectangles.
-    if ((subencoding & rfb.HextileAnySubrects) == 0)
-      return;
-
-    int nSubrects = rfb.is.readUnsignedByte();
-
-    int b1, b2, sx, sy, sw, sh;
-    if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
-      for (int j = 0; j < nSubrects; j++) {
-        rfb.is.readFully(buf, 0, 4);
-        hextile_fg = new Color(buf[2] & 0xFF, buf[1] & 0xFF, buf[0] & 0xFF);
-        b1 = rfb.is.readUnsignedByte();
-        b2 = rfb.is.readUnsignedByte();
-        sx = tx + (b1 >> 4);
-        sy = ty + (b1 & 0xf);
-        sw = (b2 >> 4) + 1;
-        sh = (b2 & 0xf) + 1;
-        memGraphics.setColor(hextile_fg);
-        memGraphics.fillRect(sx, sy, sw, sh);
-      }
-
-    } else {
-      memGraphics.setColor(hextile_fg);
-      for (int j = 0; j < nSubrects; j++) {
-        b1 = rfb.is.readUnsignedByte();
-        b2 = rfb.is.readUnsignedByte();
-        sx = tx + (b1 >> 4);
-        sy = ty + (b1 & 0xf);
-        sw = (b2 >> 4) + 1;
-        sh = (b2 & 0xf) + 1;
-        memGraphics.fillRect(sx, sy, sw, sh);
-      }
-
-    }
-  }
-
-  //
-  // Handle a Zlib-encoded rectangle.
-  //
-  void handleZlibRect(int x, int y, int w, int h) throws Exception {
-
-    int nBytes = rfb.is.readInt();
-
-    if (zlibBuf == null || zlibBufLen < nBytes) {
-      zlibBufLen = nBytes * 2;
-      zlibBuf = new byte[zlibBufLen];
-    }
-
-    rfb.is.readFully(zlibBuf, 0, nBytes);
-    zlibInflater.setInput(zlibBuf, 0, nBytes);
-
-    try {
-      byte[] buf = new byte[w * 4];
-      int i, offset;
-      for (int dy = y; dy < y + h; dy++) {
-        zlibInflater.inflate(buf);
-        offset = dy * rfb.framebufferWidth + x;
-        for (i = 0; i < w; i++) {
-          pixels24[offset + i] =
-              (buf[i * 4 + 2] & 0xFF) << 16 |
-              (buf[i * 4 + 1] & 0xFF) << 8 |
-              (buf[i * 4] & 0xFF);
-        }
-      }
-    } catch (DataFormatException dfe) {
-      throw new Exception(dfe.toString());
-    }
-
-    handleUpdatedPixels(x, y, w, h);
-    scheduleRepaint(x, y, w, h);
-  }
-
-  //
-  // Handle a Tight-encoded rectangle.
-  //
-  void handleTightRect(int x, int y, int w, int h) throws Exception {
-
-    int comp_ctl = rfb.is.readUnsignedByte();
-
-    // Flush zlib streams if we are told by the server to do so.
-    for (int stream_id = 0; stream_id < 4; stream_id++) {
-      if ((comp_ctl & 1) != 0 && tightInflaters[stream_id] != null) {
-        tightInflaters[stream_id] = null;
-      }
-      comp_ctl >>= 1;
-    }
-
-    // Check correctness of subencoding value.
-    if (comp_ctl > rfb.TightMaxSubencoding) {
-      throw new Exception("Incorrect tight subencoding: " + comp_ctl);
-    }
-
-    // Handle solid-color rectangles.
-    if (comp_ctl == rfb.TightFill) {
-      byte[] buf = new byte[3];
-      rfb.is.readFully(buf);
-      Color bg = new Color(buf[0] & 0xFF, buf[1] & 0xFF, buf[2] & 0xFF);
-      memGraphics.setColor(bg);
-      memGraphics.fillRect(x, y, w, h);
-      scheduleRepaint(x, y, w, h);
-      return;
-
-    }
-
-    if (comp_ctl == rfb.TightJpeg) {
-
-      // Read JPEG data.
-      byte[] jpegData = new byte[rfb.readCompactLen()];
-      rfb.is.readFully(jpegData);
-
-      // Create an Image object from the JPEG data.
-      Image jpegImage = Toolkit.getDefaultToolkit().createImage(jpegData);
-
-      // Remember the rectangle where the image should be drawn.
-      jpegRect = new Rectangle(x, y, w, h);
-
-      // Let the imageUpdate() method do the actual drawing, here just
-      // wait until the image is fully loaded and drawn.
-      synchronized(jpegRect) {
-        Toolkit.getDefaultToolkit().prepareImage(jpegImage, -1, -1, this);
-        try {
-          // Wait no longer than three seconds.
-          jpegRect.wait(3000);
-        } catch (InterruptedException e) {
-          throw new Exception("Interrupted while decoding JPEG image");
-        }
-      }
-
-      // Done, jpegRect is not needed any more.
-      jpegRect = null;
-      return;
-
-    }
-
-    // Read filter id and parameters.
-    int numColors = 0, rowSize = w;
-    int[] palette24 = new int[256];
-    boolean useGradient = false;
-    if ((comp_ctl & rfb.TightExplicitFilter) != 0) {
-      int filter_id = rfb.is.readUnsignedByte();
-      if (filter_id == rfb.TightFilterPalette) {
-        numColors = rfb.is.readUnsignedByte() + 1;
-        byte[] buf = new byte[numColors * 3];
-        rfb.is.readFully(buf);
-        for (int i = 0; i < numColors; i++) {
-          palette24[i] = ((buf[i * 3] & 0xFF) << 16 |
-              (buf[i * 3 + 1] & 0xFF) << 8 |
-              (buf[i * 3 + 2] & 0xFF));
-        }
-        if (numColors == 2)
-          rowSize = (w + 7) / 8;
-      } else if (filter_id == rfb.TightFilterGradient) {
-        useGradient = true;
-      } else if (filter_id != rfb.TightFilterCopy) {
-        throw new Exception("Incorrect tight filter id: " + filter_id);
-      }
-    }
-    if (numColors == 0 && bytesPixel == 4)
-      rowSize *= 3;
-
-    // Read, optionally uncompress and decode data.
-    int dataSize = h * rowSize;
-    if (dataSize < rfb.TightMinToCompress) {
-      // Data size is small - not compressed with zlib.
-      if (numColors != 0) {
-        // Indexed colors.
-        byte[] indexedData = new byte[dataSize];
-        rfb.is.readFully(indexedData);
-        if (numColors == 2) {
-          // Two colors.
-          //if (bytesPixel == 1) {
-          //  decodeMonoData(x, y, w, h, indexedData, palette8);
-          //} else {
-          decodeMonoData(x, y, w, h, indexedData, palette24);
-        //}
-        } else {
-          // 3..255 colors (assuming bytesPixel == 4).
-          int i = 0;
-          for (int dy = y; dy < y + h; dy++) {
-            for (int dx = x; dx < x + w; dx++) {
-              pixels24[dy * rfb.framebufferWidth + dx] =
-                  palette24[indexedData[i++] & 0xFF];
-            }
-          }
-        }
-      } else if (useGradient) {
-        // "Gradient"-processed data
-        byte[] buf = new byte[w * h * 3];
-        rfb.is.readFully(buf);
-        decodeGradientData(x, y, w, h, buf);
-      } else {
-        // Raw truecolor data.
-        if (bytesPixel == 1) {
-          for (int dy = y; dy < y + h; dy++) {
-            rfb.is.readFully(pixels8, dy * rfb.framebufferWidth + x, w);
-          //if (rfb.rec != null) {
-          //  rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w);
-          //}
-          }
-        } else {
-          byte[] buf = new byte[w * 3];
-          int i, offset;
-          for (int dy = y; dy < y + h; dy++) {
-            rfb.is.readFully(buf);
-            //if (rfb.rec != null) {
-            //  rfb.rec.write(buf);
-            //}
-            offset = dy * rfb.framebufferWidth + x;
-            for (i = 0; i < w; i++) {
-              pixels24[offset + i] =
-                  (buf[i * 3] & 0xFF) << 16 |
-                  (buf[i * 3 + 1] & 0xFF) << 8 |
-                  (buf[i * 3 + 2] & 0xFF);
-            }
-          }
-        }
-      }
-    } else {
-      // Data was compressed with zlib.
-      int zlibDataLen = rfb.readCompactLen();
-      byte[] zlibData = new byte[zlibDataLen];
-      rfb.is.readFully(zlibData);
-      int stream_id = comp_ctl & 0x03;
-      if (tightInflaters[stream_id] == null) {
-        tightInflaters[stream_id] = new Inflater();
-      }
-      Inflater myInflater = tightInflaters[stream_id];
-      myInflater.setInput(zlibData);
-      try {
-        if (numColors != 0) {
-          // Indexed colors.
-          byte[] indexedData = new byte[dataSize];
-          myInflater.inflate(indexedData);
-          if (numColors == 2) {
-            // Two colors.
-            decodeMonoData(x, y, w, h, indexedData, palette24);
-          } else {
-            // More than two colors.
-            int i = 0;
-            for (int dy = y; dy < y + h; dy++) {
-              for (int dx = x; dx < x + w; dx++) {
-                pixels24[dy * rfb.framebufferWidth + dx] =
-                    palette24[indexedData[i++] & 0xFF];
-              }
-            }
-          }
-        } else if (useGradient) {
-          // Compressed "Gradient"-filtered data.
-          byte[] buf = new byte[w * h * 3];
-          myInflater.inflate(buf);
-          decodeGradientData(x, y, w, h, buf);
-        } else {
-          // Compressed truecolor data.
-          byte[] buf = new byte[w * 3];
-          int i, offset;
-          for (int dy = y; dy < y + h; dy++) {
-            myInflater.inflate(buf);
-            offset = dy * rfb.framebufferWidth + x;
-            for (i = 0; i < w; i++) {
-              pixels24[offset + i] =
-                  (buf[i * 3] & 0xFF) << 16 |
-                  (buf[i * 3 + 1] & 0xFF) << 8 |
-                  (buf[i * 3 + 2] & 0xFF);
-            }
-          }
-        }
-      } catch (DataFormatException dfe) {
-        throw new Exception(dfe.toString());
-      }
-    }
-
-    handleUpdatedPixels(x, y, w, h);
-    scheduleRepaint(x, y, w, h);
-  }
-
-  //
-  // Decode 1bpp-encoded bi-color rectangle (8-bit and 24-bit versions).
-  //
-  void decodeMonoData(int x, int y, int w, int h, byte[] src, byte[] palette) {
-
-    int dx, dy, n;
-    int i = y * rfb.framebufferWidth + x;
-    int rowBytes = (w + 7) / 8;
-    byte b;
-
-    for (dy = 0; dy < h; dy++) {
-      for (dx = 0; dx < w / 8; dx++) {
-        b = src[dy * rowBytes + dx];
-        for (n = 7; n >= 0; n--)
-          pixels8[i++] = palette[b >> n & 1];
-      }
-      for (n = 7; n >= 8 - w % 8; n--) {
-        pixels8[i++] = palette[src[dy * rowBytes + dx] >> n & 1];
-      }
-      i += (rfb.framebufferWidth - w);
-    }
-  }
-
-  void decodeMonoData(int x, int y, int w, int h, byte[] src, int[] palette) {
-
-    int dx, dy, n;
-    int i = y * rfb.framebufferWidth + x;
-    int rowBytes = (w + 7) / 8;
-    byte b;
-
-    for (dy = 0; dy < h; dy++) {
-      for (dx = 0; dx < w / 8; dx++) {
-        b = src[dy * rowBytes + dx];
-        for (n = 7; n >= 0; n--)
-          pixels24[i++] = palette[b >> n & 1];
-      }
-      for (n = 7; n >= 8 - w % 8; n--) {
-        pixels24[i++] = palette[src[dy * rowBytes + dx] >> n & 1];
-      }
-      i += (rfb.framebufferWidth - w);
-    }
-  }
-
-  //
-  // Decode data processed with the "Gradient" filter.
-  //
-  void decodeGradientData(int x, int y, int w, int h, byte[] buf) {
-
-    int dx, dy, c;
-    byte[] prevRow = new byte[w * 3];
-    byte[] thisRow = new byte[w * 3];
-    byte[] pix = new byte[3];
-    int[] est = new int[3];
-
-    int offset = y * rfb.framebufferWidth + x;
-
-    for (dy = 0; dy < h; dy++) {
-
-      /* First pixel in a row */
-      for (c = 0; c < 3; c++) {
-        pix[c] = (byte)(prevRow[c] + buf[dy * w * 3 + c]);
-        thisRow[c] = pix[c];
-      }
-      pixels24[offset++] =
-          (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF);
-
-      /* Remaining pixels of a row */
-      for (dx = 1; dx < w; dx++) {
-        for (c = 0; c < 3; c++) {
-          est[c] = ((prevRow[dx * 3 + c] & 0xFF) + (pix[c] & 0xFF) -
-              (prevRow[(dx - 1) * 3 + c] & 0xFF));
-          if (est[c] > 0xFF) {
-            est[c] = 0xFF;
-          } else if (est[c] < 0x00) {
-            est[c] = 0x00;
-          }
-          pix[c] = (byte)(est[c] + buf[(dy * w + dx) * 3 + c]);
-          thisRow[dx * 3 + c] = pix[c];
-        }
-        pixels24[offset++] =
-            (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF);
-      }
-
-      System.arraycopy(thisRow, 0, prevRow, 0, w * 3);
-      offset += (rfb.framebufferWidth - w);
-    }
-  }
-
-  //
-  // Display newly updated area of pixels.
-  //
-  void handleUpdatedPixels(int x, int y, int w, int h) {
-
-    // Draw updated pixels of the off-screen image.
-    pixelsSource.newPixels(x, y, w, h);
-    memGraphics.setClip(x, y, w, h);
-    memGraphics.drawImage(rawPixelsImage, 0, 0, null);
-    memGraphics.setClip(0, 0, rfb.framebufferWidth, rfb.framebufferHeight);
-  }
-
-  //
-  // Tell JVM to repaint specified desktop area.
-  //
-  void scheduleRepaint(int x, int y, int w, int h) {
-    if (appClass.fbs.isSeeking()) {
-      // Do nothing, and remember we are seeking.
-      seekMode = true;
-    } else {
-      if (seekMode) {
-        // Immediate repaint of the whole desktop after seeking.
-        seekMode = false;
-        if (showSoftCursor)
-          scrollToPoint(cursorX, cursorY);
-        updateFramebufferSize();
-        repaint();
-      } else {
-        // Usual incremental repaint.
-        Point o = getImageOrigin();
-        repaint(appClass.deferScreenUpdates, o.x + x, o.y + y, w, h);
-      }
-    }
-  }
-
-
-  //////////////////////////////////////////////////////////////////
-  //
-  // Handle cursor shape updates (XCursor and RichCursor encodings).
-  //
-  boolean showSoftCursor = false;
-
-  MemoryImageSource softCursorSource;
-  Image softCursor;
-
-  int cursorX = 0, cursorY = 0;
-  int cursorWidth, cursorHeight;
-  int origCursorWidth, origCursorHeight;
-  int hotX, hotY;
-  int origHotX, origHotY;
-
-  //
-  // Handle cursor shape update (XCursor and RichCursor encodings).
-  //
-  synchronized void handleCursorShapeUpdate(int encodingType,
-                                             int xhot, int yhot, int width,
-                                             int height)
-      throws IOException {
-
-    softCursorFree();
-
-    if (width * height == 0)
-      return;
-
-    // Ignore cursor shape data if requested by user.
-    //if (appClass.options.ignoreCursorUpdates) {
-    if (false) {
-      int bytesPerRow = (width + 7) / 8;
-      int bytesMaskData = bytesPerRow * height;
-
-      if (encodingType == rfb.EncodingXCursor) {
-        rfb.is.skipBytes(6 + bytesMaskData * 2);
-      } else {
-        // rfb.EncodingRichCursor
-        rfb.is.skipBytes(width * height + bytesMaskData);
-      }
-      return;
-    }
-
-    // Decode cursor pixel data.
-    softCursorSource = decodeCursorShape(encodingType, width, height);
-
-    // Set original (non-scaled) cursor dimensions.
-    origCursorWidth = width;
-    origCursorHeight = height;
-    origHotX = xhot;
-    origHotY = yhot;
-
-    // Create off-screen cursor image.
-    createSoftCursor();
-
-    // Show the cursor.
-    showSoftCursor = true;
-    Point p = getImageOrigin();
-    scheduleCursorRepaint(cursorX - hotX + p.x, cursorY - hotY + p.y,
-                          cursorWidth, cursorHeight, 5);
-  }
-
-  //
-  // decodeCursorShape(). Decode cursor pixel data and return
-  // corresponding MemoryImageSource instance.
-  //
-  synchronized MemoryImageSource decodeCursorShape(int encodingType, int width,
-                                                    int height)
-      throws IOException {
-
-    int bytesPerRow = (width + 7) / 8;
-    int bytesMaskData = bytesPerRow * height;
-
-    int[] softCursorPixels = new int[width * height];
-
-    if (encodingType == rfb.EncodingXCursor) {
-
-      // Read foreground and background colors of the cursor.
-      byte[] rgb = new byte[6];
-      rfb.is.readFully(rgb);
-      int[] colors = {(0xFF000000 | (rgb[3] & 0xFF) << 16 |
-                      (rgb[4] & 0xFF) << 8 | (rgb[5] & 0xFF)),
-                      (0xFF000000 | (rgb[0] & 0xFF) << 16 |
-                      (rgb[1] & 0xFF) << 8 | (rgb[2] & 0xFF))
-      };
-
-      // Read pixel and mask data.
-      byte[] pixBuf = new byte[bytesMaskData];
-      rfb.is.readFully(pixBuf);
-      byte[] maskBuf = new byte[bytesMaskData];
-      rfb.is.readFully(maskBuf);
-
-      // Decode pixel data into softCursorPixels[].
-      byte pixByte, maskByte;
-      int x, y, n, result;
-      int i = 0;
-      for (y = 0; y < height; y++) {
-        for (x = 0; x < width / 8; x++) {
-          pixByte = pixBuf[y * bytesPerRow + x];
-          maskByte = maskBuf[y * bytesPerRow + x];
-          for (n = 7; n >= 0; n--) {
-            if ((maskByte >> n & 1) != 0) {
-              result = colors[pixByte >> n & 1];
-            } else {
-              result = 0;	// Transparent pixel
-            }
-            softCursorPixels[i++] = result;
-          }
-        }
-        for (n = 7; n >= 8 - width % 8; n--) {
-          if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) {
-            result = colors[pixBuf[y * bytesPerRow + x] >> n & 1];
-          } else {
-            result = 0;		// Transparent pixel
-          }
-          softCursorPixels[i++] = result;
-        }
-      }
-
-    } else {
-      // encodingType == rfb.EncodingRichCursor
-
-      // Read pixel and mask data.
-      byte[] pixBuf = new byte[width * height * bytesPixel];
-      rfb.is.readFully(pixBuf);
-      byte[] maskBuf = new byte[bytesMaskData];
-      rfb.is.readFully(maskBuf);
-
-      // Decode pixel data into softCursorPixels[].
-      byte maskByte;
-      int x, y, n, result;
-      int i = 0;
-      for (y = 0; y < height; y++) {
-        for (x = 0; x < width / 8; x++) {
-          maskByte = maskBuf[y * bytesPerRow + x];
-          for (n = 7; n >= 0; n--) {
-            if ((maskByte >> n & 1) != 0) {
-              if (bytesPixel == 1) {
-                result = cm8.getRGB(pixBuf[i]);
-              } else {
-                result = (pixBuf[i * 4] & 0xFF) << 24 |
-                    (pixBuf[i * 4 + 1] & 0xFF) << 16 |
-                    (pixBuf[i * 4 + 2] & 0xFF) << 8 |
-                    (pixBuf[i * 4 + 3] & 0xFF);
-              }
-            } else {
-              result = 0;	// Transparent pixel
-            }
-            softCursorPixels[i++] = result;
-          }
-        }
-        for (n = 7; n >= 8 - width % 8; n--) {
-          if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) {
-            if (bytesPixel == 1) {
-              result = cm8.getRGB(pixBuf[i]);
-            } else {
-              result = 0xFF000000 |
-                  (pixBuf[i * 4 + 1] & 0xFF) << 16 |
-                  (pixBuf[i * 4 + 2] & 0xFF) << 8 |
-                  (pixBuf[i * 4 + 3] & 0xFF);
-            }
-          } else {
-            result = 0;		// Transparent pixel
-          }
-          softCursorPixels[i++] = result;
-        }
-      }
-
-    }
-
-    return new MemoryImageSource(width, height, softCursorPixels, 0, width);
-  }
-
-  //
-  // createSoftCursor(). Assign softCursor new Image (scaled if necessary).
-  // Uses softCursorSource as a source for new cursor image.
-  //
-  synchronized void createSoftCursor() {
-
-    if (softCursorSource == null)
-      return;
-
-    int scaleCursor = 100;
-    //int scaleCursor = appClass.options.scaleCursor;
-    //if (scaleCursor == 0 || !inputEnabled)
-    //scaleCursor = 100;
-
-    cursorWidth = (origCursorWidth * scaleCursor + 50) / 100;
-    cursorHeight = (origCursorHeight * scaleCursor + 50) / 100;
-    hotX = (origHotX * scaleCursor + 50) / 100;
-    hotY = (origHotY * scaleCursor + 50) / 100;
-    softCursor = Toolkit.getDefaultToolkit().createImage(softCursorSource);
-
-    if (scaleCursor != 100) {
-      softCursor = softCursor.getScaledInstance(cursorWidth, cursorHeight,
-                                                Image.SCALE_SMOOTH);
-    }
-  }
-
-  private void scrollToPoint(int x, int y) {
-    // Automatic viewport scrolling 
-    if (appClass.desktopScrollPane != null) {
-      boolean needScroll = false;
-      Dimension d = appClass.desktopScrollPane.getViewportSize();
-      Point topLeft = appClass.desktopScrollPane.getScrollPosition();
-      Point botRight = new Point(topLeft.x + d.width, topLeft.y + d.height);
-
-      if (x < topLeft.x + SCROLL_MARGIN) {
-        // shift left
-        topLeft.x = x - SCROLL_MARGIN;
-        needScroll = true;
-      } else if (x > botRight.x - SCROLL_MARGIN) {
-        // shift right
-        topLeft.x = x - d.width + SCROLL_MARGIN;
-        needScroll = true;
-      }
-      if (y < topLeft.y + SCROLL_MARGIN) {
-        // shift up
-        topLeft.y = y - SCROLL_MARGIN;
-        needScroll = true;
-      } else if (y > botRight.y - SCROLL_MARGIN) {
-        // shift down
-        topLeft.y = y - d.height + SCROLL_MARGIN;
-        needScroll = true;
-      }
-      if (needScroll)
-        appClass.desktopScrollPane.setScrollPosition(topLeft.x, topLeft.y);
-    }
-  }
-
-  //
-  // softCursorMove(). Moves soft cursor into a particular location.
-  //
-  synchronized void softCursorMove(int x, int y) {
-    Point o = getImageOrigin();
-    int oldX = cursorX + o.x;
-    int oldY = cursorY + o.y;
-    cursorX = x;
-    cursorY = y;
-    if (showSoftCursor) {
-      scheduleCursorRepaint(oldX - hotX, oldY - hotY, cursorWidth, cursorHeight,
-                            0);
-      scheduleCursorRepaint(cursorX - hotX + o.x, cursorY - hotY + o.y,
-                            cursorWidth, cursorHeight, 1);
-      if (!seekMode)
-        scrollToPoint(x, y);
-    }
-  }
-
-  //
-  // softCursorFree(). Remove soft cursor, dispose resources.
-  //
-  synchronized void softCursorFree() {
-    if (showSoftCursor) {
-      showSoftCursor = false;
-      softCursor = null;
-      softCursorSource = null;
-
-      Point p = getImageOrigin();
-      scheduleCursorRepaint(cursorX - hotX + p.x, cursorY - hotY + p.y,
-                            cursorWidth, cursorHeight, 3);
-    }
-  }
-
-  Point getFrameCenter() {
-    Dimension d = appClass.desktopScrollPane.getViewportSize();
-    Point p = appClass.desktopScrollPane.getScrollPosition();
-    if (d.width > rfb.framebufferWidth)
-      p.x = d.width / 2;
-    else
-      p.x += d.width / 2;
-    if (d.height > rfb.framebufferHeight)
-      p.y = d.height / 2;
-    else
-      p.y += d.height / 2;
-    return p;
-  }
-
-  //
-  // We are observing our FbsInputStream object to get notified on
-  // switching to the `paused' mode. In such cases we want to repaint
-  // our desktop if we were seeking.
-  //
-  public void update(Observable o, Object arg) {
-    // Immediate repaint of the whole desktop after seeking.
-    repaint();
-    // Let next scheduleRepaint() call invoke incremental drawing.
-    seekMode = false;
-  }
-
-  void scheduleCursorRepaint(int x, int y, int w, int h, int n) {
-    if (appClass.fbs.isSeeking()) {
-      // Do nothing, and remember we are seeking.
-      seekMode = true;
-    } else {
-      if (seekMode) {
-        // Immediate repaint of the whole desktop after seeking.
-        seekMode = false;
-        if (showSoftCursor)
-          scrollToPoint(cursorX, cursorY);
-        updateFramebufferSize();
-        repaint();
-      } else {
-        // Usual incremental repaint.
-        repaint(appClass.deferScreenUpdates, x, y, w, h);
-      }
-    }
-  }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/index.html b/java/src/com/tightvnc/rfbplayer/index.html
deleted file mode 100644
index 303bc5d..0000000
--- a/java/src/com/tightvnc/rfbplayer/index.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<HTML>
-<TITLE>RFB Session Playback</TITLE>
-<BODY>
-<APPLET CODE=RfbPlayer.class ARCHIVE=RfbPlayer.jar
-        WIDTH=800 HEIGHT=640>
-<param name=URL value="session.fbs">
-</APPLET>
-</BODY>
-</HTML>
