aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2002-05-20 10:55:47 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2002-05-20 10:55:47 +0000
commit903009eca89d779b78201c0015073d60f80c6306 (patch)
treef20dc56af169c93cb024c184ffa987caa510c6bd /java/src
parentfc21f67855e89126afe10f6deb0a5e7b5ea515dc (diff)
downloadtigervnc-903009eca89d779b78201c0015073d60f80c6306.tar.gz
tigervnc-903009eca89d779b78201c0015073d60f80c6306.zip
Preliminary version of RFB Session Player converted from TightVNC Java
viewer sources. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2500 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/tightvnc/rfbplayer/AuthPanel.java116
-rw-r--r--java/src/com/tightvnc/rfbplayer/ButtonPanel.java123
-rw-r--r--java/src/com/tightvnc/rfbplayer/ClipboardFrame.java133
-rw-r--r--java/src/com/tightvnc/rfbplayer/DesCipher.java496
-rw-r--r--java/src/com/tightvnc/rfbplayer/FbsInputStream.java174
-rw-r--r--java/src/com/tightvnc/rfbplayer/Makefile22
-rw-r--r--java/src/com/tightvnc/rfbplayer/OptionsFrame.java387
-rw-r--r--java/src/com/tightvnc/rfbplayer/README283
-rw-r--r--java/src/com/tightvnc/rfbplayer/RfbPlayer.java353
-rw-r--r--java/src/com/tightvnc/rfbplayer/RfbProto.java424
-rw-r--r--java/src/com/tightvnc/rfbplayer/VncCanvas.java801
-rw-r--r--java/src/com/tightvnc/rfbplayer/dir.mk20
-rw-r--r--java/src/com/tightvnc/rfbplayer/hextile.vnc19
-rw-r--r--java/src/com/tightvnc/rfbplayer/index.html9
-rw-r--r--java/src/com/tightvnc/rfbplayer/index.vnc17
-rw-r--r--java/src/com/tightvnc/rfbplayer/noshared.vnc17
-rw-r--r--java/src/com/tightvnc/rfbplayer/shared.vnc17
-rw-r--r--java/src/com/tightvnc/rfbplayer/tight.vnc18
-rw-r--r--java/src/com/tightvnc/rfbplayer/zlib.vnc18
19 files changed, 482 insertions, 2965 deletions
diff --git a/java/src/com/tightvnc/rfbplayer/AuthPanel.java b/java/src/com/tightvnc/rfbplayer/AuthPanel.java
deleted file mode 100644
index cdc4fe8c..00000000
--- a/java/src/com/tightvnc/rfbplayer/AuthPanel.java
+++ /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();
- }
-
-}
diff --git a/java/src/com/tightvnc/rfbplayer/ButtonPanel.java b/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
index de3ddfee..e7cabb58 100644
--- a/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
+++ b/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
@@ -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
@@ -18,62 +17,55 @@
// 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
index f0a5b8df..00000000
--- a/java/src/com/tightvnc/rfbplayer/ClipboardFrame.java
+++ /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
index 2b7b5f22..00000000
--- a/java/src/com/tightvnc/rfbplayer/DesCipher.java
+++ /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
index 00000000..fab854be
--- /dev/null
+++ b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
@@ -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;
+ }
+}
+
diff --git a/java/src/com/tightvnc/rfbplayer/Makefile b/java/src/com/tightvnc/rfbplayer/Makefile
index 76dbca43..42d10474 100644
--- a/java/src/com/tightvnc/rfbplayer/Makefile
+++ b/java/src/com/tightvnc/rfbplayer/Makefile
@@ -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
index 45e5ab6e..00000000
--- a/java/src/com/tightvnc/rfbplayer/OptionsFrame.java
+++ /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) {}
-}
diff --git a/java/src/com/tightvnc/rfbplayer/README b/java/src/com/tightvnc/rfbplayer/README
index b9f24c0f..7d52c580 100644
--- a/java/src/com/tightvnc/rfbplayer/README
+++ b/java/src/com/tightvnc/rfbplayer/README
@@ -1,274 +1,29 @@
-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/
diff --git a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
index 2524a50b..4a9bc2fe 100644
--- a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
+++ b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
@@ -18,17 +18,11 @@
// 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) {
@@ -439,51 +259,6 @@ public class VncViewer extends java.applet.Applet
}
//
- // 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) {
@@ -544,18 +317,10 @@ 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) {}
diff --git a/java/src/com/tightvnc/rfbplayer/RfbProto.java b/java/src/com/tightvnc/rfbplayer/RfbProto.java
index a86aac53..daff66c3 100644
--- a/java/src/com/tightvnc/rfbplayer/RfbProto.java
+++ b/java/src/com/tightvnc/rfbplayer/RfbProto.java
@@ -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');
@@ -133,15 +121,6 @@ class RfbProto {
//
- // Write our protocol version message
- //
-
- void writeVersionMsg() throws IOException {
- os.write(versionMsg.getBytes());
- }
-
-
- //
// Find out the authentication scheme.
//
@@ -161,28 +140,13 @@ 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;
- }
}
diff --git a/java/src/com/tightvnc/rfbplayer/VncCanvas.java b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
index 6d12aa25..750c8472 100644
--- a/java/src/com/tightvnc/rfbplayer/VncCanvas.java
+++ b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
@@ -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
index 21744056..00000000
--- a/java/src/com/tightvnc/rfbplayer/dir.mk
+++ /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
index d758ccdf..00000000
--- a/java/src/com/tightvnc/rfbplayer/hextile.vnc
+++ /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
index 00000000..f5e0eea0
--- /dev/null
+++ b/java/src/com/tightvnc/rfbplayer/index.html
@@ -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
index d9bb30ef..00000000
--- a/java/src/com/tightvnc/rfbplayer/index.vnc
+++ /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
index b0dc3afc..00000000
--- a/java/src/com/tightvnc/rfbplayer/noshared.vnc
+++ /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
index 2f8ea1c5..00000000
--- a/java/src/com/tightvnc/rfbplayer/shared.vnc
+++ /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
index 3ca7a69f..00000000
--- a/java/src/com/tightvnc/rfbplayer/tight.vnc
+++ /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
index 877ec5d1..00000000
--- a/java/src/com/tightvnc/rfbplayer/zlib.vnc
+++ /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>