]> source.dussan.org Git - tigervnc.git/commitdiff
Preliminary version of RFB Session Player converted from TightVNC Java
authorConstantin Kaplinsky <const@tightvnc.com>
Mon, 20 May 2002 10:55:47 +0000 (10:55 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Mon, 20 May 2002 10:55:47 +0000 (10:55 +0000)
viewer sources.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2500 3789f03b-4d11-0410-bbf8-ca57d06f2519

19 files changed:
java/src/com/tightvnc/rfbplayer/AuthPanel.java [deleted file]
java/src/com/tightvnc/rfbplayer/ButtonPanel.java
java/src/com/tightvnc/rfbplayer/ClipboardFrame.java [deleted file]
java/src/com/tightvnc/rfbplayer/DesCipher.java [deleted file]
java/src/com/tightvnc/rfbplayer/FbsInputStream.java [new file with mode: 0644]
java/src/com/tightvnc/rfbplayer/Makefile
java/src/com/tightvnc/rfbplayer/OptionsFrame.java [deleted file]
java/src/com/tightvnc/rfbplayer/README
java/src/com/tightvnc/rfbplayer/RfbPlayer.java
java/src/com/tightvnc/rfbplayer/RfbProto.java
java/src/com/tightvnc/rfbplayer/VncCanvas.java
java/src/com/tightvnc/rfbplayer/dir.mk [deleted file]
java/src/com/tightvnc/rfbplayer/hextile.vnc [deleted file]
java/src/com/tightvnc/rfbplayer/index.html [new file with mode: 0644]
java/src/com/tightvnc/rfbplayer/index.vnc [deleted file]
java/src/com/tightvnc/rfbplayer/noshared.vnc [deleted file]
java/src/com/tightvnc/rfbplayer/shared.vnc [deleted file]
java/src/com/tightvnc/rfbplayer/tight.vnc [deleted file]
java/src/com/tightvnc/rfbplayer/zlib.vnc [deleted file]

diff --git a/java/src/com/tightvnc/rfbplayer/AuthPanel.java b/java/src/com/tightvnc/rfbplayer/AuthPanel.java
deleted file mode 100644 (file)
index cdc4fe8..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-//  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.
-//
-
-import java.awt.*;
-import java.awt.event.*;
-
-//
-// The panel which implements the user authentication scheme
-//
-
-class AuthPanel extends Panel implements ActionListener {
-
-  Label title, retry, prompt;
-  TextField password;
-  Button ok;
-
-  //
-  // Constructor.
-  //
-
-  public AuthPanel() {
-
-    title = new Label("VNC Authentication",Label.CENTER);
-    title.setFont(new Font("Helvetica", Font.BOLD, 18));
-
-    prompt = new Label("Password:",Label.CENTER);
-
-    password = new TextField(10);
-    password.setForeground(Color.black);
-    password.setBackground(Color.white);
-    password.setEchoChar('*');
-
-    ok = new Button("OK");
-
-    retry = new Label("",Label.CENTER);
-    retry.setFont(new Font("Courier", Font.BOLD, 16));
-
-
-    GridBagLayout gridbag = new GridBagLayout();
-    GridBagConstraints gbc = new GridBagConstraints();
-
-    setLayout(gridbag);
-
-    gbc.gridwidth = GridBagConstraints.REMAINDER;
-    gridbag.setConstraints(title,gbc);
-    add(title);
-
-    gbc.fill = GridBagConstraints.HORIZONTAL;
-    gridbag.setConstraints(retry,gbc);
-    add(retry);
-
-    gbc.fill = GridBagConstraints.NONE;
-    gbc.gridwidth = 1;
-    gridbag.setConstraints(prompt,gbc);
-    add(prompt);
-
-    gridbag.setConstraints(password,gbc);
-    add(password);
-    password.addActionListener(this);
-
-    gbc.ipady = 10;
-    gbc.gridwidth = GridBagConstraints.REMAINDER;
-    gbc.fill = GridBagConstraints.BOTH;
-    gbc.insets = new Insets(0,20,0,0);
-    gbc.ipadx = 40;
-    gridbag.setConstraints(ok,gbc);
-    add(ok);
-    ok.addActionListener(this);
-  }
-
-  //
-  // Move keyboard focus to the password text field object.
-  //
-
-  public void moveFocusToPasswordField() {
-    password.requestFocus();
-  }
-
-  //
-  // This method is called when a button is pressed or return is
-  // pressed in the password text field.
-  //
-
-  public synchronized void actionPerformed(ActionEvent evt) {
-    if (evt.getSource() == password || evt.getSource() == ok) {
-      notify();
-    }
-  }
-
-  //
-  // retry().
-  //
-
-  public void retry() {
-    retry.setText("Sorry. Try again.");
-    password.setText("");
-    moveFocusToPasswordField();
-  }
-
-}
index de3ddfee6c229659dc9f1fe1f02289122e3a6ef3..e7cabb58259178ce1f32c35437a188a60504ac4e 100644 (file)
@@ -1,6 +1,5 @@
 //
-//  Copyright (C) 2001,2002 HorizonLive.com, Inc.  All Rights Reserved.
-//  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
+//  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
 //  USA.
 //
 
-//
-// ButtonPanel class implements panel with four buttons in the
-// VNCViewer desktop window.
-//
-
 import java.awt.*;
 import java.awt.event.*;
 import java.io.*;
 
 class ButtonPanel extends Panel implements ActionListener {
 
-  VncViewer viewer;
-  Button disconnectButton;
-  Button optionsButton;
-  Button clipboardButton;
-  Button ctrlAltDelButton;
-  Button refreshButton;
+  protected RfbPlayer player;
+  protected Button playButton;
+  protected Button pauseButton;
 
-  ButtonPanel(VncViewer v) {
-    viewer = v;
+  ButtonPanel(RfbPlayer player) {
+    this.player = player;
 
     setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-    disconnectButton = new Button("Disconnect");
-    disconnectButton.setEnabled(false);
-    add(disconnectButton);
-    disconnectButton.addActionListener(this);
-    optionsButton = new Button("Options");
-    add(optionsButton);
-    optionsButton.addActionListener(this);
-    clipboardButton = new Button("Clipboard");
-    clipboardButton.setEnabled(false);
-    add(clipboardButton);
-    clipboardButton.addActionListener(this);
-    ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
-    ctrlAltDelButton.setEnabled(false);
-    add(ctrlAltDelButton);
-    ctrlAltDelButton.addActionListener(this);
-    refreshButton = new Button("Refresh");
-    refreshButton.setEnabled(false);
-    add(refreshButton);
-    refreshButton.addActionListener(this);
-  }
 
-  public void enableButtons() {
-    disconnectButton.setEnabled(true);
-    clipboardButton.setEnabled(true);
-    refreshButton.setEnabled(true);
-  }
+    playButton = new Button("Play");
+    playButton.setEnabled(false);
+    add(playButton);
+    playButton.addActionListener(this);
 
-  //
-  // Enable/disable controls that should not be available in view-only
-  // mode.
-  //
+    pauseButton = new Button("Pause");
+    pauseButton.setEnabled(false);
+    add(pauseButton);
+    pauseButton.addActionListener(this);
+  }
 
-  void enableRemoteAccessControls(boolean enable) {
-    ctrlAltDelButton.setEnabled(enable);
+  public void setMode(int mode) {
+    switch(mode) {
+    case RfbPlayer.MODE_PLAYBACK:
+      playButton.setLabel("Stop");
+      playButton.setEnabled(true);
+      pauseButton.setLabel("Pause");
+      pauseButton.setEnabled(true);
+      break;
+    case RfbPlayer.MODE_PAUSED:
+      playButton.setLabel("Stop");
+      playButton.setEnabled(true);
+      pauseButton.setLabel("Resume");
+      pauseButton.setEnabled(true);
+      break;
+    default:
+      // case RfbPlayer.MODE_STOPPED:
+      playButton.setLabel("Play");
+      playButton.setEnabled(true);
+      pauseButton.setLabel("Pause");
+      pauseButton.setEnabled(false);
+      break;
+    }
+    player.setMode(mode);
   }
 
   //
@@ -81,40 +73,13 @@ class ButtonPanel extends Panel implements ActionListener {
   //
 
   public void actionPerformed(ActionEvent evt) {
-    if (evt.getSource() == disconnectButton) {
-      viewer.disconnect();
-
-    } else if (evt.getSource() == optionsButton) {
-      viewer.options.setVisible(!viewer.options.isVisible());
-
-    } else if (evt.getSource() == clipboardButton) {
-      viewer.clipboard.setVisible(!viewer.clipboard.isVisible());
-
-    } else if (evt.getSource() == ctrlAltDelButton) {
-      try {
-        final int modifiers = InputEvent.CTRL_MASK | InputEvent.ALT_MASK;
-
-        KeyEvent ctrlAltDelEvent =
-          new KeyEvent(this, KeyEvent.KEY_PRESSED, 0, modifiers, 127);
-        viewer.rfb.writeKeyEvent(ctrlAltDelEvent);
-
-        ctrlAltDelEvent =
-          new KeyEvent(this, KeyEvent.KEY_RELEASED, 0, modifiers, 127);
-        viewer.rfb.writeKeyEvent(ctrlAltDelEvent);
-
-      } catch (IOException e) {
-        e.printStackTrace();
-      }
-    } else if (evt.getSource() == refreshButton) {
-      try {
-       RfbProto rfb = viewer.rfb;
-       rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
-                                         rfb.framebufferHeight, false);
-      } catch (IOException e) {
-        e.printStackTrace();
-      }
+    if (evt.getSource() == playButton) {
+      setMode((player.getMode() == RfbPlayer.MODE_STOPPED) ?
+              RfbPlayer.MODE_PLAYBACK : RfbPlayer.MODE_STOPPED);
+    } else if (evt.getSource() == pauseButton) {
+      setMode((player.getMode() == RfbPlayer.MODE_PAUSED) ?
+              RfbPlayer.MODE_PLAYBACK : RfbPlayer.MODE_PAUSED);
     }
-    viewer.moveFocusToDesktop();
   }
 }
 
diff --git a/java/src/com/tightvnc/rfbplayer/ClipboardFrame.java b/java/src/com/tightvnc/rfbplayer/ClipboardFrame.java
deleted file mode 100644 (file)
index f0a5b8d..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-//
-//  Copyright (C) 2001 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.
-//
-
-//
-// Clipboard frame.
-//
-
-import java.awt.*;
-import java.awt.event.*;
-
-class ClipboardFrame extends Frame
-  implements WindowListener, ActionListener {
-
-  TextArea textArea;
-  Button clearButton, closeButton;
-  String selection;
-  VncViewer viewer;
-
-  //
-  // Constructor.
-  //
-
-  ClipboardFrame(VncViewer v) {
-    super("TightVNC Clipboard");
-
-    viewer = v;
-
-    GridBagLayout gridbag = new GridBagLayout();
-    setLayout(gridbag);
-
-    GridBagConstraints gbc = new GridBagConstraints();
-    gbc.gridwidth = GridBagConstraints.REMAINDER;
-    gbc.fill = GridBagConstraints.BOTH;
-    gbc.weighty = 1.0;
-
-    textArea = new TextArea(5, 40);
-    gridbag.setConstraints(textArea, gbc);
-    add(textArea);
-
-    gbc.fill = GridBagConstraints.HORIZONTAL;
-    gbc.weightx = 1.0;
-    gbc.weighty = 0.0;
-    gbc.gridwidth = 1;
-
-    clearButton = new Button("Clear");
-    gridbag.setConstraints(clearButton, gbc);
-    add(clearButton);
-    clearButton.addActionListener(this);
-
-    closeButton = new Button("Close");
-    gridbag.setConstraints(closeButton, gbc);
-    add(closeButton);
-    closeButton.addActionListener(this);
-
-    pack();
-
-    addWindowListener(this);
-  }
-
-
-  //
-  // Set the cut text from the RFB server.
-  //
-
-  void setCutText(String text) {
-    selection = text;
-    textArea.setText(text);
-    if (isVisible()) {
-      textArea.selectAll();
-    }
-  }
-
-
-  //
-  // When the focus leaves the window, see if we have new cut text and
-  // if so send it to the RFB server.
-  //
-
-  public void windowDeactivated (WindowEvent evt) {
-    if (selection != null && !selection.equals(textArea.getText())) {
-      selection = textArea.getText();
-      viewer.setCutText(selection);
-    }
-  }
-
-  //
-  // Close our window properly.
-  //
-
-  public void windowClosing(WindowEvent evt) {
-    setVisible(false);
-  }
-
-  //
-  // Ignore window events we're not interested in.
-  //
-
-  public void windowActivated(WindowEvent evt) {}
-  public void windowOpened(WindowEvent evt) {}
-  public void windowClosed(WindowEvent evt) {}
-  public void windowIconified(WindowEvent evt) {}
-  public void windowDeiconified(WindowEvent evt) {}
-
-
-  //
-  // Respond to button presses
-  //
-
-  public void actionPerformed(ActionEvent evt) {
-    if (evt.getSource() == clearButton) {
-      textArea.setText("");
-    } else if (evt.getSource() == closeButton) {
-      setVisible(false);
-    }
-  }
-}
diff --git a/java/src/com/tightvnc/rfbplayer/DesCipher.java b/java/src/com/tightvnc/rfbplayer/DesCipher.java
deleted file mode 100644 (file)
index 2b7b5f2..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-//
-// This DES class has been extracted from package Acme.Crypto for use in VNC.
-// The bytebit[] array has been reversed so that the most significant bit
-// in each byte of the key is ignored, not the least significant.  Also the
-// unnecessary odd parity code has been removed.
-//
-// These changes are:
-//  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
-//
-// 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.
-//
-
-// DesCipher - the DES encryption method
-//
-// The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
-//
-// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
-//
-// Permission to use, copy, modify, and distribute this software
-// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
-// without fee is hereby granted, provided that this copyright notice is kept 
-// intact. 
-// 
-// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
-// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
-// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
-// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
-// 
-// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
-// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
-// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
-// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
-// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
-// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
-// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  WIDGET WORKSHOP
-// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
-// HIGH RISK ACTIVITIES.
-//
-//
-// The rest is:
-//
-// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-//    notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-//    notice, this list of conditions and the following disclaimer in the
-//    documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-//
-// Visit the ACME Labs Java page for up-to-date versions of this and other
-// fine Java utilities: http://www.acme.com/java/
-
-
-import java.io.*;
-
-/// The DES encryption method.
-// <P>
-// This is surprisingly fast, for pure Java.  On a SPARC 20, wrapped
-// in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream,
-// it does around 7000 bytes/second.
-// <P>
-// Most of this code is by Dave Zimmerman <dzimm@widget.com>, and is
-// Copyright (c) 1996 Widget Workshop, Inc.  See the source file for details.
-// <P>
-// <A HREF="/resources/classes/Acme/Crypto/DesCipher.java">Fetch the software.</A><BR>
-// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
-// <P>
-// @see Des3Cipher
-// @see EncryptedOutputStream
-// @see EncryptedInputStream
-
-public class DesCipher
-    {
-
-    // Constructor, byte-array key.
-    public DesCipher( byte[] key )
-       {
-       setKey( key );
-       }
-
-    // Key routines.
-
-    private int[] encryptKeys = new int[32];
-    private int[] decryptKeys = new int[32];
-
-    /// Set the key.
-    public void setKey( byte[] key )
-       {
-       deskey( key, true, encryptKeys );
-       deskey( key, false, decryptKeys );
-       }
-
-    // Turn an 8-byte key into internal keys.
-    private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL )
-       {
-       int i, j, l, m, n;
-       int[] pc1m = new int[56];
-       int[] pcr = new int[56];
-       int[] kn = new int[32];
-
-       for ( j = 0; j < 56; ++j )
-           {
-           l = pc1[j];
-           m = l & 07;
-           pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
-           }
-
-       for ( i = 0; i < 16; ++i )
-           {
-           if ( encrypting )
-               m = i << 1;
-           else
-               m = (15-i) << 1;
-           n = m+1;
-           kn[m] = kn[n] = 0;
-           for ( j = 0; j < 28; ++j )
-               {
-               l = j+totrot[i];
-               if ( l < 28 )
-                   pcr[j] = pc1m[l];
-               else
-                   pcr[j] = pc1m[l-28];
-               }
-           for ( j=28; j < 56; ++j )
-               {
-               l = j+totrot[i];
-               if ( l < 56 )
-                   pcr[j] = pc1m[l];
-               else
-                   pcr[j] = pc1m[l-28];
-               }
-           for ( j = 0; j < 24; ++j )
-               {
-               if ( pcr[pc2[j]] != 0 )
-                   kn[m] |= bigbyte[j];
-               if ( pcr[pc2[j+24]] != 0 )
-                   kn[n] |= bigbyte[j];
-               }
-           }
-       cookey( kn, KnL );
-       }
-
-    private void cookey( int[] raw, int KnL[] )
-       {
-       int raw0, raw1;
-       int rawi, KnLi;
-       int i;
-
-       for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i )
-           {
-           raw0 = raw[rawi++];
-           raw1 = raw[rawi++];
-           KnL[KnLi]  = (raw0 & 0x00fc0000) <<   6;
-           KnL[KnLi] |= (raw0 & 0x00000fc0) <<  10;
-           KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
-           KnL[KnLi] |= (raw1 & 0x00000fc0) >>>  6;
-           ++KnLi;
-           KnL[KnLi]  = (raw0 & 0x0003f000) <<  12;
-           KnL[KnLi] |= (raw0 & 0x0000003f) <<  16;
-           KnL[KnLi] |= (raw1 & 0x0003f000) >>>  4;
-           KnL[KnLi] |= (raw1 & 0x0000003f);
-           ++KnLi;
-           }
-       }
-
-
-    // Block encryption routines.
-
-    private int[] tempInts = new int[2];
-
-    /// Encrypt a block of eight bytes.
-    public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff )
-       {
-       squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
-       des( tempInts, tempInts, encryptKeys );
-       spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
-       }
-
-    /// Decrypt a block of eight bytes.
-    public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff )
-       {
-       squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
-       des( tempInts, tempInts, decryptKeys );
-       spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
-       }
-
-    // The DES function.
-    private void des( int[] inInts, int[] outInts, int[] keys )
-       {
-       int fval, work, right, leftt;
-       int round;
-       int keysi = 0;
-
-       leftt = inInts[0];
-       right = inInts[1];
-
-       work   = ((leftt >>>  4) ^ right) & 0x0f0f0f0f;
-       right ^= work;
-       leftt ^= (work << 4);
-
-       work   = ((leftt >>> 16) ^ right) & 0x0000ffff;
-       right ^= work;
-       leftt ^= (work << 16);
-
-       work   = ((right >>>  2) ^ leftt) & 0x33333333;
-       leftt ^= work;
-       right ^= (work << 2);
-
-       work   = ((right >>>  8) ^ leftt) & 0x00ff00ff;
-       leftt ^= work;
-       right ^= (work << 8);
-       right  = (right << 1) | ((right >>> 31) & 1);
-
-       work   = (leftt ^ right) & 0xaaaaaaaa;
-       leftt ^= work;
-       right ^= work;
-       leftt  = (leftt << 1) | ((leftt >>> 31) & 1);
-
-       for ( round = 0; round < 8; ++round )
-           {
-           work   = (right << 28) | (right >>> 4);
-           work  ^= keys[keysi++];
-           fval   = SP7[ work         & 0x0000003f ];
-           fval  |= SP5[(work >>>  8) & 0x0000003f ];
-           fval  |= SP3[(work >>> 16) & 0x0000003f ];
-           fval  |= SP1[(work >>> 24) & 0x0000003f ];
-           work   = right ^ keys[keysi++];
-           fval  |= SP8[ work         & 0x0000003f ];
-           fval  |= SP6[(work >>>  8) & 0x0000003f ];
-           fval  |= SP4[(work >>> 16) & 0x0000003f ];
-           fval  |= SP2[(work >>> 24) & 0x0000003f ];
-           leftt ^= fval;
-           work   = (leftt << 28) | (leftt >>> 4);
-           work  ^= keys[keysi++];
-           fval   = SP7[ work         & 0x0000003f ];
-           fval  |= SP5[(work >>>  8) & 0x0000003f ];
-           fval  |= SP3[(work >>> 16) & 0x0000003f ];
-           fval  |= SP1[(work >>> 24) & 0x0000003f ];
-           work   = leftt ^ keys[keysi++];
-           fval  |= SP8[ work         & 0x0000003f ];
-           fval  |= SP6[(work >>>  8) & 0x0000003f ];
-           fval  |= SP4[(work >>> 16) & 0x0000003f ];
-           fval  |= SP2[(work >>> 24) & 0x0000003f ];
-           right ^= fval;
-           }
-
-       right  = (right << 31) | (right >>> 1);
-       work   = (leftt ^ right) & 0xaaaaaaaa;
-       leftt ^= work;
-       right ^= work;
-       leftt  = (leftt << 31) | (leftt >>> 1);
-       work   = ((leftt >>>  8) ^ right) & 0x00ff00ff;
-       right ^= work;
-       leftt ^= (work << 8);
-       work   = ((leftt >>>  2) ^ right) & 0x33333333;
-       right ^= work;
-       leftt ^= (work << 2);
-       work   = ((right >>> 16) ^ leftt) & 0x0000ffff;
-       leftt ^= work;
-       right ^= (work << 16);
-       work   = ((right >>>  4) ^ leftt) & 0x0f0f0f0f;
-       leftt ^= work;
-       right ^= (work << 4);
-       outInts[0] = right;
-       outInts[1] = leftt;
-       }
-
-
-    // Tables, permutations, S-boxes, etc.
-
-    private static byte[] bytebit = {
-       (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08,
-       (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80
-       };
-    private static int[] bigbyte = {
-       0x800000, 0x400000, 0x200000, 0x100000,
-       0x080000, 0x040000, 0x020000, 0x010000,
-       0x008000, 0x004000, 0x002000, 0x001000,
-       0x000800, 0x000400, 0x000200, 0x000100,
-       0x000080, 0x000040, 0x000020, 0x000010,
-       0x000008, 0x000004, 0x000002, 0x000001
-       };
-    private static byte[] pc1 = {
-         (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
-      (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
-        (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
-      (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
-        (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
-      (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
-        (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
-      (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
-       };
-    private static int[] totrot = {
-        1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
-       };
-
-    private static byte[] pc2 = {
-       (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
-                 (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
-       (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
-                 (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
-       (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
-                 (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
-       (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
-                 (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
-       };
-
-    private static int[] SP1 = {
-        0x01010400, 0x00000000, 0x00010000, 0x01010404,
-       0x01010004, 0x00010404, 0x00000004, 0x00010000,
-       0x00000400, 0x01010400, 0x01010404, 0x00000400,
-       0x01000404, 0x01010004, 0x01000000, 0x00000004,
-       0x00000404, 0x01000400, 0x01000400, 0x00010400,
-       0x00010400, 0x01010000, 0x01010000, 0x01000404,
-       0x00010004, 0x01000004, 0x01000004, 0x00010004,
-       0x00000000, 0x00000404, 0x00010404, 0x01000000,
-       0x00010000, 0x01010404, 0x00000004, 0x01010000,
-       0x01010400, 0x01000000, 0x01000000, 0x00000400,
-       0x01010004, 0x00010000, 0x00010400, 0x01000004,
-       0x00000400, 0x00000004, 0x01000404, 0x00010404,
-       0x01010404, 0x00010004, 0x01010000, 0x01000404,
-       0x01000004, 0x00000404, 0x00010404, 0x01010400,
-       0x00000404, 0x01000400, 0x01000400, 0x00000000,
-       0x00010004, 0x00010400, 0x00000000, 0x01010004
-       };
-    private static int[] SP2 = {
-       0x80108020, 0x80008000, 0x00008000, 0x00108020,
-       0x00100000, 0x00000020, 0x80100020, 0x80008020,
-       0x80000020, 0x80108020, 0x80108000, 0x80000000,
-       0x80008000, 0x00100000, 0x00000020, 0x80100020,
-       0x00108000, 0x00100020, 0x80008020, 0x00000000,
-       0x80000000, 0x00008000, 0x00108020, 0x80100000,
-       0x00100020, 0x80000020, 0x00000000, 0x00108000,
-       0x00008020, 0x80108000, 0x80100000, 0x00008020,
-       0x00000000, 0x00108020, 0x80100020, 0x00100000,
-       0x80008020, 0x80100000, 0x80108000, 0x00008000,
-       0x80100000, 0x80008000, 0x00000020, 0x80108020,
-       0x00108020, 0x00000020, 0x00008000, 0x80000000,
-       0x00008020, 0x80108000, 0x00100000, 0x80000020,
-       0x00100020, 0x80008020, 0x80000020, 0x00100020,
-       0x00108000, 0x00000000, 0x80008000, 0x00008020,
-       0x80000000, 0x80100020, 0x80108020, 0x00108000
-       };
-    private static int[] SP3 = {
-       0x00000208, 0x08020200, 0x00000000, 0x08020008,
-       0x08000200, 0x00000000, 0x00020208, 0x08000200,
-       0x00020008, 0x08000008, 0x08000008, 0x00020000,
-       0x08020208, 0x00020008, 0x08020000, 0x00000208,
-       0x08000000, 0x00000008, 0x08020200, 0x00000200,
-       0x00020200, 0x08020000, 0x08020008, 0x00020208,
-       0x08000208, 0x00020200, 0x00020000, 0x08000208,
-       0x00000008, 0x08020208, 0x00000200, 0x08000000,
-       0x08020200, 0x08000000, 0x00020008, 0x00000208,
-       0x00020000, 0x08020200, 0x08000200, 0x00000000,
-       0x00000200, 0x00020008, 0x08020208, 0x08000200,
-       0x08000008, 0x00000200, 0x00000000, 0x08020008,
-       0x08000208, 0x00020000, 0x08000000, 0x08020208,
-       0x00000008, 0x00020208, 0x00020200, 0x08000008,
-       0x08020000, 0x08000208, 0x00000208, 0x08020000,
-       0x00020208, 0x00000008, 0x08020008, 0x00020200
-       };
-    private static int[] SP4 = {
-       0x00802001, 0x00002081, 0x00002081, 0x00000080,
-       0x00802080, 0x00800081, 0x00800001, 0x00002001,
-       0x00000000, 0x00802000, 0x00802000, 0x00802081,
-       0x00000081, 0x00000000, 0x00800080, 0x00800001,
-       0x00000001, 0x00002000, 0x00800000, 0x00802001,
-       0x00000080, 0x00800000, 0x00002001, 0x00002080,
-       0x00800081, 0x00000001, 0x00002080, 0x00800080,
-       0x00002000, 0x00802080, 0x00802081, 0x00000081,
-       0x00800080, 0x00800001, 0x00802000, 0x00802081,
-       0x00000081, 0x00000000, 0x00000000, 0x00802000,
-       0x00002080, 0x00800080, 0x00800081, 0x00000001,
-       0x00802001, 0x00002081, 0x00002081, 0x00000080,
-       0x00802081, 0x00000081, 0x00000001, 0x00002000,
-       0x00800001, 0x00002001, 0x00802080, 0x00800081,
-       0x00002001, 0x00002080, 0x00800000, 0x00802001,
-       0x00000080, 0x00800000, 0x00002000, 0x00802080
-       };
-    private static int[] SP5 = {
-       0x00000100, 0x02080100, 0x02080000, 0x42000100,
-       0x00080000, 0x00000100, 0x40000000, 0x02080000,
-       0x40080100, 0x00080000, 0x02000100, 0x40080100,
-       0x42000100, 0x42080000, 0x00080100, 0x40000000,
-       0x02000000, 0x40080000, 0x40080000, 0x00000000,
-       0x40000100, 0x42080100, 0x42080100, 0x02000100,
-       0x42080000, 0x40000100, 0x00000000, 0x42000000,
-       0x02080100, 0x02000000, 0x42000000, 0x00080100,
-       0x00080000, 0x42000100, 0x00000100, 0x02000000,
-       0x40000000, 0x02080000, 0x42000100, 0x40080100,
-       0x02000100, 0x40000000, 0x42080000, 0x02080100,
-       0x40080100, 0x00000100, 0x02000000, 0x42080000,
-       0x42080100, 0x00080100, 0x42000000, 0x42080100,
-       0x02080000, 0x00000000, 0x40080000, 0x42000000,
-       0x00080100, 0x02000100, 0x40000100, 0x00080000,
-       0x00000000, 0x40080000, 0x02080100, 0x40000100
-       };
-    private static int[] SP6 = {
-       0x20000010, 0x20400000, 0x00004000, 0x20404010,
-       0x20400000, 0x00000010, 0x20404010, 0x00400000,
-       0x20004000, 0x00404010, 0x00400000, 0x20000010,
-       0x00400010, 0x20004000, 0x20000000, 0x00004010,
-       0x00000000, 0x00400010, 0x20004010, 0x00004000,
-       0x00404000, 0x20004010, 0x00000010, 0x20400010,
-       0x20400010, 0x00000000, 0x00404010, 0x20404000,
-       0x00004010, 0x00404000, 0x20404000, 0x20000000,
-       0x20004000, 0x00000010, 0x20400010, 0x00404000,
-       0x20404010, 0x00400000, 0x00004010, 0x20000010,
-       0x00400000, 0x20004000, 0x20000000, 0x00004010,
-       0x20000010, 0x20404010, 0x00404000, 0x20400000,
-       0x00404010, 0x20404000, 0x00000000, 0x20400010,
-       0x00000010, 0x00004000, 0x20400000, 0x00404010,
-       0x00004000, 0x00400010, 0x20004010, 0x00000000,
-       0x20404000, 0x20000000, 0x00400010, 0x20004010
-       };
-    private static int[] SP7 = {
-       0x00200000, 0x04200002, 0x04000802, 0x00000000,
-       0x00000800, 0x04000802, 0x00200802, 0x04200800,
-       0x04200802, 0x00200000, 0x00000000, 0x04000002,
-       0x00000002, 0x04000000, 0x04200002, 0x00000802,
-       0x04000800, 0x00200802, 0x00200002, 0x04000800,
-       0x04000002, 0x04200000, 0x04200800, 0x00200002,
-       0x04200000, 0x00000800, 0x00000802, 0x04200802,
-       0x00200800, 0x00000002, 0x04000000, 0x00200800,
-       0x04000000, 0x00200800, 0x00200000, 0x04000802,
-       0x04000802, 0x04200002, 0x04200002, 0x00000002,
-       0x00200002, 0x04000000, 0x04000800, 0x00200000,
-       0x04200800, 0x00000802, 0x00200802, 0x04200800,
-       0x00000802, 0x04000002, 0x04200802, 0x04200000,
-       0x00200800, 0x00000000, 0x00000002, 0x04200802,
-       0x00000000, 0x00200802, 0x04200000, 0x00000800,
-       0x04000002, 0x04000800, 0x00000800, 0x00200002
-       };
-    private static int[] SP8 = {
-       0x10001040, 0x00001000, 0x00040000, 0x10041040,
-       0x10000000, 0x10001040, 0x00000040, 0x10000000,
-       0x00040040, 0x10040000, 0x10041040, 0x00041000,
-       0x10041000, 0x00041040, 0x00001000, 0x00000040,
-       0x10040000, 0x10000040, 0x10001000, 0x00001040,
-       0x00041000, 0x00040040, 0x10040040, 0x10041000,
-       0x00001040, 0x00000000, 0x00000000, 0x10040040,
-       0x10000040, 0x10001000, 0x00041040, 0x00040000,
-       0x00041040, 0x00040000, 0x10041000, 0x00001000,
-       0x00000040, 0x10040040, 0x00001000, 0x00041040,
-       0x10001000, 0x00000040, 0x10000040, 0x10040000,
-       0x10040040, 0x10000000, 0x00040000, 0x10001040,
-       0x00000000, 0x10041040, 0x00040040, 0x10000040,
-       0x10040000, 0x10001000, 0x10001040, 0x00000000,
-       0x10041040, 0x00041000, 0x00041000, 0x00001040,
-       0x00001040, 0x00040040, 0x10000000, 0x10041000
-       };
-
-    // Routines taken from other parts of the Acme utilities.
-
-    /// Squash bytes down to ints.
-    public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen )
-        {
-       for ( int i = 0; i < intLen; ++i )
-           outInts[outOff + i] = 
-               ( ( inBytes[inOff + i * 4    ] & 0xff ) << 24 ) |
-               ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
-               ( ( inBytes[inOff + i * 4 + 2] & 0xff ) <<  8 ) |
-                 ( inBytes[inOff + i * 4 + 3] & 0xff );
-        }
-
-    /// Spread ints into bytes.
-    public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen )
-        {
-       for ( int i = 0; i < intLen; ++i )
-           {
-           outBytes[outOff + i * 4    ] = (byte) ( inInts[inOff + i] >>> 24 );
-           outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
-           outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>>  8 );
-           outBytes[outOff + i * 4 + 3] = (byte)   inInts[inOff + i];
-           }
-        }
-    }
diff --git a/java/src/com/tightvnc/rfbplayer/FbsInputStream.java b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
new file mode 100644 (file)
index 0000000..fab854b
--- /dev/null
@@ -0,0 +1,174 @@
+//
+//  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.
+//
+
+//
+// FbsInputStream.java
+//
+
+import java.io.*;
+
+class FbsInputStream extends InputStream {
+
+  protected InputStream in;
+  protected long startTime;
+  protected long timeOffset;
+
+  protected byte[] buffer;
+  protected int bufferSize;
+  protected int bufferPos;
+
+  //
+  // Constructors.
+  //
+
+  FbsInputStream() throws IOException {
+    throw new IOException("FbsInputStream: no such constructor");
+  }
+
+  FbsInputStream(InputStream in) throws IOException
+  {
+    this.in = in;
+    startTime = System.currentTimeMillis();
+    timeOffset = 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 protocol version");
+    }
+
+    buffer = null;
+    bufferSize = 0;
+    bufferPos = 0;
+  }
+
+  //
+  // 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 void close() throws IOException
+  {
+    in.close();
+    in = null;
+    startTime = 0;
+    timeOffset = 0;
+
+    buffer = null;
+    bufferSize = 0;
+    bufferPos = 0;
+  }
+
+  //
+  // Methods providing additional functionality.
+  //
+
+  public void resumeReading()
+  {
+    startTime = System.currentTimeMillis() - timeOffset;
+  }
+
+  //
+  // Methods for internal use.
+  //
+
+  private boolean fillBuffer() throws IOException
+  {
+    bufferSize = (int)readUnsigned32();
+    if (bufferSize >= 0) {
+      int realSize = (bufferSize + 3) & 0xFFFFFFFC;
+      buffer = new byte[realSize];
+      readFully(buffer);
+      bufferPos = 0;
+
+      timeOffset = readUnsigned32();
+    }
+
+    if (bufferSize < 0 || timeOffset < 0) {
+      buffer = null;
+      bufferSize = 0;
+      bufferPos = 0;
+      return false;
+    }
+
+    while (true) {
+      long timeDiff = startTime + timeOffset - System.currentTimeMillis();
+      if (timeDiff <= 0) {
+       break;
+      }
+      try {
+       Thread.currentThread().sleep(timeDiff);
+      } catch (InterruptedException e) {
+      }
+    }
+
+    return true;
+  }
+
+  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;
+  }
+}
+
index 76dbca430470d2d6123204b17ee1efd4bd62503f..42d10474bb2213a33a615251c1cc9e68920cc0ff 100644 (file)
@@ -3,24 +3,23 @@
 #
 
 CP = cp
+RM = rm
 JC = javac
 JAR = jar
-ARCHIVE = VncViewer.jar
-PAGES = index.vnc shared.vnc noshared.vnc hextile.vnc zlib.vnc tight.vnc
-INSTALL_DIR = /usr/local/vnc/classes
+ARCHIVE = RfbPlayer.jar
+PAGES = index.html
+INSTALL_DIR = ./classes
 
-CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \
-         OptionsFrame.class ClipboardFrame.class ButtonPanel.class \
-         DesCipher.class
+CLASSES = RfbPlayer.class RfbProto.class ButtonPanel.class VncCanvas.class \
+         FbsInputStream.class
 
-SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \
-         OptionsFrame.java ClipboardFrame.java ButtonPanel.java \
-         DesCipher.java
+SOURCES = RfbPlayer.java RfbProto.java ButtonPanel.java VncCanvas.java \
+         FbsInputStream.java
 
 all: $(CLASSES) $(ARCHIVE)
 
 $(CLASSES): $(SOURCES)
-       $(JC) -O $(SOURCES)
+       $(JC) -g $(SOURCES)
 
 $(ARCHIVE): $(CLASSES)
        $(JAR) cf $(ARCHIVE) $(CLASSES)
@@ -28,8 +27,5 @@ $(ARCHIVE): $(CLASSES)
 install: $(CLASSES) $(ARCHIVE)
        $(CP) $(CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR)
 
-export:: $(CLASSES) $(ARCHIVE) $(PAGES)
-       @$(ExportJavaClasses)
-
 clean::
        $(RM) *.class *.jar
diff --git a/java/src/com/tightvnc/rfbplayer/OptionsFrame.java b/java/src/com/tightvnc/rfbplayer/OptionsFrame.java
deleted file mode 100644 (file)
index 45e5ab6..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-//
-//  Copyright (C) 2001 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.
-//
-
-//
-// Options frame.
-//
-// This deals with all the options the user can play with.
-// It sets the encodings array and some booleans.
-//
-
-import java.awt.*;
-import java.awt.event.*;
-
-class OptionsFrame extends Frame
-  implements WindowListener, ActionListener, ItemListener {
-
-  static String[] names = {
-    "Encoding",
-    "Compression level",
-    "JPEG image quality",
-    "Cursor shape updates",
-    "Use CopyRect",
-    "Restricted colors",
-    "Mouse buttons 2 and 3",
-    "View only",
-    "Share desktop",
-  };
-
-  static String[][] values = {
-    { "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight" },
-    { "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
-    { "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
-    { "Enable", "Ignore", "Disable" },
-    { "Yes", "No" },
-    { "Yes", "No" },
-    { "Normal", "Reversed" },
-    { "Yes", "No" },
-    { "Yes", "No" },
-  };
-
-  final int
-    encodingIndex        = 0,
-    compressLevelIndex   = 1,
-    jpegQualityIndex     = 2,
-    cursorUpdatesIndex   = 3,
-    useCopyRectIndex     = 4,
-    eightBitColorsIndex  = 5,
-    mouseButtonIndex     = 6,
-    viewOnlyIndex        = 7,
-    shareDesktopIndex    = 8;
-
-  Label[] labels = new Label[names.length];
-  Choice[] choices = new Choice[names.length];
-  Button closeButton;
-  VncViewer viewer;
-
-
-  //
-  // The actual data which other classes look at:
-  //
-
-  int[] encodings = new int[20];
-  int nEncodings;
-
-  int compressLevel;
-  int jpegQuality;
-
-  boolean eightBitColors;
-
-  boolean requestCursorUpdates;
-  boolean ignoreCursorUpdates;
-
-  boolean reverseMouseButtons2And3;
-  boolean shareDesktop;
-  boolean viewOnly;
-  boolean showControls;
-
-  //
-  // Constructor.  Set up the labels and choices from the names and values
-  // arrays.
-  //
-
-  OptionsFrame(VncViewer v) {
-    super("TightVNC Options");
-
-    viewer = v;
-
-    GridBagLayout gridbag = new GridBagLayout();
-    setLayout(gridbag);
-
-    GridBagConstraints gbc = new GridBagConstraints();
-    gbc.fill = GridBagConstraints.BOTH;
-
-    for (int i = 0; i < names.length; i++) {
-      labels[i] = new Label(names[i]);
-      gbc.gridwidth = 1;
-      gridbag.setConstraints(labels[i],gbc);
-      add(labels[i]);
-
-      choices[i] = new Choice();
-      gbc.gridwidth = GridBagConstraints.REMAINDER;
-      gridbag.setConstraints(choices[i],gbc);
-      add(choices[i]);
-      choices[i].addItemListener(this);
-
-      for (int j = 0; j < values[i].length; j++) {
-       choices[i].addItem(values[i][j]);
-      }
-    }
-
-    closeButton = new Button("Close");
-    gbc.gridwidth = GridBagConstraints.REMAINDER;
-    gridbag.setConstraints(closeButton, gbc);
-    add(closeButton);
-    closeButton.addActionListener(this);
-
-    pack();
-
-    addWindowListener(this);
-
-    // Set up defaults
-
-    choices[encodingIndex].select("Tight");
-    choices[compressLevelIndex].select("Default");
-    choices[jpegQualityIndex].select("6");
-    choices[cursorUpdatesIndex].select("Enable");
-    choices[useCopyRectIndex].select("Yes");
-    choices[eightBitColorsIndex].select("No");
-    choices[mouseButtonIndex].select("Normal");
-    choices[viewOnlyIndex].select("No");
-    choices[shareDesktopIndex].select("Yes");
-
-    // But let them be overridden by parameters
-
-    for (int i = 0; i < names.length; i++) {
-      String s = viewer.readParameter(names[i], false);
-      if (s != null) {
-       for (int j = 0; j < values[i].length; j++) {
-         if (s.equalsIgnoreCase(values[i][j])) {
-           choices[i].select(j);
-         }
-       }
-      }
-    }
-
-    // "Show Controls" setting does not have associated GUI option
-
-    showControls = true;
-    String s = viewer.readParameter("Show Controls", false);
-    if (s != null && s.equalsIgnoreCase("No"))
-      showControls = false;
-
-    // Make the booleans and encodings array correspond to the state of the GUI
-
-    setEncodings();
-    setColorFormat();
-    setOtherOptions();
-  }
-
-
-  //
-  // Disable the shareDesktop option
-  //
-
-  void disableShareDesktop() {
-    labels[shareDesktopIndex].setEnabled(false);
-    choices[shareDesktopIndex].setEnabled(false);
-  }
-
-
-  //
-  // setEncodings looks at the encoding, compression level, JPEG
-  // quality level, cursor shape updates and copyRect choices and sets
-  // the encodings array appropriately. It also calls the VncViewer's
-  // setEncodings method to send a message to the RFB server if
-  // necessary.
-  //
-
-  void setEncodings() {
-    nEncodings = 0;
-    if (choices[useCopyRectIndex].getSelectedItem().equals("Yes")) {
-      encodings[nEncodings++] = RfbProto.EncodingCopyRect;
-    }
-
-    int preferredEncoding = RfbProto.EncodingRaw;
-    boolean enableCompressLevel = false;
-
-    if (choices[encodingIndex].getSelectedItem().equals("RRE")) {
-      preferredEncoding = RfbProto.EncodingRRE;
-    } else if (choices[encodingIndex].getSelectedItem().equals("CoRRE")) {
-      preferredEncoding = RfbProto.EncodingCoRRE;
-    } else if (choices[encodingIndex].getSelectedItem().equals("Hextile")) {
-      preferredEncoding = RfbProto.EncodingHextile;
-    } else if (choices[encodingIndex].getSelectedItem().equals("Zlib")) {
-      preferredEncoding = RfbProto.EncodingZlib;
-      enableCompressLevel = true;
-    } else if (choices[encodingIndex].getSelectedItem().equals("Tight")) {
-      preferredEncoding = RfbProto.EncodingTight;
-      enableCompressLevel = true;
-    }
-
-    encodings[nEncodings++] = preferredEncoding;
-    if (preferredEncoding != RfbProto.EncodingHextile) {
-      encodings[nEncodings++] = RfbProto.EncodingHextile;
-    }
-    if (preferredEncoding != RfbProto.EncodingTight) {
-      encodings[nEncodings++] = RfbProto.EncodingTight;
-    }
-    if (preferredEncoding != RfbProto.EncodingZlib) {
-      encodings[nEncodings++] = RfbProto.EncodingZlib;
-    }
-    if (preferredEncoding != RfbProto.EncodingCoRRE) {
-      encodings[nEncodings++] = RfbProto.EncodingCoRRE;
-    }
-    if (preferredEncoding != RfbProto.EncodingRRE) {
-      encodings[nEncodings++] = RfbProto.EncodingRRE;
-    }
-
-    // Handle compression level setting.
-
-    if (enableCompressLevel) {
-      labels[compressLevelIndex].setEnabled(true);
-      choices[compressLevelIndex].setEnabled(true);
-      try {
-       compressLevel =
-         Integer.parseInt(choices[compressLevelIndex].getSelectedItem());
-      }
-      catch (NumberFormatException e) {
-       compressLevel = -1;
-      }
-      if (compressLevel >= 1 && compressLevel <= 9) {
-       encodings[nEncodings++] =
-         RfbProto.EncodingCompressLevel0 + compressLevel;
-      } else {
-       compressLevel = -1;
-      }
-    } else {
-      labels[compressLevelIndex].setEnabled(false);
-      choices[compressLevelIndex].setEnabled(false);
-    }
-
-    // Handle JPEG quality setting.
-
-    if (preferredEncoding == RfbProto.EncodingTight) {
-      labels[jpegQualityIndex].setEnabled(true);
-      choices[jpegQualityIndex].setEnabled(true);
-      try {
-       jpegQuality =
-         Integer.parseInt(choices[jpegQualityIndex].getSelectedItem());
-      }
-      catch (NumberFormatException e) {
-       jpegQuality = -1;
-      }
-      if (jpegQuality >= 0 && jpegQuality <= 9) {
-       encodings[nEncodings++] =
-         RfbProto.EncodingQualityLevel0 + jpegQuality;
-      } else {
-       jpegQuality = -1;
-      }
-    } else {
-      labels[jpegQualityIndex].setEnabled(false);
-      choices[jpegQualityIndex].setEnabled(false);
-    }
-
-    // Request cursor shape updates if necessary.
-
-    requestCursorUpdates =
-      !choices[cursorUpdatesIndex].getSelectedItem().equals("Disable");
-
-    if (requestCursorUpdates) {
-      encodings[nEncodings++] = RfbProto.EncodingXCursor;
-      encodings[nEncodings++] = RfbProto.EncodingRichCursor;
-      ignoreCursorUpdates =
-       choices[cursorUpdatesIndex].getSelectedItem().equals("Ignore");
-    }
-
-    encodings[nEncodings++] = RfbProto.EncodingLastRect;
-    encodings[nEncodings++] = RfbProto.EncodingNewFBSize;
-
-    viewer.setEncodings();
-  }
-
-  //
-  // setColorFormat sets eightBitColors variable depending on the GUI
-  // setting, and switches between 8-bit and 24-bit colors mode, if
-  // necessary.
-  //
-
-  void setColorFormat() {
-
-    eightBitColors
-      = choices[eightBitColorsIndex].getSelectedItem().equals("Yes");
-
-    // FIXME: implement dynamic changing of the color mode.
-
-  }
-
-  //
-  // setOtherOptions looks at the "other" choices (ones which don't set the
-  // encoding or the color format) and sets the boolean flags appropriately.
-  //
-
-  void setOtherOptions() {
-
-    reverseMouseButtons2And3
-      = choices[mouseButtonIndex].getSelectedItem().equals("Reversed");
-
-    viewOnly 
-      = choices[viewOnlyIndex].getSelectedItem().equals("Yes");
-    if (viewer.vc != null)
-      viewer.vc.enableInput(!viewOnly);
-
-    shareDesktop
-      = choices[shareDesktopIndex].getSelectedItem().equals("Yes");
-  }
-
-
-  //
-  // Respond to actions on Choice controls
-  //
-
-  public void itemStateChanged(ItemEvent evt) {
-    Object source = evt.getSource();
-
-    if (source == choices[encodingIndex] ||
-        source == choices[compressLevelIndex] ||
-        source == choices[jpegQualityIndex] ||
-        source == choices[cursorUpdatesIndex] ||
-        source == choices[useCopyRectIndex]) {
-
-      setEncodings();
-
-    } else if (source == choices[eightBitColorsIndex]) {
-
-      setColorFormat();
-
-    } else if (source == choices[mouseButtonIndex] ||
-              source == choices[shareDesktopIndex] ||
-              source == choices[viewOnlyIndex]) {
-
-      setOtherOptions();
-    }
-  }
-
-  //
-  // Respond to button press
-  //
-
-  public void actionPerformed(ActionEvent evt) {
-    if (evt.getSource() == closeButton)
-      setVisible(false);
-  }
-
-  //
-  // Respond to window events
-  //
-
-  public void windowClosing(WindowEvent evt) {
-    setVisible(false);
-  }
-
-  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) {}
-}
index b9f24c0f1f6e62635c1eb3da1dd923235be3e1b2..7d52c58063a39df48e7c55ba604a04e940a5a8fb 100644 (file)
 
-TightVNC 1.2.3 Java Viewer
-==========================
+RFB Session Player 0.1.0
+========================
 
-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.
+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.
 
-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.
-
-
-Compiling from the sources
-==========================
-
-To compile all the .java files to .class files, simply do:
-
-       % make all
-
-This will also generate a JAR (Java archive) file containing all the classes. 
-Copy all the .class files, the .jar file and the .vnc files to an
-installation directory (e.g. /usr/local/vnc/classes):
-
-       % cp *.class *.jar *.vnc /usr/local/vnc/classes
-
-Make sure that the vncserver script is configured to point to the
-installation directory.
-
-
-Configuration
-=============
-
-TightVNC Java viewer supports a number of parameters allowing you to
-customize its behaviour. Most parameter names copy settings available from
-the Options frame in the Java viewer. Both parameter names and their values
-are case-insensitive, with one exception for the "PASSWORD" parameter. Here
-is the full list of parameters supported in TightVNC Java viewer:
-
---> "HOST" (no GUI equivalent)
-
-    Value: host name or IP address of the VNC server.
-    Default: in applet mode, the host from which the applet was loaded.
-
-    This parameter tells the viewer which server to connect to. Normally,
-    it's not needed, because default Java security policy allow connections
-    from applets to the only one host anyway, and that is the host from which
-    the applet was loaded.
-
---> "PORT" (no GUI equivalent)
-
-    Value: TCP port number on the VNC server.
-    Default: none.
-
-    This parameter is required in all cases. Note that this port is not the
-    one used for HTTP connection from the browser, it is the port used for
-    RFB connection. Usually, VNC servers use ports 58xx for HTTP connections,
-    and ports 59xx for RFB connections. Thus, most likely, this parameter
-    should be set to something like 5900, 5901 etc.
-
---> "PASSWORD"
-
-    Value: session password in plan text.
-    Default: none, ask user.
-
-    DO NOT EVER USE THIS PARAMETER, unless you really know what you are
-    doing. It's extremely dangerous from the security point of view. When
-    this parameter is set, the viewer won't ever ask for a password.
-
---> "Encoding"
-
-    Values: "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight".
-    Default: "Tight".
-
-    The preferred encoding. "Hextile" is a good choice for fast networks,
-    while "Tight" is better suited for low-bandwidth connections. From the
-    other side, the "Tight" decoder in TightVNC Java viewer seems to be more
-    efficient than "Hextile" decoder so it's possible that this default
-    setting can be ok for fast networks too.
-
---> "Compression level"
-
-    Values: "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9".
-    Default: "Default". ;-)
-
-    Use specified compression level for "Tight" and "Zlib" encodings. Level 1
-    uses minimum of CPU time on the server but achieves weak compression
-    ratios. Level 9 offers best compression but may be slow in terms of CPU
-    time consumption on the server side. Use high levels with very slow
-    network connections, and low levels when working over higher-speed
-    networks. The "Default" value means that the server's default compression
-    level should be used.
-
---> "JPEG image quality"
-
-    Values: "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9".
-    Default: "6".
-
-    Use the specified image quality level in "Tight" encoding. Quality level
-    0 denotes bad image quality but very impressive compression ratios, while
-    level 9 offers very good image quality at lower compression ratios. If
-    the value is "JPEG off", the server will not use lossy JPEG compression
-    in "Tight" encoding.
-
---> "Cursor shape updates"
-
-    Values: "Enable", "Ignore", "Disable".
-    Default: "Enable".
-
-    Cursor shape updates is a protocol extension used to handle remote cursor
-    movements locally on the client side, saving bandwidth and eliminating
-    delays in mouse pointer movement. Note that current implementation of
-    cursor shape updates does not allow a client to track mouse cursor
-    position at the server side. This means that clients would not see mouse
-    cursor movements if mouse was moved either locally on the server, or by
-    another remote VNC client. Set this parameter to "Disable" if you always
-    want to see real cursor position on the remote side. Setting this option
-    to "Ignore" is similar to "Enable" but the remote cursor will not be
-    visible at all. This can be a reasonable setting if you don't care about
-    cursor shape and don't want to see two mouse cursors, one above another.
-
---> "Use CopyRect"
 
-    Values: "Yes", "No".
-    Default: "Yes".
+Licensing Terms
+===============
 
-    The "CopyRect" encoding saves bandwidth and drawing time when parts of
-    the remote screen are moving around. Most likely, you don't want to
-    change this setting.
+RFB Session Player is
 
---> "Restricted colors"
+  Copyright (C) 2002 HorizonLive.com, Inc.  All Rights Reserved.
 
-    Values: "Yes", "No".
-    Default: "No".
+This software is based on the TightVNC Java viewer which is
 
-    If set to "No", then 24-bit color format is used to represent pixel data. 
-    If set to "Yes", then only 8 bits are used to represent each pixel. 8-bit
-    color format can save bandwidth, but colors may look very inaccurate.
+  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.
 
---> "Mouse buttons 2 and 3"
-
-    Values: "Normal", "Reversed".
-    Default: "Normal".
-
-    If set to "Reversed", then right mouse button (button 2) will act as it
-    was middle mouse button (button 3), and vice versa.
-
---> "View only"
-
-    Values: "Yes", "No".
-    Default: "No".
-
-    If set to "Yes", then all keyboard and mouse events in the desktop window
-    will be silently ignored and will not be passed to the remote side.
-
---> "Share desktop"
-
-    Values: "Yes", "No".
-    Default: "Yes".
-
-    Share the connection with other clients on the same VNC server. The exact
-    behaviour in each case depends on the server configuration.
-
---> "Open new window" (no GUI equivalent, 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" (no GUI equivalent)
-
-    Values: "Yes", "No".
-    Default: "Yes".
-
-    Set to "No" if you want to get rid of that button panel at the top.
-
---> "Defer screen updates" (no GUI equivalent)
-
-    Value: time in milliseconds.
-    Default: "20".
-
-    When updating the desktop contents after receiving an update from server,
-    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.
-
---> "Defer cursor updates" (no GUI equivalent)
-
-    Value: time in milliseconds.
-    Default: "10".
-
-    When updating the desktop after moving the mouse, schedule repaint within
-    the specified number of milliseconds. This setting makes sense only when
-    "Cursor shape updates" parameter is set to "Enable". Small delay helps to
-    coalesce several small updates into one drawing operation, improving CPU
-    usage. Set this parameter to 0 to disable deferred cursor updates.
-
---> "Defer update requests" (no GUI equivalent)
-
-    Value: time in milliseconds.
-    Default: "50".
-
-    After processing an update received from server, wait for the specified
-    number of milliseconds before requesting next screen update. Such delay
-    will end immediately on every mouse or keyboard event if not in the "view
-    only" mode. Small delay helps the server to coalesce several small
-    updates into one framebuffer update, improving both bandwidth and CPU
-    usage. Increasing the parameter value does not affect responsiveness on
-    mouse and keyboard events, but causes delays in updating the screen when
-    there is no mouse and keyboard activity on the client side.
-
-
-ACKNOWLEDGEMENTS
-================
-
-This distribution contains Java DES software by Dave Zimmerman
-<dzimm@widget.com> and Jef Poskanzer <jef@acme.com>.  This is:
-
-    Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
-
-    Permission to use, copy, modify, and distribute this software and its
-    documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee
-    is hereby granted, provided that this copyright notice is kept intact.
-    
-    WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
-    SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
-    NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-    PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE
-    LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
-    MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
-    
-    THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
-    CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
-    PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
-    NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
-    SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
-    SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
-    PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  WIDGET
-    WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF
-    FITNESS FOR HIGH RISK ACTIVITIES.
-
-    Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights
-    reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-
-    THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-    PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-    BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+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.
 
-    Visit the ACME Labs Java page for up-to-date versions of this and other
-    fine Java utilities: http://www.acme.com/java/
index 2524a50bbc20fb73c8ed863b9123cdaf1b8edfec..4a9bc2fe9e53ff35f290cadca9b1d2d040bd5cd7 100644 (file)
 //  USA.
 //
 
-//
-// VncViewer.java - the VNC viewer applet.  This class mainly just sets up the
-// user interface, leaving it to the VncCanvas to do the actual rendering of
-// a VNC desktop.
-//
-
 import java.awt.*;
 import java.awt.event.*;
 import java.io.*;
 
-public class VncViewer extends java.applet.Applet
+public class RfbPlayer extends java.applet.Applet
   implements java.lang.Runnable, WindowListener {
 
   boolean inAnApplet = true;
@@ -40,13 +34,13 @@ public class VncViewer extends java.applet.Applet
   //
 
   public static void main(String[] argv) {
-    VncViewer v = new VncViewer();
-    v.mainArgs = argv;
-    v.inAnApplet = false;
-    v.inSeparateFrame = true;
+    RfbPlayer p = new RfbPlayer();
+    p.mainArgs = argv;
+    p.inAnApplet = false;
+    p.inSeparateFrame = true;
 
-    v.init();
-    v.start();
+    p.init();
+    p.start();
   }
 
   String[] mainArgs;
@@ -54,24 +48,23 @@ public class VncViewer extends java.applet.Applet
   RfbProto rfb;
   Thread rfbThread;
 
+  public static final int MODE_STOPPED  = 0;
+  public static final int MODE_PLAYBACK = 1;
+  public static final int MODE_PAUSED   = 2;
+  protected int mode;
+
+  FbsInputStream fbsStream;
+
   Frame vncFrame;
   Container vncContainer;
   ScrollPane desktopScrollPane;
   GridBagLayout gridbag;
   ButtonPanel buttonPanel;
-  AuthPanel authenticator;
   VncCanvas vc;
-  OptionsFrame options;
-  ClipboardFrame clipboard;
 
-  // Variables read from parameter values.
-  String host;
-  int port;
-  String passwordParam;
+  String sessionFileName;
+  boolean showControls;
   int deferScreenUpdates;
-  int deferCursorUpdates;
-  int deferUpdateRequests;
-
 
   //
   // init()
@@ -82,7 +75,7 @@ public class VncViewer extends java.applet.Applet
     readParameters();
 
     if (inSeparateFrame) {
-      vncFrame = new Frame("TightVNC");
+      vncFrame = new Frame("RFB Session Player");
       if (!inAnApplet) {
        vncFrame.add("Center", this);
       }
@@ -91,10 +84,6 @@ public class VncViewer extends java.applet.Applet
       vncContainer = this;
     }
 
-    options = new OptionsFrame(this);
-    clipboard = new ClipboardFrame(this);
-    authenticator = new AuthPanel();
-
     if (inSeparateFrame)
       vncFrame.addWindowListener(this);
 
@@ -106,7 +95,7 @@ public class VncViewer extends java.applet.Applet
   }
 
   //
-  // run() - executed by the rfbThread to deal with the RFB socket.
+  // run() - executed by the rfbThread to read RFB data.
   //
 
   public void run() {
@@ -118,17 +107,24 @@ public class VncViewer extends java.applet.Applet
     gbc.gridwidth = GridBagConstraints.REMAINDER;
     gbc.anchor = GridBagConstraints.NORTHWEST;
 
-    if (options.showControls) {
+    if (showControls) {
       buttonPanel = new ButtonPanel(this);
       buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
       gridbag.setConstraints(buttonPanel, gbc);
       vncContainer.add(buttonPanel);
     }
 
-    try {
-      connectAndAuthenticate();
+    if (inSeparateFrame) {
+      vncFrame.pack();
+      vncFrame.show();
+    } else {
+      validate();
+    }
 
-      doProtocolInitialisation();
+    try {
+      FileInputStream file = new FileInputStream(sessionFileName);
+      fbsStream = new FbsInputStream(file);
+      rfb = new RfbProto(fbsStream);
 
       vc = new VncCanvas(this);
       gbc.weightx = 1.0;
@@ -164,209 +160,40 @@ public class VncViewer extends java.applet.Applet
 
       }
 
-      if (options.showControls)
-        buttonPanel.enableButtons();
-
-      moveFocusToDesktop();
-      vc.processNormalProtocol();
-
-    } catch (Exception e) {
-      e.printStackTrace();
-      fatalError(e.toString());
-    }
-    
-  }
-
-
-  //
-  // Connect to the RFB server and authenticate the user.
-  //
-
-  void connectAndAuthenticate() throws IOException {
-
-    // The simplest case -- don't ask user a password, get it from the
-    // "PASSWORD" parameter instead. Authentication failures would be
-    // fatal.
-
-    if (passwordParam != null) {
-      if (inSeparateFrame) {
-       vncFrame.pack();
-       vncFrame.show();
-      } else {
-       validate();
-      }
-      if (!tryAuthenticate(passwordParam)) {
-       throw new IOException("VNC authentication failed");
-      }
-      return;
-    }
-
-    // There is no "PASSWORD" parameter -- ask user for a password,
-    // try to authenticate, retry on authentication failures.
-
-    GridBagConstraints gbc = new GridBagConstraints();
-    gbc.gridwidth = GridBagConstraints.REMAINDER;
-    gbc.anchor = GridBagConstraints.NORTHWEST;
-    gbc.weightx = 1.0;
-    gbc.weighty = 1.0;
-    gbc.ipadx = 100;
-    gbc.ipady = 50;
-    gridbag.setConstraints(authenticator, gbc);
-    vncContainer.add(authenticator);
-
-    if (inSeparateFrame) {
-      vncFrame.pack();
-      vncFrame.show();
-    } else {
-      validate();
-      // FIXME: here moveFocusToPasswordField() does not always work
-      // under Netscape 4.7x/Java 1.1.5/Linux. It seems like this call
-      // is being executed before the password field of the
-      // authenticator is fully drawn and activated, therefore
-      // requestFocus() does not work. Currently, I don't know how to
-      // solve this problem.
-      //   -- const
-      authenticator.moveFocusToPasswordField();
-    }
-
-    while (true) {
-      // Wait for user entering a password.
-      synchronized(authenticator) {
+      while (true) {
        try {
-         authenticator.wait();
-       } catch (InterruptedException e) {
+         buttonPanel.setMode(MODE_STOPPED);
+         vc.processNormalProtocol();
+       } catch (EOFException e) {
+         file.close();
+         file = new FileInputStream(sessionFileName);
+         fbsStream = new FbsInputStream(file);
+         rfb.newInputStream(fbsStream);
        }
       }
 
-      // Try to authenticate with a given password.
-      if (tryAuthenticate(authenticator.password.getText()))
-       break;
-
-      // Retry on authentication failure.
-      authenticator.retry();
-    }
-
-    vncContainer.remove(authenticator);
-  }
-
-
-  //
-  // Try to authenticate with a given password.
-  //
-
-  boolean tryAuthenticate(String pw) throws IOException {
-
-    rfb = new RfbProto(host, port, this);
-
-    rfb.readVersionMsg();
-
-    System.out.println("RFB server supports protocol version " +
-                      rfb.serverMajor + "." + rfb.serverMinor);
-
-    rfb.writeVersionMsg();
-
-    int authScheme = rfb.readAuthScheme();
-
-    switch (authScheme) {
-
-    case RfbProto.NoAuth:
-      System.out.println("No authentication needed");
-      return true;
-
-    case RfbProto.VncAuth:
-      byte[] challenge = new byte[16];
-      rfb.is.readFully(challenge);
-
-      if (pw.length() > 8)
-       pw = pw.substring(0, 8); // Truncate to 8 chars
-
-      byte[] key = {0, 0, 0, 0, 0, 0, 0, 0};
-      System.arraycopy(pw.getBytes(), 0, key, 0, pw.length());
-
-      DesCipher des = new DesCipher(key);
-
-      des.encrypt(challenge, 0, challenge, 0);
-      des.encrypt(challenge, 8, challenge, 8);
-
-      rfb.os.write(challenge);
-
-      int authResult = rfb.is.readInt();
-
-      switch (authResult) {
-      case RfbProto.VncAuthOK:
-       System.out.println("VNC authentication succeeded");
-       return true;
-      case RfbProto.VncAuthFailed:
-       System.out.println("VNC authentication failed");
-       break;
-      case RfbProto.VncAuthTooMany:
-       throw new IOException("VNC authentication failed - " +
-                             "too many tries");
-      default:
-       throw new IOException("Unknown VNC authentication result " +
-                             authResult);
-      }
-      break;
-
-    default:
-      throw new IOException("Unknown VNC authentication scheme " +
-                           authScheme);
-    }
-    return false;
-  }
-
-
-  //
-  // Do the rest of the protocol initialisation.
-  //
-
-  void doProtocolInitialisation() throws IOException {
-
-    rfb.writeClientInit();
-
-    rfb.readServerInit();
-
-    System.out.println("Desktop name is " + rfb.desktopName);
-    System.out.println("Desktop size is " + rfb.framebufferWidth + " x " +
-                      rfb.framebufferHeight);
-
-    setEncodings();
-  }
-
-
-  //
-  // Send current encoding list to the RFB server.
-  //
-
-  void setEncodings() {
-    try {
-      if (rfb != null && rfb.inNormalProtocol) {
-       rfb.writeSetEncodings(options.encodings, options.nEncodings);
-       if (vc != null) {
-         vc.softCursorFree();
-       }
-      }
+    } catch (FileNotFoundException e) {
+      fatalError(e.toString());
     } catch (Exception e) {
       e.printStackTrace();
+      fatalError(e.toString());
     }
+    
   }
 
+  public int getMode() {
+    return mode;
+  }
 
-  //
-  // setCutText() - send the given cut text to the RFB server.
-  //
-
-  void setCutText(String text) {
-    try {
-      if ((rfb != null) && rfb.inNormalProtocol) {
-       rfb.writeClientCutText(text);
+  public void setMode(int mode) {
+    this.mode = mode;
+    if (vc != null) {
+      synchronized(vc) {
+       vc.notify();
       }
-    } catch (Exception e) {
-      e.printStackTrace();
     }
   }
 
-
   //
   // readParameters() - read parameters from the html source or from the
   // command line.  On the command line, the arguments are just a sequence of
@@ -375,16 +202,13 @@ public class VncViewer extends java.applet.Applet
   //
 
   public void readParameters() {
-    host = readParameter("HOST", !inAnApplet);
-    if (host == null) {
-      host = getCodeBase().getHost();
-      if (host.equals("")) {
-       fatalError("HOST parameter not specified");
-      }
-    }
 
-    String str = readParameter("PORT", true);
-    port = Integer.parseInt(str);
+    sessionFileName = readParameter("FILE", true);
+
+    showControls = true;
+    String str = readParameter("Show Controls", false);
+    if (str != null && str.equalsIgnoreCase("No"))
+      showControls = false;
 
     if (inAnApplet) {
       str = readParameter("Open New Window", false);
@@ -392,12 +216,8 @@ public class VncViewer extends java.applet.Applet
        inSeparateFrame = true;
     }
 
-    passwordParam = readParameter("PASSWORD", false);
-
     // Fine tuning options.
     deferScreenUpdates = readIntParameter("Defer screen updates", 20);
-    deferCursorUpdates = readIntParameter("Defer cursor updates", 10);
-    deferUpdateRequests = readIntParameter("Defer update requests", 50);
   }
 
   public String readParameter(String name, boolean required) {
@@ -438,51 +258,6 @@ public class VncViewer extends java.applet.Applet
     return result;
   }
 
-  //
-  // moveFocusToDesktop() - move keyboard focus either to the
-  // VncCanvas or to the AuthPanel.
-  //
-
-  void moveFocusToDesktop() {
-    if (vncContainer != null) {
-      if (vc != null && vncContainer.isAncestorOf(vc)) {
-       vc.requestFocus();
-      } else if (vncContainer.isAncestorOf(authenticator)) {
-       authenticator.moveFocusToPasswordField();
-      }
-    }
-  }
-
-  //
-  // disconnect() - close connection to server.
-  //
-
-  public void disconnect() {
-    System.out.println("Disconnect");
-    options.dispose();
-    clipboard.dispose();
-
-    if (inAnApplet) {
-      vncContainer.removeAll();
-      if (rfb != null) {
-       rfb.close();
-       rfb = null;
-      }
-      Label errLabel = new Label("Disconnected");
-      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();
-      }
-      rfbThread.stop();
-    } else {
-      System.exit(0);
-    }
-  }
-
   //
   // fatalError() - print out a fatal error message.
   //
@@ -493,7 +268,6 @@ public class VncViewer extends java.applet.Applet
     if (inAnApplet) {
       vncContainer.removeAll();
       if (rfb != null) {
-       rfb.close();
        rfb = null;
       }
       Label errLabel = new Label(str);
@@ -518,10 +292,8 @@ public class VncViewer extends java.applet.Applet
 
   public void destroy() {
     vncContainer.removeAll();
-    options.dispose();
-    clipboard.dispose();
     if (rfb != null) {
-      rfb.close();
+      rfb = null;
     }
     if (inSeparateFrame) {
       vncFrame.dispose();
@@ -534,8 +306,9 @@ public class VncViewer extends java.applet.Applet
   //
 
   public void windowClosing(WindowEvent evt) {
+    vncContainer.removeAll();
     if (rfb != null)
-      disconnect();
+      rfb = null;
 
     vncFrame.dispose();
     if (!inAnApplet) {
@@ -543,19 +316,11 @@ public class VncViewer extends java.applet.Applet
     }
   }
 
-  //
-  // Move the keyboard focus to the password field on window activation.
-  //
-
-  public void windowActivated(WindowEvent evt) {
-    if (vncFrame.isAncestorOf(authenticator))
-      authenticator.moveFocusToPasswordField();
-  }
-
   //
   // 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) {}
index a86aac536a076a544f70c722915a44cb36e9aa49..daff66c3ab7ed55bcf3b48ea1ab5fc5340507d12 100644 (file)
@@ -73,36 +73,25 @@ class RfbProto {
 
   final static int TightMinToCompress   = 12;
 
-  String host;
-  int port;
-  Socket sock;
   DataInputStream is;
-  OutputStream os;
-  boolean inNormalProtocol = false;
-  VncViewer viewer;
 
 
   //
-  // Constructor.  Just make TCP connection to RFB server.
+  // Constructor.
   //
 
-  RfbProto(String h, int p, VncViewer v) throws IOException {
-    viewer = v;
-    host = h;
-    port = p;
-    sock = new Socket(host, port);
-    is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
-                                                    16384));
-    os = sock.getOutputStream();
+  RfbProto(InputStream is) throws IOException {
+    newInputStream(is);
   }
 
+  public void newInputStream(InputStream is) throws IOException {
+    this.is = new DataInputStream(is);
 
-  void close() {
-    try {
-      sock.close();
-    } catch (Exception e) {
-      e.printStackTrace();
+    readVersionMsg();
+    if (readAuthScheme() != NoAuth) {
+      throw new IOException("Wrong authentication type in the session file");
     }
+    readServerInit();
   }
 
   //
@@ -123,8 +112,7 @@ class RfbProto {
        || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
        || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n'))
     {
-      throw new IOException("Host " + host + " port " + port +
-                           " is not an RFB server");
+      throw new IOException("Incorrect protocol version");
     }
 
     serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
@@ -132,15 +120,6 @@ class RfbProto {
   }
 
 
-  //
-  // Write our protocol version message
-  //
-
-  void writeVersionMsg() throws IOException {
-    os.write(versionMsg.getBytes());
-  }
-
-
   //
   // Find out the authentication scheme.
   //
@@ -161,27 +140,12 @@ class RfbProto {
       return authScheme;
 
     default:
-      throw new IOException("Unknown authentication scheme from RFB " +
-                           "server " + authScheme);
+      throw new IOException("Unknown authentication scheme " + authScheme);
 
     }
   }
 
 
-  //
-  // Write the client initialisation message
-  //
-
-  void writeClientInit() throws IOException {
-    if (viewer.options.shareDesktop) {
-      os.write(1);
-    } else {
-      os.write(0);
-    }
-    viewer.options.disableShareDesktop();
-  }
-
-
   //
   // Read the server initialisation message
   //
@@ -211,8 +175,6 @@ class RfbProto {
     byte[] name = new byte[nameLength];
     is.readFully(name);
     desktopName = new String(name);
-
-    inNormalProtocol = true;
   }
 
 
@@ -311,368 +273,4 @@ class RfbProto {
     return len;
   }
 
-
-  //
-  // Write a FramebufferUpdateRequest message
-  //
-
-  void writeFramebufferUpdateRequest(int x, int y, int w, int h,
-                                    boolean incremental)
-       throws IOException
-  {
-    byte[] b = new byte[10];
-
-    b[0] = (byte) FramebufferUpdateRequest;
-    b[1] = (byte) (incremental ? 1 : 0);
-    b[2] = (byte) ((x >> 8) & 0xff);
-    b[3] = (byte) (x & 0xff);
-    b[4] = (byte) ((y >> 8) & 0xff);
-    b[5] = (byte) (y & 0xff);
-    b[6] = (byte) ((w >> 8) & 0xff);
-    b[7] = (byte) (w & 0xff);
-    b[8] = (byte) ((h >> 8) & 0xff);
-    b[9] = (byte) (h & 0xff);
-
-    os.write(b);
-  }
-
-
-  //
-  // Write a SetPixelFormat message
-  //
-
-  void writeSetPixelFormat(int bitsPerPixel, int depth, boolean bigEndian,
-                          boolean trueColour,
-                          int redMax, int greenMax, int blueMax,
-                          int redShift, int greenShift, int blueShift)
-       throws IOException
-  {
-    byte[] b = new byte[20];
-
-    b[0]  = (byte) SetPixelFormat;
-    b[4]  = (byte) bitsPerPixel;
-    b[5]  = (byte) depth;
-    b[6]  = (byte) (bigEndian ? 1 : 0);
-    b[7]  = (byte) (trueColour ? 1 : 0);
-    b[8]  = (byte) ((redMax >> 8) & 0xff);
-    b[9]  = (byte) (redMax & 0xff);
-    b[10] = (byte) ((greenMax >> 8) & 0xff);
-    b[11] = (byte) (greenMax & 0xff);
-    b[12] = (byte) ((blueMax >> 8) & 0xff);
-    b[13] = (byte) (blueMax & 0xff);
-    b[14] = (byte) redShift;
-    b[15] = (byte) greenShift;
-    b[16] = (byte) blueShift;
-
-    os.write(b);
-  }
-
-
-  //
-  // Write a FixColourMapEntries message.  The values in the red, green and
-  // blue arrays are from 0 to 65535.
-  //
-
-  void writeFixColourMapEntries(int firstColour, int nColours,
-                               int[] red, int[] green, int[] blue)
-       throws IOException
-  {
-    byte[] b = new byte[6 + nColours * 6];
-
-    b[0] = (byte) FixColourMapEntries;
-    b[2] = (byte) ((firstColour >> 8) & 0xff);
-    b[3] = (byte) (firstColour & 0xff);
-    b[4] = (byte) ((nColours >> 8) & 0xff);
-    b[5] = (byte) (nColours & 0xff);
-
-    for (int i = 0; i < nColours; i++) {
-      b[6 + i * 6]     = (byte) ((red[i] >> 8) & 0xff);
-      b[6 + i * 6 + 1] = (byte) (red[i] & 0xff);
-      b[6 + i * 6 + 2] = (byte) ((green[i] >> 8) & 0xff);
-      b[6 + i * 6 + 3] = (byte) (green[i] & 0xff);
-      b[6 + i * 6 + 4] = (byte) ((blue[i] >> 8) & 0xff);
-      b[6 + i * 6 + 5] = (byte) (blue[i] & 0xff);
-    }
-    os.write(b);
-  }
-
-
-  //
-  // Write a SetEncodings message
-  //
-
-  void writeSetEncodings(int[] encs, int len) throws IOException {
-    byte[] b = new byte[4 + 4 * len];
-
-    b[0] = (byte) SetEncodings;
-    b[2] = (byte) ((len >> 8) & 0xff);
-    b[3] = (byte) (len & 0xff);
-
-    for (int i = 0; i < len; i++) {
-      b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff);
-      b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff);
-      b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff);
-      b[7 + 4 * i] = (byte) (encs[i] & 0xff);
-    }
-
-    os.write(b);
-  }
-
-
-  //
-  // Write a ClientCutText message
-  //
-
-  void writeClientCutText(String text) throws IOException {
-    byte[] b = new byte[8 + text.length()];
-
-    b[0] = (byte) ClientCutText;
-    b[4] = (byte) ((text.length() >> 24) & 0xff);
-    b[5] = (byte) ((text.length() >> 16) & 0xff);
-    b[6] = (byte) ((text.length() >> 8) & 0xff);
-    b[7] = (byte) (text.length() & 0xff);
-
-    System.arraycopy(text.getBytes(), 0, b, 8, text.length());
-
-    os.write(b);
-  }
-
-
-  //
-  // A buffer for putting pointer and keyboard events before being sent.  This
-  // is to ensure that multiple RFB events generated from a single Java Event 
-  // will all be sent in a single network packet.  The maximum possible
-  // length is 4 modifier down events, a single key event followed by 4
-  // modifier up events i.e. 9 key events or 72 bytes.
-  //
-
-  byte[] eventBuf = new byte[72];
-  int eventBufLen;
-
-
-  // Useful shortcuts for modifier masks.
-
-  final static int CTRL_MASK  = InputEvent.CTRL_MASK;
-  final static int SHIFT_MASK = InputEvent.SHIFT_MASK;
-  final static int META_MASK  = InputEvent.META_MASK;
-  final static int ALT_MASK   = InputEvent.ALT_MASK;
-
-
-  //
-  // Write a pointer event message.  We may need to send modifier key events
-  // around it to set the correct modifier state.
-  //
-
-  int pointerMask = 0;
-
-  void writePointerEvent(MouseEvent evt) throws IOException {
-    int modifiers = evt.getModifiers();
-
-    int mask2 = 2;
-    int mask3 = 4;
-    if (viewer.options.reverseMouseButtons2And3) {
-      mask2 = 4;
-      mask3 = 2;
-    }
-
-    // Note: For some reason, AWT does not set BUTTON1_MASK on left
-    // button presses. Here we think that it was the left button if
-    // modifiers do not include BUTTON2_MASK or BUTTON3_MASK.
-
-    if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
-      if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {
-        pointerMask = mask2;
-        modifiers &= ~ALT_MASK;
-      } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
-        pointerMask = mask3;
-        modifiers &= ~META_MASK;
-      } else {
-        pointerMask = 1;
-      }
-    } else if (evt.getID() == MouseEvent.MOUSE_RELEASED) {
-      pointerMask = 0;
-      if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {
-        modifiers &= ~ALT_MASK;
-      } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
-        modifiers &= ~META_MASK;
-      }
-    }
-
-    eventBufLen = 0;
-    writeModifierKeyEvents(modifiers);
-
-    int x = evt.getX();
-    int y = evt.getY();
-
-    if (x < 0) x = 0;
-    if (y < 0) y = 0;
-
-    eventBuf[eventBufLen++] = (byte) PointerEvent;
-    eventBuf[eventBufLen++] = (byte) pointerMask;
-    eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff);
-    eventBuf[eventBufLen++] = (byte) (x & 0xff);
-    eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff);
-    eventBuf[eventBufLen++] = (byte) (y & 0xff);
-
-    //
-    // Always release all modifiers after an "up" event
-    //
-
-    if (pointerMask == 0) {
-      writeModifierKeyEvents(0);
-    }
-
-    os.write(eventBuf, 0, eventBufLen);
-  }
-
-
-  //
-  // Write a key event message.  We may need to send modifier key events
-  // around it to set the correct modifier state.  Also we need to translate
-  // from the Java key values to the X keysym values used by the RFB protocol.
-  //
-
-  void writeKeyEvent(KeyEvent evt) throws IOException {
-
-    int keyChar = evt.getKeyChar();
-
-    //
-    // Ignore event if only modifiers were pressed.
-    //
-
-    // Some JVMs return 0 instead of CHAR_UNDEFINED in getKeyChar().
-    if (keyChar == 0)
-      keyChar = KeyEvent.CHAR_UNDEFINED;
-
-    if (keyChar == KeyEvent.CHAR_UNDEFINED) {
-      int code = evt.getKeyCode();
-      if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_SHIFT ||
-          code == KeyEvent.VK_META || code == KeyEvent.VK_ALT)
-        return;
-    }
-
-    //
-    // Key press or key release?
-    //
-
-    boolean down = (evt.getID() == KeyEvent.KEY_PRESSED);
-
-    int key;
-    if (evt.isActionKey()) {
-
-      //
-      // An action key should be one of the following.
-      // If not then just ignore the event.
-      //
-
-      switch(evt.getKeyCode()) {
-      case KeyEvent.VK_HOME:      key = 0xff50; break;
-      case KeyEvent.VK_LEFT:      key = 0xff51; break;
-      case KeyEvent.VK_UP:        key = 0xff52; break;
-      case KeyEvent.VK_RIGHT:     key = 0xff53; break;
-      case KeyEvent.VK_DOWN:      key = 0xff54; break;
-      case KeyEvent.VK_PAGE_UP:   key = 0xff55; break;
-      case KeyEvent.VK_PAGE_DOWN: key = 0xff56; break;
-      case KeyEvent.VK_END:       key = 0xff57; break;
-      case KeyEvent.VK_INSERT:    key = 0xff63; break;
-      case KeyEvent.VK_F1:        key = 0xffbe; break;
-      case KeyEvent.VK_F2:        key = 0xffbf; break;
-      case KeyEvent.VK_F3:        key = 0xffc0; break;
-      case KeyEvent.VK_F4:        key = 0xffc1; break;
-      case KeyEvent.VK_F5:        key = 0xffc2; break;
-      case KeyEvent.VK_F6:        key = 0xffc3; break;
-      case KeyEvent.VK_F7:        key = 0xffc4; break;
-      case KeyEvent.VK_F8:        key = 0xffc5; break;
-      case KeyEvent.VK_F9:        key = 0xffc6; break;
-      case KeyEvent.VK_F10:       key = 0xffc7; break;
-      case KeyEvent.VK_F11:       key = 0xffc8; break;
-      case KeyEvent.VK_F12:       key = 0xffc9; break;
-      default:
-        return;
-      }
-
-    } else {
-
-      //
-      // A "normal" key press.  Ordinary ASCII characters go straight through.
-      // For CTRL-<letter>, CTRL is sent separately so just send <letter>.
-      // Backspace, tab, return, escape and delete have special keysyms.
-      // Anything else we ignore.
-      //
-
-      key = keyChar;
-
-      if (key < 32) {
-        if (evt.isControlDown()) {
-          key += 96;
-        } else {
-          switch(key) {
-          case KeyEvent.VK_BACK_SPACE: key = 0xff08; break;
-          case KeyEvent.VK_TAB:        key = 0xff09; break;
-          case KeyEvent.VK_ENTER:      key = 0xff0d; break;
-          case KeyEvent.VK_ESCAPE:     key = 0xff1b; break;
-          }
-        }
-      } else if (key >= 127) {
-        if (key == 127) {
-          key = 0xffff;
-        } else {
-          // JDK1.1 on X incorrectly passes some keysyms straight through,
-          // so we do too.  JDK1.1.4 seems to have fixed this.
-          if ((key < 0xff00) || (key > 0xffff))
-            return;
-        }
-      }
-    }
-
-    eventBufLen = 0;
-    writeModifierKeyEvents(evt.getModifiers());
-    writeKeyEvent(key, down);
-
-    // Always release all modifiers after an "up" event
-    if (!down)
-      writeModifierKeyEvents(0);
-
-    os.write(eventBuf, 0, eventBufLen);
-  }
-
-
-  //
-  // Add a raw key event with the given X keysym to eventBuf.
-  //
-
-  void writeKeyEvent(int keysym, boolean down) {
-    eventBuf[eventBufLen++] = (byte) KeyboardEvent;
-    eventBuf[eventBufLen++] = (byte) (down ? 1 : 0);
-    eventBuf[eventBufLen++] = (byte) 0;
-    eventBuf[eventBufLen++] = (byte) 0;
-    eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff);
-    eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff);
-    eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff);
-    eventBuf[eventBufLen++] = (byte) (keysym & 0xff);
-  }
-
-
-  //
-  // Write key events to set the correct modifier state.
-  //
-
-  int oldModifiers = 0;
-
-  void writeModifierKeyEvents(int newModifiers) {
-    if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK))
-      writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0);
-
-    if ((newModifiers & SHIFT_MASK) != (oldModifiers & SHIFT_MASK))
-      writeKeyEvent(0xffe1, (newModifiers & SHIFT_MASK) != 0);
-
-    if ((newModifiers & META_MASK) != (oldModifiers & META_MASK))
-      writeKeyEvent(0xffe7, (newModifiers & META_MASK) != 0);
-
-    if ((newModifiers & ALT_MASK) != (oldModifiers & ALT_MASK))
-      writeKeyEvent(0xffe9, (newModifiers & ALT_MASK) != 0);
-
-    oldModifiers = newModifiers;
-  }
 }
index 6d12aa250a7282d1bb9825b3432e5ff81eb27d78..750c847231dc304968d5d444f7e5271cca6d2fce 100644 (file)
@@ -32,21 +32,17 @@ import java.util.zip.*;
 // VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
 //
 
-class VncCanvas extends Canvas
-  implements KeyListener, MouseListener, MouseMotionListener {
+class VncCanvas extends Canvas {
 
-  VncViewer viewer;
+  RfbPlayer player;
   RfbProto rfb;
-  ColorModel cm8, cm24;
-  Color[] colors;
-  int bytesPixel;
+  ColorModel cm24;
 
   Image memImage;
   Graphics memGraphics;
 
   Image rawPixelsImage;
   MemoryImageSource pixelsSource;
-  byte[] pixels8;
   int[] pixels24;
 
   // Zlib encoder's data.
@@ -64,31 +60,17 @@ class VncCanvas extends Canvas
   // which decodes and loads JPEG images.
   Rectangle jpegRect;
 
-  // True if we process keyboard and mouse events.
-  boolean listenersInstalled;
-
   //
   // The constructor.
   //
 
-  VncCanvas(VncViewer v) throws IOException {
-    viewer = v;
-    rfb = viewer.rfb;
-
-    tightInflaters = new Inflater[4];
+  VncCanvas(RfbPlayer player) throws IOException {
+    this.player = player;
+    rfb = player.rfb;
 
-    cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
     cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
 
-    colors = new Color[256];
-    for (int i = 0; i < 256; i++)
-      colors[i] = new Color(cm8.getRGB(i));
-
-    setPixelFormat();
-
-    listenersInstalled = false;
-    if (!viewer.options.viewOnly)
-      enableInput(true);
+    updateFramebufferSize();
   }
 
   //
@@ -119,13 +101,6 @@ class VncCanvas extends Canvas
     synchronized(memImage) {
       g.drawImage(memImage, 0, 0, null);
     }
-    if (showSoftCursor) {
-      int x0 = cursorX - hotX, y0 = cursorY - hotY;
-      Rectangle r = new Rectangle(x0, y0, cursorWidth, cursorHeight);
-      if (r.intersects(g.getClipBounds())) {
-       g.drawImage(softCursor, x0, y0, null);
-      }
-    }
   }
 
   //
@@ -153,37 +128,6 @@ class VncCanvas extends Canvas
     }
   }
 
-  //
-  // Start/stop receiving keyboard and mouse events.
-  //
-
-  public synchronized void enableInput(boolean enable) {
-    if (enable && !listenersInstalled) {
-      listenersInstalled = true;
-      addKeyListener(this);
-      addMouseListener(this);
-      addMouseMotionListener(this);
-      viewer.buttonPanel.enableRemoteAccessControls(true);
-    } else if (!enable && listenersInstalled) {
-      listenersInstalled = false;
-      removeKeyListener(this);
-      removeMouseListener(this);
-      removeMouseMotionListener(this);
-      viewer.buttonPanel.enableRemoteAccessControls(false);
-    }
-  }
-
-  public void setPixelFormat() throws IOException {
-    if (viewer.options.eightBitColors) {
-      rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6);
-      bytesPixel = 1;
-    } else {
-      rfb.writeSetPixelFormat(32, 24, true, true, 255, 255, 255, 16, 8, 0);
-      bytesPixel = 4;
-    }
-    updateFramebufferSize();
-  }
-
   void updateFramebufferSize() {
 
     // Useful shortcuts.
@@ -194,37 +138,27 @@ class VncCanvas extends Canvas
     // its geometry should be changed. It's not necessary to replace
     // existing image if only pixel format should be changed.
     if (memImage == null) {
-      memImage = viewer.createImage(fbWidth, fbHeight);
+      memImage = player.createImage(fbWidth, fbHeight);
       memGraphics = memImage.getGraphics();
     } else if (memImage.getWidth(null) != fbWidth ||
               memImage.getHeight(null) != fbHeight) {
       synchronized(memImage) {
-       memImage = viewer.createImage(fbWidth, fbHeight);
+       memImage = player.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);
-    }
+    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.
-    if (viewer.inSeparateFrame) {
-      if (viewer.desktopScrollPane != null)
+    if (player.inSeparateFrame) {
+      if (player.desktopScrollPane != null)
        resizeDesktopFrame();
     } else {
       setSize(fbWidth, fbHeight);
@@ -236,17 +170,17 @@ class VncCanvas extends Canvas
 
     // FIXME: Find a better way to determine correct size of a
     // ScrollPane.  -- const
-    Insets insets = viewer.desktopScrollPane.getInsets();
-    viewer.desktopScrollPane.setSize(rfb.framebufferWidth +
+    Insets insets = player.desktopScrollPane.getInsets();
+    player.desktopScrollPane.setSize(rfb.framebufferWidth +
                                     2 * Math.min(insets.left, insets.right),
                                     rfb.framebufferHeight +
                                     2 * Math.min(insets.top, insets.bottom));
 
-    viewer.vncFrame.pack();
+    player.vncFrame.pack();
 
     // Try to limit the frame size to the screen size.
-    Dimension screenSize = viewer.vncFrame.getToolkit().getScreenSize();
-    Dimension frameSize = viewer.vncFrame.getSize();
+    Dimension screenSize = player.vncFrame.getToolkit().getScreenSize();
+    Dimension frameSize = player.vncFrame.getSize();
     Dimension newSize = frameSize;
     boolean needToResizeFrame = false;
     if (frameSize.height > screenSize.height) {
@@ -258,10 +192,10 @@ class VncCanvas extends Canvas
       needToResizeFrame = true;
     }
     if (needToResizeFrame) {
-      viewer.vncFrame.setSize(newSize);
+      player.vncFrame.setSize(newSize);
     }
 
-    viewer.desktopScrollPane.doLayout();
+    player.desktopScrollPane.doLayout();
   }
 
   //
@@ -271,14 +205,28 @@ class VncCanvas extends Canvas
 
   public void processNormalProtocol() throws IOException {
 
-    rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
-                                     rfb.framebufferHeight, false);
+    zlibInflater = new Inflater();
+    tightInflaters = new Inflater[4];
 
-    //
-    // main dispatch loop
-    //
+    // Main dispatch loop.
 
     while (true) {
+
+      while (player.getMode() != player.MODE_PLAYBACK) {
+       synchronized(this) {
+         try {
+           wait();
+         } catch (InterruptedException e) {
+         }
+       }
+       if (player.getMode() == player.MODE_STOPPED) {
+         throw new EOFException("Playback stopped");
+       }
+       if (player.getMode() == player.MODE_PLAYBACK) {
+         player.fbsStream.resumeReading();
+       }
+      }
+
       int msgType = rfb.readServerMessageType();
 
       switch (msgType) {
@@ -299,10 +247,8 @@ class VncCanvas extends Canvas
 
          if (rfb.updateRectEncoding == rfb.EncodingXCursor ||
              rfb.updateRectEncoding == rfb.EncodingRichCursor) {
-           handleCursorShapeUpdate(rfb.updateRectEncoding,
-                                   rfb.updateRectX, rfb.updateRectY,
-                                   rfb.updateRectW, rfb.updateRectH);
-           continue;
+           throw new IOException("Sorry, no support for" +
+                                 " cursor shape updates yet");
          }
 
          switch (rfb.updateRectEncoding) {
@@ -336,35 +282,19 @@ class VncCanvas extends Canvas
            int x, y, w, h;
            Color pixel;
 
-           if (bytesPixel == 1) {
-             memGraphics.setColor(colors[rfb.is.readUnsignedByte()]);
-             memGraphics.fillRect(rx, ry, rw, rh);
+           pixel = new Color(0xFF000000 | rfb.is.readInt());
+           memGraphics.setColor(pixel);
+           memGraphics.fillRect(rx, ry, rw, rh);
 
-             for (int j = 0; j < nSubrects; j++) {
-               pixel = colors[rfb.is.readUnsignedByte()];
-               x = rx + rfb.is.readUnsignedShort();
-               y = ry + rfb.is.readUnsignedShort();
-               w = rfb.is.readUnsignedShort();
-               h = rfb.is.readUnsignedShort();
-
-               memGraphics.setColor(pixel);
-               memGraphics.fillRect(x, y, w, h);
-             }
-           } else {            // 24-bit color
+           for (int j = 0; j < nSubrects; j++) {
              pixel = new Color(0xFF000000 | rfb.is.readInt());
-             memGraphics.setColor(pixel);
-             memGraphics.fillRect(rx, ry, rw, rh);
-
-             for (int j = 0; j < nSubrects; j++) {
-               pixel = new Color(0xFF000000 | rfb.is.readInt());
-               x = rx + rfb.is.readUnsignedShort();
-               y = ry + rfb.is.readUnsignedShort();
-               w = rfb.is.readUnsignedShort();
-               h = rfb.is.readUnsignedShort();
+             x = rx + rfb.is.readUnsignedShort();
+             y = ry + rfb.is.readUnsignedShort();
+             w = rfb.is.readUnsignedShort();
+             h = rfb.is.readUnsignedShort();
 
-               memGraphics.setColor(pixel);
-               memGraphics.fillRect(x, y, w, h);
-             }
+             memGraphics.setColor(pixel);
+             memGraphics.fillRect(x, y, w, h);
            }
 
            scheduleRepaint(rx, ry, rw, rh);
@@ -379,35 +309,19 @@ class VncCanvas extends Canvas
            int x, y, w, h;
            Color pixel;
 
-           if (bytesPixel == 1) {
-             memGraphics.setColor(colors[rfb.is.readUnsignedByte()]);
-             memGraphics.fillRect(rx, ry, rw, rh);
+           pixel = new Color(0xFF000000 | rfb.is.readInt());
+           memGraphics.setColor(pixel);
+           memGraphics.fillRect(rx, ry, rw, rh);
 
-             for (int j = 0; j < nSubrects; j++) {
-               pixel = colors[rfb.is.readUnsignedByte()];
-               x = rx + rfb.is.readUnsignedByte();
-               y = ry + rfb.is.readUnsignedByte();
-               w = rfb.is.readUnsignedByte();
-               h = rfb.is.readUnsignedByte();
-
-               memGraphics.setColor(pixel);
-               memGraphics.fillRect(x, y, w, h);
-             }
-           } else {            // 24-bit color
+           for (int j = 0; j < nSubrects; j++) {
              pixel = new Color(0xFF000000 | rfb.is.readInt());
-             memGraphics.setColor(pixel);
-             memGraphics.fillRect(rx, ry, rw, rh);
-
-             for (int j = 0; j < nSubrects; j++) {
-               pixel = new Color(0xFF000000 | rfb.is.readInt());
-               x = rx + rfb.is.readUnsignedByte();
-               y = ry + rfb.is.readUnsignedByte();
-               w = rfb.is.readUnsignedByte();
-               h = rfb.is.readUnsignedByte();
+             x = rx + rfb.is.readUnsignedByte();
+             y = ry + rfb.is.readUnsignedByte();
+             w = rfb.is.readUnsignedByte();
+             h = rfb.is.readUnsignedByte();
 
-               memGraphics.setColor(pixel);
-               memGraphics.fillRect(x, y, w, h);
-             }
+             memGraphics.setColor(pixel);
+             memGraphics.fillRect(x, y, w, h);
            }
 
            scheduleRepaint(rx, ry, rw, rh);
@@ -436,22 +350,16 @@ class VncCanvas extends Canvas
 
                // Is it a raw-encoded sub-rectangle?
                if ((subencoding & rfb.HextileRaw) != 0) {
-                 if (bytesPixel == 1) {
-                   for (int j = ty; j < ty + th; j++) {
-                     rfb.is.readFully(pixels8, j*rfb.framebufferWidth+tx, tw);
-                   }
-                 } else {
-                   byte[] buf = new byte[tw * 4];
-                   int count, offset;
-                   for (int j = ty; j < ty + th; j++) {
-                     rfb.is.readFully(buf);
-                     offset = j * rfb.framebufferWidth + tx;
-                     for (count = 0; count < tw; count++) {
-                       pixels24[offset + count] =
-                         (buf[count * 4 + 1] & 0xFF) << 16 |
-                         (buf[count * 4 + 2] & 0xFF) << 8 |
-                         (buf[count * 4 + 3] & 0xFF);
-                     }
+                 byte[] buf = new byte[tw * 4];
+                 int count, offset;
+                 for (int j = ty; j < ty + th; j++) {
+                   rfb.is.readFully(buf);
+                   offset = j * rfb.framebufferWidth + tx;
+                   for (count = 0; count < tw; count++) {
+                     pixels24[offset + count] =
+                       (buf[count * 4 + 1] & 0xFF) << 16 |
+                       (buf[count * 4 + 2] & 0xFF) << 8 |
+                       (buf[count * 4 + 3] & 0xFF);
                    }
                  }
                  handleUpdatedPixels(tx, ty, tw, th);
@@ -460,22 +368,14 @@ class VncCanvas extends Canvas
 
                // Read and draw the background if specified.
                if ((subencoding & rfb.HextileBackgroundSpecified) != 0) {
-                 if (bytesPixel == 1) {
-                   bg = colors[rfb.is.readUnsignedByte()];
-                 } else {
-                   bg = new Color(0xFF000000 | rfb.is.readInt());
-                 }
+                 bg = new Color(0xFF000000 | rfb.is.readInt());
                }
                memGraphics.setColor(bg);
                memGraphics.fillRect(tx, ty, tw, th);
 
                // Read the foreground color if specified.
                if ((subencoding & rfb.HextileForegroundSpecified) != 0) {
-                 if (bytesPixel == 1) {
-                   fg = colors[rfb.is.readUnsignedByte()];
-                 } else {
-                   fg = new Color(0xFF000000 | rfb.is.readInt());
-                 }
+                 fg = new Color(0xFF000000 | rfb.is.readInt());
                }
 
                // Done with this tile if there is no sub-rectangles.
@@ -485,62 +385,29 @@ class VncCanvas extends Canvas
                int nSubrects = rfb.is.readUnsignedByte();
 
                int b1, b2, sx, sy, sw, sh;
-               if (bytesPixel == 1) {
-
-                 // BGR233 (8-bit color) version.
-                 if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
-                   for (int j = 0; j < nSubrects; j++) {
-                     fg = colors[rfb.is.readUnsignedByte()];
-                     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(fg);
-                     memGraphics.fillRect(sx, sy, sw, sh);
-                   }
-                 } else {
+               if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
+                 for (int j = 0; j < nSubrects; j++) {
+                   fg = new Color(0xFF000000 | rfb.is.readInt());
+                   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(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);
-                   }
+                   memGraphics.fillRect(sx, sy, sw, sh);
                  }
-
                } else {
-
-                 // Full-color (24-bit) version.
-                 if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
-                   for (int j = 0; j < nSubrects; j++) {
-                     fg = new Color(0xFF000000 | rfb.is.readInt());
-                     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(fg);
-                     memGraphics.fillRect(sx, sy, sw, sh);
-                   }
-                 } else {
-                   memGraphics.setColor(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);
-                   }
+                 memGraphics.setColor(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);
                  }
-
                }
 
              }
@@ -560,10 +427,6 @@ class VncCanvas extends Canvas
             }
 
             rfb.is.readFully(zlibBuf, 0, nBytes);
-
-            if (zlibInflater == null) {
-              zlibInflater = new Inflater();
-            }
             zlibInflater.setInput(zlibBuf, 0, nBytes);
 
             handleZlibRect(rfb.updateRectX, rfb.updateRectY,
@@ -586,30 +449,6 @@ class VncCanvas extends Canvas
          }
 
        }
-
-       // Defer framebuffer update request if necessary. But wake up
-       // immediately on keyboard or mouse event.
-       if (viewer.deferUpdateRequests > 0) {
-         synchronized(rfb) {
-           try {
-             rfb.wait(viewer.deferUpdateRequests);
-           } catch (InterruptedException e) {
-           }
-         }
-       }
-
-       // Before requesting framebuffer update, check if the pixel
-       // format should be changed. If it should, request full update
-       // instead of incremental one.
-       if (viewer.options.eightBitColors != (bytesPixel == 1)) {
-         setPixelFormat();
-         rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
-                                           rfb.framebufferHeight, false);
-       } else {
-         rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
-                                           rfb.framebufferHeight, true);
-       }
-
        break;
 
       case RfbProto.SetColourMapEntries:
@@ -621,12 +460,15 @@ class VncCanvas extends Canvas
 
       case RfbProto.ServerCutText:
        String s = rfb.readServerCutText();
-       viewer.clipboard.setCutText(s);
        break;
 
       default:
        throw new IOException("Unknown RFB message type " + msgType);
       }
+
+      if (player.getMode() == player.MODE_STOPPED) {
+       throw new EOFException("Playback stopped");
+      }
     }
   }
 
@@ -637,22 +479,16 @@ class VncCanvas extends Canvas
 
   void handleRawRect(int x, int y, int w, int h) throws IOException {
 
-    if (bytesPixel == 1) {
-      for (int dy = y; dy < y + h; dy++) {
-       rfb.is.readFully(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);
-       offset = dy * rfb.framebufferWidth + x;
-       for (i = 0; i < w; i++) {
-         pixels24[offset + i] =
-           (buf[i * 4 + 1] & 0xFF) << 16 |
-           (buf[i * 4 + 2] & 0xFF) << 8 |
-           (buf[i * 4 + 3] & 0xFF);
-       }
+    byte[] buf = new byte[w * 4];
+    int i, offset;
+    for (int dy = y; dy < y + h; dy++) {
+      rfb.is.readFully(buf);
+      offset = dy * rfb.framebufferWidth + x;
+      for (i = 0; i < w; i++) {
+       pixels24[offset + i] =
+         (buf[i * 4 + 1] & 0xFF) << 16 |
+         (buf[i * 4 + 2] & 0xFF) << 8 |
+         (buf[i * 4 + 3] & 0xFF);
       }
     }
 
@@ -669,22 +505,16 @@ class VncCanvas extends Canvas
     throws IOException {
 
     try {
-      if (bytesPixel == 1) {
-       for (int dy = y; dy < y + h; dy++) {
-         zlibInflater.inflate(pixels8, dy * rfb.framebufferWidth + x, w);
-       }
-      } else {
-       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 + 1] & 0xFF) << 16 |
-             (buf[i * 4 + 2] & 0xFF) << 8 |
-             (buf[i * 4 + 3] & 0xFF);
-         }
+      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 + 1] & 0xFF) << 16 |
+           (buf[i * 4 + 2] & 0xFF) << 8 |
+           (buf[i * 4 + 3] & 0xFF);
        }
       }
     }
@@ -720,15 +550,11 @@ class VncCanvas extends Canvas
 
     // Handle solid-color rectangles.
     if (comp_ctl == rfb.TightFill) {
-      if (bytesPixel == 1) {
-       memGraphics.setColor(colors[rfb.is.readUnsignedByte()]);
-      } else {
-       byte[] buf = new byte[3];
-       rfb.is.readFully(buf);
-       Color bg = new Color(0xFF000000 | (buf[0] & 0xFF) << 16 |
-                            (buf[1] & 0xFF) << 8 | (buf[2] & 0xFF));
-       memGraphics.setColor(bg);
-      }
+      byte[] buf = new byte[3];
+      rfb.is.readFully(buf);
+      Color bg = new Color(0xFF000000 | (buf[0] & 0xFF) << 16 |
+                          (buf[1] & 0xFF) << 8 | (buf[2] & 0xFF));
+      memGraphics.setColor(bg);
       memGraphics.fillRect(x, y, w, h);
       scheduleRepaint(x, y, w, h);
       return;
@@ -773,21 +599,12 @@ class VncCanvas extends Canvas
       int filter_id = rfb.is.readUnsignedByte();
       if (filter_id == rfb.TightFilterPalette) {
        numColors = rfb.is.readUnsignedByte() + 1;
-        if (bytesPixel == 1) {
-         if (numColors != 2) {
-           throw new IOException("Incorrect tight palette size: " +
-                                 numColors);
-         }
-         palette8[0] = rfb.is.readByte();
-         palette8[1] = rfb.is.readByte();
-       } else {
-         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));
-         }
+       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;
@@ -797,7 +614,7 @@ class VncCanvas extends Canvas
        throw new IOException("Incorrect tight filter id: " + filter_id);
       }
     }
-    if (numColors == 0 && bytesPixel == 4)
+    if (numColors == 0)
       rowSize *= 3;
 
     // Read, optionally uncompress and decode data.
@@ -810,13 +627,9 @@ class VncCanvas extends Canvas
        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);
-         }
+         decodeMonoData(x, y, w, h, indexedData, palette24);
        } else {
-         // 3..255 colors (assuming bytesPixel == 4).
+         // 3..255 colors.
          int i = 0;
          for (int dy = y; dy < y + h; dy++) {
            for (int dx = x; dx < x + w; dx++) {
@@ -832,22 +645,16 @@ class VncCanvas extends Canvas
        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);
-         }
-       } else {
-         byte[] buf = new byte[w * 3];
-         int i, offset;
-         for (int dy = y; dy < y + h; dy++) {
-           rfb.is.readFully(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);
-           }
+       byte[] buf = new byte[w * 3];
+       int i, offset;
+       for (int dy = y; dy < y + h; dy++) {
+         rfb.is.readFully(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);
          }
        }
       }
@@ -869,13 +676,9 @@ class VncCanvas extends Canvas
          myInflater.inflate(indexedData);
          if (numColors == 2) {
            // Two colors.
-           if (bytesPixel == 1) {
-             decodeMonoData(x, y, w, h, indexedData, palette8);
-           } else {
-             decodeMonoData(x, y, w, h, indexedData, palette24);
-           }
+           decodeMonoData(x, y, w, h, indexedData, palette24);
          } else {
-           // More than two colors (assuming bytesPixel == 4).
+           // More than two colors.
            int i = 0;
            for (int dy = y; dy < y + h; dy++) {
              for (int dx = x; dx < x + w; dx++) {
@@ -885,28 +688,22 @@ class VncCanvas extends Canvas
            }
          }
        } else if (useGradient) {
-         // Compressed "Gradient"-filtered data (assuming bytesPixel == 4).
+         // Compressed "Gradient"-filtered data.
          byte[] buf = new byte[w * h * 3];
          myInflater.inflate(buf);
          decodeGradientData(x, y, w, h, buf);
        } else {
          // Compressed truecolor data.
-         if (bytesPixel == 1) {
-           for (int dy = y; dy < y + h; dy++) {
-             myInflater.inflate(pixels8, dy * rfb.framebufferWidth + x, w);
-           }
-         } else {
-           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);
-             }
+         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);
            }
          }
        }
@@ -921,30 +718,9 @@ class VncCanvas extends Canvas
   }
 
   //
-  // Decode 1bpp-encoded bi-color rectangle (8-bit and 24-bit versions).
+  // Decode 1bpp-encoded bi-color rectangle.
   //
 
-  void decodeMonoData(int x, int y, int w, int h, byte[] src, byte[] palette)
-    throws IOException {
-
-    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)
     throws IOException {
 
@@ -1021,6 +797,7 @@ class VncCanvas extends Canvas
   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);
@@ -1033,271 +810,7 @@ class VncCanvas extends Canvas
 
   void scheduleRepaint(int x, int y, int w, int h) {
     // Request repaint, deferred if necessary.
-    repaint(viewer.deferScreenUpdates, x, y, w, h);
-  }
-
-
-  //
-  // Handle events.
-  //
-
-  public void keyPressed(KeyEvent evt) {
-    processLocalKeyEvent(evt);
-  }
-  public void keyReleased(KeyEvent evt) {
-    processLocalKeyEvent(evt);
-  }
-  public void keyTyped(KeyEvent evt) {
-    evt.consume();
-  }
-
-  public void mousePressed(MouseEvent evt) {
-    processLocalMouseEvent(evt, false);
-  }
-  public void mouseReleased(MouseEvent evt) {
-    processLocalMouseEvent(evt, false);
-  }
-  public void mouseMoved(MouseEvent evt) {
-    processLocalMouseEvent(evt, true);
-  }
-  public void mouseDragged(MouseEvent evt) {
-    processLocalMouseEvent(evt, true);
-  }
-
-  public void processLocalKeyEvent(KeyEvent evt) {
-    if (rfb != null && rfb.inNormalProtocol) {
-      synchronized(rfb) {
-       try {
-         rfb.writeKeyEvent(evt);
-       } catch (Exception e) {
-         e.printStackTrace();
-       }
-       rfb.notify();
-      }
-    }
-    // Don't ever pass keyboard events to AWT for default processing. 
-    // Otherwise, pressing Tab would switch focus to ButtonPanel etc.
-    evt.consume();
-  }
-
-  public void processLocalMouseEvent(MouseEvent evt, boolean moved) {
-    if (rfb != null && rfb.inNormalProtocol) {
-      if (moved) {
-       softCursorMove(evt.getX(), evt.getY());
-      }
-      synchronized(rfb) {
-       try {
-         rfb.writePointerEvent(evt);
-       } catch (Exception e) {
-         e.printStackTrace();
-       }
-       rfb.notify();
-      }
-    }
-  }
-
-
-  //
-  // Ignored events.
-  //
-
-  public void mouseClicked(MouseEvent evt) {}
-  public void mouseEntered(MouseEvent evt) {}
-  public void mouseExited(MouseEvent evt) {}
-
-
-  //////////////////////////////////////////////////////////////////
-  //
-  // Handle cursor shape updates (XCursor and RichCursor encodings).
-  //
-
-  boolean showSoftCursor = false;
-
-  int[] softCursorPixels;
-  MemoryImageSource softCursorSource;
-  Image softCursor;
-
-  int cursorX = 0, cursorY = 0;
-  int cursorWidth, cursorHeight;
-  int hotX, hotY;
-
-  //
-  // Handle cursor shape update (XCursor and RichCursor encodings).
-  //
-
-  synchronized void
-    handleCursorShapeUpdate(int encodingType,
-                           int xhot, int yhot, int width, int height)
-    throws IOException {
-
-    int bytesPerRow = (width + 7) / 8;
-    int bytesMaskData = bytesPerRow * height;
-
-    softCursorFree();
-
-    if (width * height == 0)
-      return;
-
-    // Ignore cursor shape data if requested by user.
-
-    if (viewer.options.ignoreCursorUpdates) {
-      if (encodingType == rfb.EncodingXCursor) {
-       rfb.is.skipBytes(6 + bytesMaskData * 2);
-      } else {
-       // rfb.EncodingRichCursor
-       rfb.is.skipBytes(width * height + bytesMaskData);
-      }
-      return;
-    }
-
-    // Decode cursor pixel data.
-
-    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 pixByte, 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 = 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;
-         }
-       }
-       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;
-       }
-      }
-
-    }
-
-    // Draw the cursor on an off-screen image.
-
-    softCursorSource =
-      new MemoryImageSource(width, height, softCursorPixels, 0, width);
-    softCursor = createImage(softCursorSource);
-
-    // Set remaining data associated with cursor.
-
-    cursorWidth = width;
-    cursorHeight = height;
-    hotX = xhot;
-    hotY = yhot;
-
-    showSoftCursor = true;
-
-    // Show the cursor.
-
-    repaint(viewer.deferCursorUpdates,
-           cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight);
-  }
-
-  //
-  // softCursorMove(). Moves soft cursor into a particular location.
-  //
-
-  synchronized void softCursorMove(int x, int y) {
-    if (showSoftCursor) {
-      repaint(viewer.deferCursorUpdates,
-             cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight);
-      repaint(viewer.deferCursorUpdates,
-             x - hotX, y - hotY, cursorWidth, cursorHeight);
-    }
-
-    cursorX = x;
-    cursorY = y;
+    repaint(player.deferScreenUpdates, x, y, w, h);
   }
 
-  //
-  // softCursorFree(). Remove soft cursor, dispose resources.
-  //
-
-  synchronized void softCursorFree() {
-    if (showSoftCursor) {
-      showSoftCursor = false;
-      softCursor = null;
-      softCursorSource = null;
-      softCursorPixels = null;
-
-      repaint(viewer.deferCursorUpdates,
-             cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight);
-    }
-  }
 }
diff --git a/java/src/com/tightvnc/rfbplayer/dir.mk b/java/src/com/tightvnc/rfbplayer/dir.mk
deleted file mode 100644 (file)
index 2174405..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Making the VNC applet.
-#
-
-CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \
-         OptionsFrame.class ClipboardFrame.class ButtonPanel.class \
-         DesCipher.class
-
-PAGES = index.vnc shared.vnc noshared.vnc hextile.vnc zlib.vnc tight.vnc
-
-all: $(CLASSES) VncViewer.jar
-
-VncViewer.jar: $(CLASSES)
-       @$(JavaArchive)
-
-export:: $(CLASSES) VncViewer.jar $(PAGES)
-       @$(ExportJavaClasses)
-
-clean::
-       $(RM) *.class *.jar
diff --git a/java/src/com/tightvnc/rfbplayer/hextile.vnc b/java/src/com/tightvnc/rfbplayer/hextile.vnc
deleted file mode 100644 (file)
index d758ccd..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- hextile.vnc - hextile html page for Java VNC viewer applet.  On
-     any file ending in .vnc, the HTTP server embedded in Xvnc will
-     substitute the following variables when preceded by a dollar:
-     USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT,
-     PORT.  Use two dollar signs ($$) to get a dollar sign in the
-     generated html. -->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
-        WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name=ENCODING value=Hextile>
-</APPLET>
-<BR>
-<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
-</HTML>
diff --git a/java/src/com/tightvnc/rfbplayer/index.html b/java/src/com/tightvnc/rfbplayer/index.html
new file mode 100644 (file)
index 0000000..f5e0eea
--- /dev/null
@@ -0,0 +1,9 @@
+<HTML>
+<TITLE>RFB Session Playback</TITLE>
+<BODY>
+<APPLET CODE=RfbPlayer.class ARCHIVE=RfbPlayer.jar
+        WIDTH=800 HEIGHT=640>
+<param name=FILE value="./session.fbs">
+</APPLET>
+</BODY>
+</HTML>
diff --git a/java/src/com/tightvnc/rfbplayer/index.vnc b/java/src/com/tightvnc/rfbplayer/index.vnc
deleted file mode 100644 (file)
index d9bb30e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- index.vnc - default html page for Java VNC viewer applet.  On any file
-     ending in .vnc, the HTTP server embedded in Xvnc will substitute the
-     following variables when preceded by a dollar: USER, DESKTOP, DISPLAY,
-     APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT.  Use two dollar signs
-     ($$) to get a dollar sign in the generated html. -->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
-        WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-</APPLET>
-<BR>
-<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
-</HTML>
diff --git a/java/src/com/tightvnc/rfbplayer/noshared.vnc b/java/src/com/tightvnc/rfbplayer/noshared.vnc
deleted file mode 100644 (file)
index b0dc3af..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This is an example of how to set default options in the Java VNC viewer
-     applet - in this case the "Share Desktop" option is set to "No".  Any
-     option can be set by giving a parameter with the same name as the
-     option (spaces are important, but case isn't) -->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY) [not shared]
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
-        WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name="share desktop" value=no>
-</APPLET>
-<BR>
-<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
-</HTML>
diff --git a/java/src/com/tightvnc/rfbplayer/shared.vnc b/java/src/com/tightvnc/rfbplayer/shared.vnc
deleted file mode 100644 (file)
index 2f8ea1c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This is an example of how to set default options in the Java VNC viewer
-     applet - in this case the "Share Desktop" option is set to "Yes".  Any
-     option can be set by giving a parameter with the same name as the
-     option (spaces are important, but case isn't) -->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY) [shared]
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
-        WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name="share desktop" value=yes>
-</APPLET>
-<BR>
-<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
-</HTML>
diff --git a/java/src/com/tightvnc/rfbplayer/tight.vnc b/java/src/com/tightvnc/rfbplayer/tight.vnc
deleted file mode 100644 (file)
index 3ca7a69..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- tight.vnc - tight html page for Java VNC viewer applet.  On any file
-     ending in .vnc, the HTTP server embedded in Xvnc will substitute the
-     following variables when preceded by a dollar: USER, DESKTOP, DISPLAY,
-     APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT.  Use two dollar signs
-     ($$) to get a dollar sign in the generated html. -->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
-        WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name=ENCODING value=Tight>
-</APPLET>
-<BR>
-<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
-</HTML>
diff --git a/java/src/com/tightvnc/rfbplayer/zlib.vnc b/java/src/com/tightvnc/rfbplayer/zlib.vnc
deleted file mode 100644 (file)
index 877ec5d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- zlib.vnc - zlib html page for Java VNC viewer applet.  On any file
-     ending in .vnc, the HTTP server embedded in Xvnc will substitute the
-     following variables when preceded by a dollar: USER, DESKTOP, DISPLAY,
-     APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT.  Use two dollar signs
-     ($$) to get a dollar sign in the generated html. -->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
-        WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name=ENCODING value=Zlib>
-</APPLET>
-<BR>
-<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
-</HTML>