git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2457 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
@@ -0,0 +1,116 @@ | |||
// | |||
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. | |||
// Copyright (C) 2002-2006 Constantin Kaplinsky. 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 { | |||
TextField passwordField; | |||
Button okButton; | |||
// | |||
// Constructor. | |||
// | |||
public AuthPanel(VncViewer viewer) | |||
{ | |||
Label titleLabel = new Label("VNC Authentication", Label.CENTER); | |||
titleLabel.setFont(new Font("Helvetica", Font.BOLD, 18)); | |||
Label promptLabel = new Label("Password:", Label.CENTER); | |||
passwordField = new TextField(10); | |||
passwordField.setForeground(Color.black); | |||
passwordField.setBackground(Color.white); | |||
passwordField.setEchoChar('*'); | |||
okButton = new Button("OK"); | |||
GridBagLayout gridbag = new GridBagLayout(); | |||
GridBagConstraints gbc = new GridBagConstraints(); | |||
setLayout(gridbag); | |||
gbc.gridwidth = GridBagConstraints.REMAINDER; | |||
gbc.insets = new Insets(0,0,20,0); | |||
gridbag.setConstraints(titleLabel,gbc); | |||
add(titleLabel); | |||
gbc.fill = GridBagConstraints.NONE; | |||
gbc.gridwidth = 1; | |||
gbc.insets = new Insets(0,0,0,0); | |||
gridbag.setConstraints(promptLabel,gbc); | |||
add(promptLabel); | |||
gridbag.setConstraints(passwordField,gbc); | |||
add(passwordField); | |||
passwordField.addActionListener(this); | |||
// gbc.ipady = 10; | |||
gbc.gridwidth = GridBagConstraints.REMAINDER; | |||
gbc.fill = GridBagConstraints.BOTH; | |||
gbc.insets = new Insets(0,20,0,0); | |||
gbc.ipadx = 30; | |||
gridbag.setConstraints(okButton,gbc); | |||
add(okButton); | |||
okButton.addActionListener(this); | |||
} | |||
// | |||
// Move keyboard focus to the default object, that is, the password | |||
// text field. | |||
// | |||
public void moveFocusToDefaultField() | |||
{ | |||
passwordField.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() == passwordField || evt.getSource() == okButton) { | |||
passwordField.setEnabled(false); | |||
notify(); | |||
} | |||
} | |||
// | |||
// Wait for user entering a password, and return it as String. | |||
// | |||
public synchronized String getPassword() throws Exception | |||
{ | |||
try { | |||
wait(); | |||
} catch (InterruptedException e) { } | |||
return passwordField.getText(); | |||
} | |||
} |
@@ -0,0 +1,154 @@ | |||
// | |||
// Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved. | |||
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. | |||
// | |||
// This is free software; you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License as published by | |||
// the Free Software Foundation; either version 2 of the License, or | |||
// (at your option) any later version. | |||
// | |||
// This software is distributed in the hope that it will be useful, | |||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
// GNU General Public License for more details. | |||
// | |||
// You should have received a copy of the GNU General Public License | |||
// along with this software; if not, write to the Free Software | |||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
// USA. | |||
// | |||
// | |||
// 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 recordButton; | |||
Button clipboardButton; | |||
Button ctrlAltDelButton; | |||
Button refreshButton; | |||
ButtonPanel(VncViewer v) { | |||
viewer = v; | |||
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); | |||
if (viewer.rec != null) { | |||
recordButton = new Button("Record"); | |||
add(recordButton); | |||
recordButton.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); | |||
} | |||
// | |||
// Enable buttons on successful connection. | |||
// | |||
public void enableButtons() { | |||
disconnectButton.setEnabled(true); | |||
clipboardButton.setEnabled(true); | |||
refreshButton.setEnabled(true); | |||
} | |||
// | |||
// Disable all buttons on disconnect. | |||
// | |||
public void disableButtonsOnDisconnect() { | |||
remove(disconnectButton); | |||
disconnectButton = new Button("Hide desktop"); | |||
disconnectButton.setEnabled(true); | |||
add(disconnectButton, 0); | |||
disconnectButton.addActionListener(this); | |||
optionsButton.setEnabled(false); | |||
clipboardButton.setEnabled(false); | |||
ctrlAltDelButton.setEnabled(false); | |||
refreshButton.setEnabled(false); | |||
validate(); | |||
} | |||
// | |||
// Enable/disable controls that should not be available in view-only | |||
// mode. | |||
// | |||
public void enableRemoteAccessControls(boolean enable) { | |||
ctrlAltDelButton.setEnabled(enable); | |||
} | |||
// | |||
// Event processing. | |||
// | |||
public void actionPerformed(ActionEvent evt) { | |||
viewer.moveFocusToDesktop(); | |||
if (evt.getSource() == disconnectButton) { | |||
viewer.disconnect(); | |||
} else if (evt.getSource() == optionsButton) { | |||
viewer.options.setVisible(!viewer.options.isVisible()); | |||
} else if (evt.getSource() == recordButton) { | |||
viewer.rec.setVisible(!viewer.rec.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(); | |||
} | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,87 @@ | |||
// | |||
// Copyright (C) 2003 Constantin Kaplinsky. 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. | |||
// | |||
// | |||
// CapabilityInfo.java - A class to hold information about a | |||
// particular capability as used in the RFB protocol 3.130. | |||
// | |||
class CapabilityInfo { | |||
// Public methods | |||
public CapabilityInfo(int code, | |||
String vendorSignature, | |||
String nameSignature, | |||
String description) { | |||
this.code = code; | |||
this.vendorSignature = vendorSignature; | |||
this.nameSignature = nameSignature; | |||
this.description = description; | |||
enabled = false; | |||
} | |||
public CapabilityInfo(int code, | |||
byte[] vendorSignature, | |||
byte[] nameSignature) { | |||
this.code = code; | |||
this.vendorSignature = new String(vendorSignature); | |||
this.nameSignature = new String(nameSignature); | |||
this.description = null; | |||
enabled = false; | |||
} | |||
public int getCode() { | |||
return code; | |||
} | |||
public String getDescription() { | |||
return description; | |||
} | |||
public boolean isEnabled() { | |||
return enabled; | |||
} | |||
public void enable() { | |||
enabled = true; | |||
} | |||
public boolean equals(CapabilityInfo other) { | |||
return (other != null && this.code == other.code && | |||
this.vendorSignature.equals(other.vendorSignature) && | |||
this.nameSignature.equals(other.nameSignature)); | |||
} | |||
public boolean enableIfEquals(CapabilityInfo other) { | |||
if (this.equals(other)) | |||
enable(); | |||
return isEnabled(); | |||
} | |||
// Protected data | |||
protected int code; | |||
protected String vendorSignature; | |||
protected String nameSignature; | |||
protected String description; | |||
protected boolean enabled; | |||
} |
@@ -0,0 +1,103 @@ | |||
// | |||
// Copyright (C) 2003 Constantin Kaplinsky. 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. | |||
// | |||
// | |||
// CapsContainer.java - A container of capabilities as used in the RFB | |||
// protocol 3.130 | |||
// | |||
import java.util.Vector; | |||
import java.util.Hashtable; | |||
class CapsContainer { | |||
// Public methods | |||
public CapsContainer() { | |||
infoMap = new Hashtable(64, (float)0.25); | |||
orderedList = new Vector(32, 8); | |||
} | |||
public void add(CapabilityInfo capinfo) { | |||
Integer key = new Integer(capinfo.getCode()); | |||
infoMap.put(key, capinfo); | |||
} | |||
public void add(int code, String vendor, String name, String desc) { | |||
Integer key = new Integer(code); | |||
infoMap.put(key, new CapabilityInfo(code, vendor, name, desc)); | |||
} | |||
public boolean isKnown(int code) { | |||
return infoMap.containsKey(new Integer(code)); | |||
} | |||
public CapabilityInfo getInfo(int code) { | |||
return (CapabilityInfo)infoMap.get(new Integer(code)); | |||
} | |||
public String getDescription(int code) { | |||
CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(new Integer(code)); | |||
if (capinfo == null) | |||
return null; | |||
return capinfo.getDescription(); | |||
} | |||
public boolean enable(CapabilityInfo other) { | |||
Integer key = new Integer(other.getCode()); | |||
CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(key); | |||
if (capinfo == null) | |||
return false; | |||
boolean enabled = capinfo.enableIfEquals(other); | |||
if (enabled) | |||
orderedList.addElement(key); | |||
return enabled; | |||
} | |||
public boolean isEnabled(int code) { | |||
CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(new Integer(code)); | |||
if (capinfo == null) | |||
return false; | |||
return capinfo.isEnabled(); | |||
} | |||
public int numEnabled() { | |||
return orderedList.size(); | |||
} | |||
public int getByOrder(int idx) { | |||
int code; | |||
try { | |||
code = ((Integer)orderedList.elementAt(idx)).intValue(); | |||
} catch (ArrayIndexOutOfBoundsException e) { | |||
code = 0; | |||
} | |||
return code; | |||
} | |||
// Protected data | |||
protected Hashtable infoMap; | |||
protected Vector orderedList; | |||
} | |||
@@ -0,0 +1,133 @@ | |||
// | |||
// 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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,496 @@ | |||
// | |||
// 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]; | |||
} | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
// | |||
// Copyright (C) 2002 Constantin Kaplinsky, 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. | |||
// | |||
// | |||
// HTTPConnectSocket.java together with HTTPConnectSocketFactory.java | |||
// implement an alternate way to connect to VNC servers via one or two | |||
// HTTP proxies supporting the HTTP CONNECT method. | |||
// | |||
import java.net.*; | |||
import java.io.*; | |||
class HTTPConnectSocket extends Socket { | |||
public HTTPConnectSocket(String host, int port, | |||
String proxyHost, int proxyPort) | |||
throws IOException { | |||
// Connect to the specified HTTP proxy | |||
super(proxyHost, proxyPort); | |||
// Send the CONNECT request | |||
getOutputStream().write(("CONNECT " + host + ":" + port + | |||
" HTTP/1.0\r\n\r\n").getBytes()); | |||
// Read the first line of the response | |||
DataInputStream is = new DataInputStream(getInputStream()); | |||
String str = is.readLine(); | |||
// Check the HTTP error code -- it should be "200" on success | |||
if (!str.startsWith("HTTP/1.0 200 ")) { | |||
if (str.startsWith("HTTP/1.0 ")) | |||
str = str.substring(9); | |||
throw new IOException("Proxy reports \"" + str + "\""); | |||
} | |||
// Success -- skip remaining HTTP headers | |||
do { | |||
str = is.readLine(); | |||
} while (str.length() != 0); | |||
} | |||
} | |||
@@ -0,0 +1,86 @@ | |||
// | |||
// Copyright (C) 2002 Constantin Kaplinsky, 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. | |||
// | |||
// | |||
// HTTPConnectSocketFactory.java together with HTTPConnectSocket.java | |||
// implement an alternate way to connect to VNC servers via one or two | |||
// HTTP proxies supporting the HTTP CONNECT method. | |||
// | |||
import java.applet.*; | |||
import java.net.*; | |||
import java.io.*; | |||
class HTTPConnectSocketFactory implements SocketFactory { | |||
public Socket createSocket(String host, int port, Applet applet) | |||
throws IOException { | |||
return createSocket(host, port, | |||
applet.getParameter("PROXYHOST1"), | |||
applet.getParameter("PROXYPORT1")); | |||
} | |||
public Socket createSocket(String host, int port, String[] args) | |||
throws IOException { | |||
return createSocket(host, port, | |||
readArg(args, "PROXYHOST1"), | |||
readArg(args, "PROXYPORT1")); | |||
} | |||
public Socket createSocket(String host, int port, | |||
String proxyHost, String proxyPortStr) | |||
throws IOException { | |||
int proxyPort = 0; | |||
if (proxyPortStr != null) { | |||
try { | |||
proxyPort = Integer.parseInt(proxyPortStr); | |||
} catch (NumberFormatException e) { } | |||
} | |||
if (proxyHost == null || proxyPort == 0) { | |||
System.out.println("Incomplete parameter list for HTTPConnectSocket"); | |||
return new Socket(host, port); | |||
} | |||
System.out.println("HTTP CONNECT via proxy " + proxyHost + | |||
" port " + proxyPort); | |||
HTTPConnectSocket s = | |||
new HTTPConnectSocket(host, port, proxyHost, proxyPort); | |||
return (Socket)s; | |||
} | |||
private String readArg(String[] args, String name) { | |||
for (int i = 0; i < args.length; i += 2) { | |||
if (args[i].equalsIgnoreCase(name)) { | |||
try { | |||
return args[i+1]; | |||
} catch (Exception e) { | |||
return null; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
} | |||
@@ -0,0 +1,177 @@ | |||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. | |||
* | |||
* This is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
// | |||
// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data | |||
// Representation). | |||
// | |||
abstract public class InStream { | |||
// check() ensures there is buffer data for at least one item of size | |||
// itemSize bytes. Returns the number of items in the buffer (up to a | |||
// maximum of nItems). | |||
public final int check(int itemSize, int nItems) throws Exception { | |||
if (ptr + itemSize * nItems > end) { | |||
if (ptr + itemSize > end) | |||
return overrun(itemSize, nItems); | |||
nItems = (end - ptr) / itemSize; | |||
} | |||
return nItems; | |||
} | |||
public final void check(int itemSize) throws Exception { | |||
if (ptr + itemSize > end) | |||
overrun(itemSize, 1); | |||
} | |||
// readU/SN() methods read unsigned and signed N-bit integers. | |||
public final int readS8() throws Exception { | |||
check(1); return b[ptr++]; | |||
} | |||
public final int readS16() throws Exception { | |||
check(2); int b0 = b[ptr++]; | |||
int b1 = b[ptr++] & 0xff; return b0 << 8 | b1; | |||
} | |||
public final int readS32() throws Exception { | |||
check(4); int b0 = b[ptr++]; | |||
int b1 = b[ptr++] & 0xff; | |||
int b2 = b[ptr++] & 0xff; | |||
int b3 = b[ptr++] & 0xff; | |||
return b0 << 24 | b1 << 16 | b2 << 8 | b3; | |||
} | |||
public final int readU8() throws Exception { | |||
return readS8() & 0xff; | |||
} | |||
public final int readU16() throws Exception { | |||
return readS16() & 0xffff; | |||
} | |||
public final int readU32() throws Exception { | |||
return readS32() & 0xffffffff; | |||
} | |||
// readString() reads a string - a U32 length followed by the data. | |||
public final String readString() throws Exception { | |||
int len = readU32(); | |||
if (len > maxStringLength) | |||
throw new Exception("InStream max string length exceeded"); | |||
char[] str = new char[len]; | |||
int i = 0; | |||
while (i < len) { | |||
int j = i + check(1, len - i); | |||
while (i < j) { | |||
str[i++] = (char)b[ptr++]; | |||
} | |||
} | |||
return new String(str); | |||
} | |||
// maxStringLength protects against allocating a huge buffer. Set it | |||
// higher if you need longer strings. | |||
public static int maxStringLength = 65535; | |||
public final void skip(int bytes) throws Exception { | |||
while (bytes > 0) { | |||
int n = check(1, bytes); | |||
ptr += n; | |||
bytes -= n; | |||
} | |||
} | |||
// readBytes() reads an exact number of bytes into an array at an offset. | |||
public void readBytes(byte[] data, int offset, int length) throws Exception { | |||
int offsetEnd = offset + length; | |||
while (offset < offsetEnd) { | |||
int n = check(1, offsetEnd - offset); | |||
System.arraycopy(b, ptr, data, offset, n); | |||
ptr += n; | |||
offset += n; | |||
} | |||
} | |||
// readOpaqueN() reads a quantity "without byte-swapping". Because java has | |||
// no byte-ordering, we just use big-endian. | |||
public final int readOpaque8() throws Exception { | |||
return readU8(); | |||
} | |||
public final int readOpaque16() throws Exception { | |||
return readU16(); | |||
} | |||
public final int readOpaque32() throws Exception { | |||
return readU32(); | |||
} | |||
public final int readOpaque24A() throws Exception { | |||
check(3); int b0 = b[ptr++]; | |||
int b1 = b[ptr++]; int b2 = b[ptr++]; | |||
return b0 << 24 | b1 << 16 | b2 << 8; | |||
} | |||
public final int readOpaque24B() throws Exception { | |||
check(3); int b0 = b[ptr++]; | |||
int b1 = b[ptr++]; int b2 = b[ptr++]; | |||
return b0 << 16 | b1 << 8 | b2; | |||
} | |||
// pos() returns the position in the stream. | |||
abstract public int pos(); | |||
// bytesAvailable() returns true if at least one byte can be read from the | |||
// stream without blocking. i.e. if false is returned then readU8() would | |||
// block. | |||
public boolean bytesAvailable() { return end != ptr; } | |||
// getbuf(), getptr(), getend() and setptr() are "dirty" methods which allow | |||
// you to manipulate the buffer directly. This is useful for a stream which | |||
// is a wrapper around an underlying stream. | |||
public final byte[] getbuf() { return b; } | |||
public final int getptr() { return ptr; } | |||
public final int getend() { return end; } | |||
public final void setptr(int p) { ptr = p; } | |||
// overrun() is implemented by a derived class to cope with buffer overrun. | |||
// It ensures there are at least itemSize bytes of buffer data. Returns | |||
// the number of items in the buffer (up to a maximum of nItems). itemSize | |||
// is supposed to be "small" (a few bytes). | |||
abstract protected int overrun(int itemSize, int nItems) throws Exception; | |||
protected InStream() {} | |||
protected byte[] b; | |||
protected int ptr; | |||
protected int end; | |||
} |
@@ -0,0 +1,340 @@ | |||
GNU GENERAL PUBLIC LICENSE | |||
Version 2, June 1991 | |||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |||
Everyone is permitted to copy and distribute verbatim copies | |||
of this license document, but changing it is not allowed. | |||
Preamble | |||
The licenses for most software are designed to take away your | |||
freedom to share and change it. By contrast, the GNU General Public | |||
License is intended to guarantee your freedom to share and change free | |||
software--to make sure the software is free for all its users. This | |||
General Public License applies to most of the Free Software | |||
Foundation's software and to any other program whose authors commit to | |||
using it. (Some other Free Software Foundation software is covered by | |||
the GNU Library General Public License instead.) You can apply it to | |||
your programs, too. | |||
When we speak of free software, we are referring to freedom, not | |||
price. Our General Public Licenses are designed to make sure that you | |||
have the freedom to distribute copies of free software (and charge for | |||
this service if you wish), that you receive source code or can get it | |||
if you want it, that you can change the software or use pieces of it | |||
in new free programs; and that you know you can do these things. | |||
To protect your rights, we need to make restrictions that forbid | |||
anyone to deny you these rights or to ask you to surrender the rights. | |||
These restrictions translate to certain responsibilities for you if you | |||
distribute copies of the software, or if you modify it. | |||
For example, if you distribute copies of such a program, whether | |||
gratis or for a fee, you must give the recipients all the rights that | |||
you have. You must make sure that they, too, receive or can get the | |||
source code. And you must show them these terms so they know their | |||
rights. | |||
We protect your rights with two steps: (1) copyright the software, and | |||
(2) offer you this license which gives you legal permission to copy, | |||
distribute and/or modify the software. | |||
Also, for each author's protection and ours, we want to make certain | |||
that everyone understands that there is no warranty for this free | |||
software. If the software is modified by someone else and passed on, we | |||
want its recipients to know that what they have is not the original, so | |||
that any problems introduced by others will not reflect on the original | |||
authors' reputations. | |||
Finally, any free program is threatened constantly by software | |||
patents. We wish to avoid the danger that redistributors of a free | |||
program will individually obtain patent licenses, in effect making the | |||
program proprietary. To prevent this, we have made it clear that any | |||
patent must be licensed for everyone's free use or not licensed at all. | |||
The precise terms and conditions for copying, distribution and | |||
modification follow. | |||
GNU GENERAL PUBLIC LICENSE | |||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||
0. This License applies to any program or other work which contains | |||
a notice placed by the copyright holder saying it may be distributed | |||
under the terms of this General Public License. The "Program", below, | |||
refers to any such program or work, and a "work based on the Program" | |||
means either the Program or any derivative work under copyright law: | |||
that is to say, a work containing the Program or a portion of it, | |||
either verbatim or with modifications and/or translated into another | |||
language. (Hereinafter, translation is included without limitation in | |||
the term "modification".) Each licensee is addressed as "you". | |||
Activities other than copying, distribution and modification are not | |||
covered by this License; they are outside its scope. The act of | |||
running the Program is not restricted, and the output from the Program | |||
is covered only if its contents constitute a work based on the | |||
Program (independent of having been made by running the Program). | |||
Whether that is true depends on what the Program does. | |||
1. You may copy and distribute verbatim copies of the Program's | |||
source code as you receive it, in any medium, provided that you | |||
conspicuously and appropriately publish on each copy an appropriate | |||
copyright notice and disclaimer of warranty; keep intact all the | |||
notices that refer to this License and to the absence of any warranty; | |||
and give any other recipients of the Program a copy of this License | |||
along with the Program. | |||
You may charge a fee for the physical act of transferring a copy, and | |||
you may at your option offer warranty protection in exchange for a fee. | |||
2. You may modify your copy or copies of the Program or any portion | |||
of it, thus forming a work based on the Program, and copy and | |||
distribute such modifications or work under the terms of Section 1 | |||
above, provided that you also meet all of these conditions: | |||
a) You must cause the modified files to carry prominent notices | |||
stating that you changed the files and the date of any change. | |||
b) You must cause any work that you distribute or publish, that in | |||
whole or in part contains or is derived from the Program or any | |||
part thereof, to be licensed as a whole at no charge to all third | |||
parties under the terms of this License. | |||
c) If the modified program normally reads commands interactively | |||
when run, you must cause it, when started running for such | |||
interactive use in the most ordinary way, to print or display an | |||
announcement including an appropriate copyright notice and a | |||
notice that there is no warranty (or else, saying that you provide | |||
a warranty) and that users may redistribute the program under | |||
these conditions, and telling the user how to view a copy of this | |||
License. (Exception: if the Program itself is interactive but | |||
does not normally print such an announcement, your work based on | |||
the Program is not required to print an announcement.) | |||
These requirements apply to the modified work as a whole. If | |||
identifiable sections of that work are not derived from the Program, | |||
and can be reasonably considered independent and separate works in | |||
themselves, then this License, and its terms, do not apply to those | |||
sections when you distribute them as separate works. But when you | |||
distribute the same sections as part of a whole which is a work based | |||
on the Program, the distribution of the whole must be on the terms of | |||
this License, whose permissions for other licensees extend to the | |||
entire whole, and thus to each and every part regardless of who wrote it. | |||
Thus, it is not the intent of this section to claim rights or contest | |||
your rights to work written entirely by you; rather, the intent is to | |||
exercise the right to control the distribution of derivative or | |||
collective works based on the Program. | |||
In addition, mere aggregation of another work not based on the Program | |||
with the Program (or with a work based on the Program) on a volume of | |||
a storage or distribution medium does not bring the other work under | |||
the scope of this License. | |||
3. You may copy and distribute the Program (or a work based on it, | |||
under Section 2) in object code or executable form under the terms of | |||
Sections 1 and 2 above provided that you also do one of the following: | |||
a) Accompany it with the complete corresponding machine-readable | |||
source code, which must be distributed under the terms of Sections | |||
1 and 2 above on a medium customarily used for software interchange; or, | |||
b) Accompany it with a written offer, valid for at least three | |||
years, to give any third party, for a charge no more than your | |||
cost of physically performing source distribution, a complete | |||
machine-readable copy of the corresponding source code, to be | |||
distributed under the terms of Sections 1 and 2 above on a medium | |||
customarily used for software interchange; or, | |||
c) Accompany it with the information you received as to the offer | |||
to distribute corresponding source code. (This alternative is | |||
allowed only for noncommercial distribution and only if you | |||
received the program in object code or executable form with such | |||
an offer, in accord with Subsection b above.) | |||
The source code for a work means the preferred form of the work for | |||
making modifications to it. For an executable work, complete source | |||
code means all the source code for all modules it contains, plus any | |||
associated interface definition files, plus the scripts used to | |||
control compilation and installation of the executable. However, as a | |||
special exception, the source code distributed need not include | |||
anything that is normally distributed (in either source or binary | |||
form) with the major components (compiler, kernel, and so on) of the | |||
operating system on which the executable runs, unless that component | |||
itself accompanies the executable. | |||
If distribution of executable or object code is made by offering | |||
access to copy from a designated place, then offering equivalent | |||
access to copy the source code from the same place counts as | |||
distribution of the source code, even though third parties are not | |||
compelled to copy the source along with the object code. | |||
4. You may not copy, modify, sublicense, or distribute the Program | |||
except as expressly provided under this License. Any attempt | |||
otherwise to copy, modify, sublicense or distribute the Program is | |||
void, and will automatically terminate your rights under this License. | |||
However, parties who have received copies, or rights, from you under | |||
this License will not have their licenses terminated so long as such | |||
parties remain in full compliance. | |||
5. You are not required to accept this License, since you have not | |||
signed it. However, nothing else grants you permission to modify or | |||
distribute the Program or its derivative works. These actions are | |||
prohibited by law if you do not accept this License. Therefore, by | |||
modifying or distributing the Program (or any work based on the | |||
Program), you indicate your acceptance of this License to do so, and | |||
all its terms and conditions for copying, distributing or modifying | |||
the Program or works based on it. | |||
6. Each time you redistribute the Program (or any work based on the | |||
Program), the recipient automatically receives a license from the | |||
original licensor to copy, distribute or modify the Program subject to | |||
these terms and conditions. You may not impose any further | |||
restrictions on the recipients' exercise of the rights granted herein. | |||
You are not responsible for enforcing compliance by third parties to | |||
this License. | |||
7. If, as a consequence of a court judgment or allegation of patent | |||
infringement or for any other reason (not limited to patent issues), | |||
conditions are imposed on you (whether by court order, agreement or | |||
otherwise) that contradict the conditions of this License, they do not | |||
excuse you from the conditions of this License. If you cannot | |||
distribute so as to satisfy simultaneously your obligations under this | |||
License and any other pertinent obligations, then as a consequence you | |||
may not distribute the Program at all. For example, if a patent | |||
license would not permit royalty-free redistribution of the Program by | |||
all those who receive copies directly or indirectly through you, then | |||
the only way you could satisfy both it and this License would be to | |||
refrain entirely from distribution of the Program. | |||
If any portion of this section is held invalid or unenforceable under | |||
any particular circumstance, the balance of the section is intended to | |||
apply and the section as a whole is intended to apply in other | |||
circumstances. | |||
It is not the purpose of this section to induce you to infringe any | |||
patents or other property right claims or to contest validity of any | |||
such claims; this section has the sole purpose of protecting the | |||
integrity of the free software distribution system, which is | |||
implemented by public license practices. Many people have made | |||
generous contributions to the wide range of software distributed | |||
through that system in reliance on consistent application of that | |||
system; it is up to the author/donor to decide if he or she is willing | |||
to distribute software through any other system and a licensee cannot | |||
impose that choice. | |||
This section is intended to make thoroughly clear what is believed to | |||
be a consequence of the rest of this License. | |||
8. If the distribution and/or use of the Program is restricted in | |||
certain countries either by patents or by copyrighted interfaces, the | |||
original copyright holder who places the Program under this License | |||
may add an explicit geographical distribution limitation excluding | |||
those countries, so that distribution is permitted only in or among | |||
countries not thus excluded. In such case, this License incorporates | |||
the limitation as if written in the body of this License. | |||
9. The Free Software Foundation may publish revised and/or new versions | |||
of the General Public License from time to time. Such new versions will | |||
be similar in spirit to the present version, but may differ in detail to | |||
address new problems or concerns. | |||
Each version is given a distinguishing version number. If the Program | |||
specifies a version number of this License which applies to it and "any | |||
later version", you have the option of following the terms and conditions | |||
either of that version or of any later version published by the Free | |||
Software Foundation. If the Program does not specify a version number of | |||
this License, you may choose any version ever published by the Free Software | |||
Foundation. | |||
10. If you wish to incorporate parts of the Program into other free | |||
programs whose distribution conditions are different, write to the author | |||
to ask for permission. For software which is copyrighted by the Free | |||
Software Foundation, write to the Free Software Foundation; we sometimes | |||
make exceptions for this. Our decision will be guided by the two goals | |||
of preserving the free status of all derivatives of our free software and | |||
of promoting the sharing and reuse of software generally. | |||
NO WARRANTY | |||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |||
REPAIR OR CORRECTION. | |||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGES. | |||
END OF TERMS AND CONDITIONS | |||
Appendix: How to Apply These Terms to Your New Programs | |||
If you develop a new program, and you want it to be of the greatest | |||
possible use to the public, the best way to achieve this is to make it | |||
free software which everyone can redistribute and change under these terms. | |||
To do so, attach the following notices to the program. It is safest | |||
to attach them to the start of each source file to most effectively | |||
convey the exclusion of warranty; and each file should have at least | |||
the "copyright" line and a pointer to where the full notice is found. | |||
<one line to give the program's name and a brief idea of what it does.> | |||
Copyright (C) 19yy <name of author> | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
USA. | |||
Also add information on how to contact you by electronic and paper mail. | |||
If the program is interactive, make it output a short notice like this | |||
when it starts in an interactive mode: | |||
Gnomovision version 69, Copyright (C) 19yy name of author | |||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
This is free software, and you are welcome to redistribute it | |||
under certain conditions; type `show c' for details. | |||
The hypothetical commands `show w' and `show c' should show the appropriate | |||
parts of the General Public License. Of course, the commands you use may | |||
be called something other than `show w' and `show c'; they could even be | |||
mouse-clicks or menu items--whatever suits your program. | |||
You should also get your employer (if you work as a programmer) or your | |||
school, if any, to sign a "copyright disclaimer" for the program, if | |||
necessary. Here is a sample; alter the names: | |||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |||
`Gnomovision' (which makes passes at compilers) written by James Hacker. | |||
<signature of Ty Coon>, 1 April 1989 | |||
Ty Coon, President of Vice | |||
This General Public License does not permit incorporating your program into | |||
proprietary programs. If your program is a subroutine library, you may | |||
consider it more useful to permit linking proprietary applications with the | |||
library. If this is what you want to do, use the GNU Library General | |||
Public License instead of this License. |
@@ -0,0 +1,2 @@ | |||
Manifest-Version: 1.0 | |||
Main-Class: VncViewer |
@@ -0,0 +1,47 @@ | |||
# | |||
# Making the VNC applet. | |||
# | |||
CP = cp | |||
JC = javac | |||
JCFLAGS = -target 1.1 | |||
JAR = jar | |||
ARCHIVE = VncViewer.jar | |||
MANIFEST = MANIFEST.MF | |||
PAGES = index.vnc | |||
INSTALL_DIR = /usr/local/vnc/classes | |||
CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \ | |||
VncCanvas2.class \ | |||
OptionsFrame.class ClipboardFrame.class ButtonPanel.class \ | |||
DesCipher.class CapabilityInfo.class CapsContainer.class \ | |||
RecordingFrame.class SessionRecorder.class \ | |||
SocketFactory.class HTTPConnectSocketFactory.class \ | |||
HTTPConnectSocket.class ReloginPanel.class \ | |||
InStream.class MemInStream.class ZlibInStream.class | |||
SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \ | |||
VncCanvas2.java \ | |||
OptionsFrame.java ClipboardFrame.java ButtonPanel.java \ | |||
DesCipher.java CapabilityInfo.java CapsContainer.java \ | |||
RecordingFrame.java SessionRecorder.java \ | |||
SocketFactory.java HTTPConnectSocketFactory.java \ | |||
HTTPConnectSocket.java ReloginPanel.java \ | |||
InStream.java MemInStream.java ZlibInStream.java | |||
all: $(CLASSES) $(ARCHIVE) | |||
$(CLASSES): $(SOURCES) | |||
$(JC) $(JCFLAGS) -O $(SOURCES) | |||
$(ARCHIVE): $(CLASSES) $(MANIFEST) | |||
$(JAR) cfm $(ARCHIVE) $(MANIFEST) $(CLASSES) | |||
install: $(CLASSES) $(ARCHIVE) | |||
$(CP) $(CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR) | |||
export:: $(CLASSES) $(ARCHIVE) $(PAGES) | |||
@$(ExportJavaClasses) | |||
clean:: | |||
$(RM) *.class *.jar |
@@ -0,0 +1,32 @@ | |||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. | |||
* | |||
* This is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
public class MemInStream extends InStream { | |||
public MemInStream(byte[] data, int offset, int len) { | |||
b = data; | |||
ptr = offset; | |||
end = offset + len; | |||
} | |||
public int pos() { return ptr; } | |||
protected int overrun(int itemSize, int nItems) throws Exception { | |||
throw new Exception("MemInStream overrun: end of stream"); | |||
} | |||
} |
@@ -0,0 +1,449 @@ | |||
// | |||
// 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", | |||
"Continuous updates", | |||
"Restricted colors", | |||
"Mouse buttons 2 and 3", | |||
"View only", | |||
"Scale remote cursor", | |||
"Share desktop", | |||
}; | |||
static String[][] values = { | |||
{ "Auto", "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight", "ZRLE" }, | |||
{ "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" }, | |||
{ "Yes", "No" }, | |||
{ "Normal", "Reversed" }, | |||
{ "Yes", "No" }, | |||
{ "No", "50%", "75%", "125%", "150%" }, | |||
{ "Yes", "No" }, | |||
}; | |||
final int | |||
encodingIndex = 0, | |||
compressLevelIndex = 1, | |||
jpegQualityIndex = 2, | |||
cursorUpdatesIndex = 3, | |||
useCopyRectIndex = 4, | |||
contUpdatesIndex = 5, | |||
eightBitColorsIndex = 6, | |||
mouseButtonIndex = 7, | |||
viewOnlyIndex = 8, | |||
scaleCursorIndex = 9, | |||
shareDesktopIndex = 10; | |||
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 preferredEncoding; | |||
int compressLevel; | |||
int jpegQuality; | |||
boolean useCopyRect; | |||
boolean continuousUpdates; | |||
boolean requestCursorUpdates; | |||
boolean ignoreCursorUpdates; | |||
boolean eightBitColors; | |||
boolean reverseMouseButtons2And3; | |||
boolean shareDesktop; | |||
boolean viewOnly; | |||
int scaleCursor; | |||
boolean autoScale; | |||
int scalingFactor; | |||
// | |||
// 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("Auto"); | |||
choices[compressLevelIndex].select("Default"); | |||
choices[jpegQualityIndex].select("6"); | |||
choices[cursorUpdatesIndex].select("Enable"); | |||
choices[useCopyRectIndex].select("Yes"); | |||
choices[contUpdatesIndex].select("No"); | |||
choices[eightBitColorsIndex].select("No"); | |||
choices[mouseButtonIndex].select("Normal"); | |||
choices[viewOnlyIndex].select("No"); | |||
choices[scaleCursorIndex].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); | |||
} | |||
} | |||
} | |||
} | |||
// FIXME: Provide some sort of GUI for "Scaling Factor". | |||
autoScale = false; | |||
scalingFactor = 100; | |||
String s = viewer.readParameter("Scaling Factor", false); | |||
if (s != null) { | |||
if (s.equalsIgnoreCase("Auto")) { | |||
autoScale = true; | |||
} else { | |||
// Remove the '%' char at the end of string if present. | |||
if (s.charAt(s.length() - 1) == '%') { | |||
s = s.substring(0, s.length() - 1); | |||
} | |||
// Convert to an integer. | |||
try { | |||
scalingFactor = Integer.parseInt(s); | |||
} | |||
catch (NumberFormatException e) { | |||
scalingFactor = 100; | |||
} | |||
// Make sure scalingFactor is in the range of [1..1000]. | |||
if (scalingFactor < 1) { | |||
scalingFactor = 1; | |||
} else if (scalingFactor > 1000) { | |||
scalingFactor = 1000; | |||
} | |||
} | |||
} | |||
// Make the booleans and encodings array correspond to the state of the GUI | |||
setEncodings(); | |||
setColorFormat(); | |||
setContinuousUpdates(); | |||
setOtherOptions(); | |||
} | |||
// | |||
// Disable the shareDesktop option | |||
// | |||
void disableShareDesktop() { | |||
labels[shareDesktopIndex].setEnabled(false); | |||
choices[shareDesktopIndex].setEnabled(false); | |||
} | |||
// | |||
// Disable the "Continuous updates" option. This method is called | |||
// when we figure out that the server does not support corresponding | |||
// protocol extensions. | |||
// | |||
void disableContUpdates() { | |||
labels[contUpdatesIndex].setEnabled(false); | |||
choices[contUpdatesIndex].setEnabled(false); | |||
choices[contUpdatesIndex].select("No"); | |||
continuousUpdates = false; | |||
} | |||
// | |||
// setEncodings looks at the encoding, compression level, JPEG | |||
// quality level, cursor shape updates and copyRect choices and sets | |||
// corresponding variables properly. Then it calls the VncViewer's | |||
// setEncodings method to send a SetEncodings message to the RFB | |||
// server. | |||
// | |||
void setEncodings() { | |||
useCopyRect = choices[useCopyRectIndex].getSelectedItem().equals("Yes"); | |||
preferredEncoding = RfbProto.EncodingRaw; | |||
boolean enableCompressLevel = false; | |||
boolean enableQualityLevel = 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("ZRLE")) { | |||
preferredEncoding = RfbProto.EncodingZRLE; | |||
} else if (choices[encodingIndex].getSelectedItem().equals("Zlib")) { | |||
preferredEncoding = RfbProto.EncodingZlib; | |||
enableCompressLevel = true; | |||
} else if (choices[encodingIndex].getSelectedItem().equals("Tight")) { | |||
preferredEncoding = RfbProto.EncodingTight; | |||
enableCompressLevel = true; | |||
enableQualityLevel = !eightBitColors; | |||
} else if (choices[encodingIndex].getSelectedItem().equals("Auto")) { | |||
preferredEncoding = -1; | |||
enableQualityLevel = !eightBitColors; | |||
} | |||
// Handle compression level setting. | |||
try { | |||
compressLevel = | |||
Integer.parseInt(choices[compressLevelIndex].getSelectedItem()); | |||
} | |||
catch (NumberFormatException e) { | |||
compressLevel = -1; | |||
} | |||
if (compressLevel < 1 || compressLevel > 9) { | |||
compressLevel = -1; | |||
} | |||
labels[compressLevelIndex].setEnabled(enableCompressLevel); | |||
choices[compressLevelIndex].setEnabled(enableCompressLevel); | |||
// Handle JPEG quality setting. | |||
try { | |||
jpegQuality = | |||
Integer.parseInt(choices[jpegQualityIndex].getSelectedItem()); | |||
} | |||
catch (NumberFormatException e) { | |||
jpegQuality = -1; | |||
} | |||
if (jpegQuality < 0 || jpegQuality > 9) { | |||
jpegQuality = -1; | |||
} | |||
labels[jpegQualityIndex].setEnabled(enableQualityLevel); | |||
choices[jpegQualityIndex].setEnabled(enableQualityLevel); | |||
// Request cursor shape updates if necessary. | |||
requestCursorUpdates = | |||
!choices[cursorUpdatesIndex].getSelectedItem().equals("Disable"); | |||
if (requestCursorUpdates) { | |||
ignoreCursorUpdates = | |||
choices[cursorUpdatesIndex].getSelectedItem().equals("Ignore"); | |||
} | |||
viewer.setEncodings(); | |||
} | |||
// | |||
// setColorFormat sets eightBitColors variable depending on the GUI | |||
// setting, causing switches between 8-bit and 24-bit colors mode if | |||
// necessary. | |||
// | |||
void setColorFormat() { | |||
eightBitColors = | |||
choices[eightBitColorsIndex].getSelectedItem().equals("Yes"); | |||
boolean enableJPEG = !eightBitColors && | |||
(choices[encodingIndex].getSelectedItem().equals("Tight") || | |||
choices[encodingIndex].getSelectedItem().equals("Auto")); | |||
labels[jpegQualityIndex].setEnabled(enableJPEG); | |||
choices[jpegQualityIndex].setEnabled(enableJPEG); | |||
} | |||
// | |||
// setContinuousUpdates sets continuousUpdates variable depending on | |||
// the GUI setting. VncViewer monitors the state of this variable and | |||
// send corresponding protocol messages to the server when necessary. | |||
// | |||
void setContinuousUpdates() { | |||
continuousUpdates = | |||
choices[contUpdatesIndex].getSelectedItem().equals("Yes"); | |||
} | |||
// | |||
// setOtherOptions looks at the "other" choices (ones that do not | |||
// cause sending any protocol messages) 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"); | |||
String scaleString = choices[scaleCursorIndex].getSelectedItem(); | |||
if (scaleString.endsWith("%")) | |||
scaleString = scaleString.substring(0, scaleString.length() - 1); | |||
try { | |||
scaleCursor = Integer.parseInt(scaleString); | |||
} | |||
catch (NumberFormatException e) { | |||
scaleCursor = 0; | |||
} | |||
if (scaleCursor < 10 || scaleCursor > 500) { | |||
scaleCursor = 0; | |||
} | |||
if (requestCursorUpdates && !ignoreCursorUpdates && !viewOnly) { | |||
labels[scaleCursorIndex].setEnabled(true); | |||
choices[scaleCursorIndex].setEnabled(true); | |||
} else { | |||
labels[scaleCursorIndex].setEnabled(false); | |||
choices[scaleCursorIndex].setEnabled(false); | |||
} | |||
if (viewer.vc != null) | |||
viewer.vc.createSoftCursor(); // update cursor scaling | |||
} | |||
// | |||
// 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(); | |||
if (source == choices[cursorUpdatesIndex]) { | |||
setOtherOptions(); // update scaleCursor state | |||
} | |||
} else if (source == choices[eightBitColorsIndex]) { | |||
setColorFormat(); | |||
} else if (source == choices[contUpdatesIndex]) { | |||
setContinuousUpdates(); | |||
} else if (source == choices[mouseButtonIndex] || | |||
source == choices[shareDesktopIndex] || | |||
source == choices[viewOnlyIndex] || | |||
source == choices[scaleCursorIndex]) { | |||
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) {} | |||
} |
@@ -0,0 +1,522 @@ | |||
TightVNC Java Viewer version 1.3.9 | |||
====================================================================== | |||
This distribution is based on the standard VNC source and includes new | |||
TightVNC-specific features and fixes, such as additional low-bandwidth | |||
optimizations, major GUI improvements, and more. | |||
Copyright (C) 1999 AT&T Laboratories Cambridge. | |||
Copyright (C) 2000 Tridia Corp. | |||
Copyright (C) 2002-2003 RealVNC Ltd. | |||
Copyright (C) 2001-2004 HorizonLive.com, Inc. | |||
Copyright (C) 2000-2007 Constantin Kaplinsky | |||
Copyright (C) 2000-2007 TightVNC Group | |||
All rights reserved. | |||
This software is distributed under the GNU General Public Licence as | |||
published by the Free Software Foundation. See the file LICENCE.TXT for the | |||
conditions under which this software is made available. TightVNC 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. | |||
Most JVM (Java Virtual Machine) implementations are able to use either a set | |||
of .class files, or the JAR archive. | |||
Installation | |||
============ | |||
There are three basic ways to use TightVNC Java viewer: | |||
1. Running applet as part of TightVNC server installation. | |||
Both the Unix and Windows versions of TightVNC servers include small | |||
built-in HTTP server which can serve Java viewer to Web clients. This | |||
enables easy Web access to the shared desktop without need to install | |||
any software on the client computer. Unix and Windows versions of | |||
TightVNC servers are different in the way they store the .class and .jar | |||
files: the Unix server (Xvnc) is able to serve any set of files present | |||
in a particular directory, while the Windows server (WinVNC) has all the | |||
.class and .jar files inside the WinVNC executable file. Therefore, for | |||
Xvnc, it's enough to copy the files into a correct directory, but for | |||
WinVNC, the server binaries should be rebuild if the built-in Java | |||
viewer should be updated. | |||
To install the Java viewer under Xvnc, 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 | |||
Also, make sure that the vncserver script is configured to point to the | |||
installation directory (see the Xvnc manual page for the description of | |||
the -httpd command-line option). | |||
2. Running applet hosted on a standalone Web server. | |||
Another possibility to use the Java viewer is to install it under a | |||
fully-functional HTTP server such as Apache or IIS. Obviously, this | |||
method requires running an HTTP server, and due to the Java security | |||
restrictions, it's also required that the server should be installed on | |||
the same machine which is running the TightVNC server. In this case, | |||
installation is simply copying the .class and .jar files into a | |||
directory that is under control of the HTTP server. Also, an HTML page | |||
should be created which will act as a the base document for the viewer | |||
applet (see an example named index.html in this distribution). | |||
NOTE: Provided index.html page is an example only. Before using that | |||
file, edit it with a text editor. See more information inside | |||
index.html. | |||
3. Running the viewer as a standalone application. | |||
Finally, the Java viewer can be executed locally on the client machine, | |||
but this method requires installation of either JRE (Java Runtime | |||
Environment) or JDK (Java Development Kit). If all the .class files are | |||
in the current directory, the Java viewer can be executed like this, | |||
from the command line: | |||
java VncViewer HOST vnchost PORT 5900 | |||
The HOST parameter is required, PORT defaults to 5900 if omitted, and | |||
there is a number of other optional parameters, see the Parameters | |||
section below. | |||
Parameters | |||
========== | |||
TightVNC Java viewer supports a number of parameters allowing you to | |||
customize its behavior. Most parameters directly correspond to the settings | |||
found in the Options window. However, there are parameters that do not | |||
correspond to those settings. For such parameters, you can see a note "no GUI | |||
equivalent", in the documentation below. | |||
Parameters can be specified in one of the two ways, depending on how the Java | |||
viewer is used: | |||
1. When the Java viewer is run as an applet (embedded within an HTML | |||
document), parameters should be specified in the <PARAM> HTML tags, | |||
within the appropriate <APPLET> section. Here is an example: | |||
<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar WIDTH=400 HEIGHT=300> | |||
<PARAM NAME="PORT" VALUE=5901> | |||
<PARAM NAME="Scaling factor" VALUE=50> | |||
</APPLET> | |||
2. When run as a standalone application, the Java viewer reads parameters | |||
from the command line. Command-line arguments should be specified in | |||
pairs -- first goes parameter name, then parameter value. Here is a | |||
command line example: | |||
java VncViewer HOST vnchost PORT 5901 "Scaling factor" 50 | |||
Both parameter names and their values are case-insensitive. The only | |||
exception is the "PASSWORD" parameter, as VNC passwords are case-sensitive. | |||
Here is the complete 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. It's not | |||
needed in the applet mode, 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. However, this parameter is | |||
required if the viewer is used as a standalone application. | |||
--> "PORT" (no GUI equivalent) | |||
Value: TCP port number on the VNC server. | |||
Default: 5900. | |||
This parameter specifies TCP port number for outgoing VNC connection. | |||
Note that this port is not the one used for HTTP connection from the | |||
browser, it is the port used for VNC/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 plain 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. | |||
--> "ENCPASSWORD" | |||
Value: encrypted session password in hex-ascii. | |||
Default: none, ask user. | |||
The same as the "PASSWORD" parameter but DES-encrypted using a fixed key. | |||
Its value should be represented in hex-ascii e.g. "494015f9a35e8b22". | |||
This parameter has higher priority over the "PASSWORD" parameter. DO NOT | |||
EVER USE THIS PARAMETER, unless you really know what you are doing. It's | |||
extremely dangerous from the security point of view, and encryption does | |||
not actually help here since the decryption key is always known. | |||
--> "Encoding" | |||
Values: "Auto", "Raw", "RRE", "CoRRE", "Hextile", "ZRLE", "Zlib", "Tight". | |||
Default: "Auto". | |||
The preferred encoding. If the value is "Auto", then the viewer will | |||
continuously estimate average network throughput and request encodings | |||
that are appropriate for current connection speed. "Hextile" is an | |||
encoding that was designed for fast networks, while "Tight" is better | |||
suited for low-bandwidth connections. From the other side, "Tight" | |||
decoder in the TightVNC Java viewer seems to be more efficient than | |||
"Hextile" decoder so it may be ok for fast networks too. "ZRLE" encoding | |||
is similar to "Tight", but it does not support JPEG compression and | |||
compression levels. Unlike "Tight" encoding, "ZRLE" is supported in | |||
recent versions of RealVNC products. Other encodings are not efficient | |||
and provided for compatibility reasons. | |||
--> "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". | |||
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. | |||
--> "Restricted colors" | |||
Values: "Yes", "No". | |||
Default: "No". | |||
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. | |||
--> "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. | |||
--> "Scale remote cursor" | |||
Values: "No", "50%", "75%", "125%", "150%". | |||
Default: "No". | |||
If a percentage value is specified, the remote cursor is reduced | |||
or enlarged accordingly. Scaling takes place only when "View only" | |||
is set to "No", and "Cursor shape updates" is set to "Enable". | |||
--> "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. | |||
--> "Scaling factor" (no GUI equivalent) | |||
Value: an integer in the range of [1..1000], or the string "auto". | |||
Default: "100". | |||
Scale local representation of the remote desktop. The value is | |||
interpreted as scaling factor in percents. The default value of 100% | |||
corresponds to the original framebuffer size. Values below 100 reduce | |||
image size, values above 100 enlarge the image proportionally. If the | |||
parameter is set to "auto", automatic scaling is performed. Auto-scaling | |||
tries to choose scaling factor such way that the whole remote framebuffer | |||
will fit on the local screen. Currently, auto-scaling is supported only | |||
when the remote desktop is shown in a separate frame (always true in the | |||
application mode, and also in the applet mode with "Open new window" | |||
parameter set to "yes"). | |||
--> "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. | |||
--> "Offer relogin" (no GUI equivalent, not applicable in the applet mode) | |||
Values: "Yes", "No". | |||
Default: "Yes". | |||
If set to "No", the buttons "Login again" and "Close window" won't be | |||
shown on disconnects or after an error has occured. | |||
--> "Show offline desktop" (no GUI equivalent) | |||
Values: "Yes", "No". | |||
Default: "No". | |||
If set to "Yes", the viewer would continue to display desktop even | |||
if the remote side has closed the connection. In this case, if the | |||
button panel is enabled, then the "Disconnect" button would be | |||
changed to "Hide desktop" after the connection is lost. | |||
--> "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: "0". | |||
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. | |||
--> "SocketFactory" (no GUI equivalent) | |||
Value: name of the class. | |||
Default: none. | |||
This option provides the way to define an alternate I/O implementation. | |||
The dynamically referenced class must implement a SocketFactory | |||
interface, and create a Socket, as configured by this parameter. See the | |||
source in SocketFactory.java. | |||
--> "DEBUG_XU" (no GUI equivalent) | |||
Value: non-negative integer. | |||
Default: 0. | |||
Debugging option that causes update statistics reset after the specified | |||
number of first framebuffer updates. This option was added to measure the | |||
performance of a VNC server. First few updates (especially the very first | |||
one) may be notably slower than others, and the viewer can exclude such | |||
updates from statistics. | |||
--> "DEBUG_CU" (no GUI equivalent) | |||
Value: non-negative integer. | |||
Default: 0. | |||
Debugging option that causes the viewer disconnect after the specified | |||
number of framebuffer updates. When used with the "DEBUG_XU" parameter, | |||
the number of updates specified in "DEBUG_XU" is not counted as part of | |||
this parameter's value. E.g. if "DEBUG_XU"=2 and "DEBUG_CU"=10, then the | |||
viewer will disconnect after 12 framebuffer updates: update statistics | |||
will be reset after first two updates, then collected for next 10 | |||
updates, then the viewer will disconnect automatically. If the value is | |||
0, the viewer will not disconnect automatically. This option was added to | |||
measure the performance of a VNC server. | |||
RECORDING VNC SESSIONS | |||
====================== | |||
Current version of the TightVNC Java viewer is able to record VNC (RFB) | |||
sessions in files for later playback. The data format in saved session files | |||
is compatible with the rfbproxy program written by Tim Waugh. Most important | |||
thing about session recording is that it's supported only if Java security | |||
manager allows access to local filesystem. Typically, it would not work for | |||
unsigned applets. To use this feature, either use TightVNC Java viewer as a | |||
standalone application (Java Runtime Environment or Java Development Kit | |||
should be installed), or as a signed applet. The code checks if it's possible | |||
to support session recording, and if everything's fine, the new "Record" | |||
button should appear in the button panel. Pressing this button opens new | |||
window which controls session recording. The GUI is pretty self-explained. | |||
Other important facts about session recording: | |||
--> All sessions are recorded in the 24-bit color format. If you use | |||
restricted colors (8-bit format), it will be temporarly switched to | |||
24-bit mode during session recording. | |||
--> All sessions are recorded with cursor shape updates turned off. This is | |||
necessary to represent remote cursor movements in recorded sessions. | |||
--> Closing and re-opening the recording control window does not affect the | |||
recording. It's not necessary to keep that window open during recording a | |||
session. | |||
--> Avoid using Zlib and ZRLE encodings when recording sessions. If you have | |||
started recording BEFORE opening a VNC session, then you are ok. But | |||
otherwise, all Zlib-encoded updates will be saved Raw-encoded (that is, | |||
without compression at all). The case with ZRLE is even worse -- ZRLE | |||
updates will not be saved at all, so the resulting session file may be | |||
corrupted. Zlib decoding depends on the pixel data received earlier, thus | |||
saving the data received from the server at an arbitrary moment is not | |||
sufficient to decompress it correctly. And there is no way to tell Zlib | |||
or ZRLE decoder to reset decompressor's state -- that's a limitation of | |||
these encoders. The viewer could re-compress raw pixel data again before | |||
saving Zlib-encoded sessions, but unfortunately Java API does not allow | |||
to flush zlib data streams making it impossible to save Zlib-encoded RFB | |||
pixel data without using native code. | |||
--> Usually, Tight encoding is the most suitable one for session recording, | |||
but some of the issues described above for the Zlib encoding affect the | |||
Tight encoding as well. Unlike Zlib sessions, Tight-encoded sessions are | |||
always saved Tight-encoded, but the viewer has to re-compress parts of | |||
data to synchronize encoder's and decoder's zlib streams. And, due to | |||
Java zlib API limitations, zlib streams' states have to be reset on each | |||
compressed rectangle, causing compression ratios to be lower than in the | |||
original VNC session. If you want to achieve the best possible | |||
performance, turn recording on BEFORE connecting to the VNC server, | |||
otherwise CPU usage and compression ratios may be notably less efficient. | |||
HINTS | |||
===== | |||
--> To refresh remote desktop in the view-only mode, press "r" or "R" | |||
on the keyboard. | |||
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. | |||
Visit the ACME Labs Java page for up-to-date versions of this and other | |||
fine Java utilities: http://www.acme.com/java/ |
@@ -0,0 +1,311 @@ | |||
// | |||
// Copyright (C) 2002 Constantin Kaplinsky. 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. | |||
// | |||
// | |||
// Recording frame. It allows to control recording RFB sessions into | |||
// FBS (FrameBuffer Stream) files. | |||
// | |||
import java.io.*; | |||
import java.awt.*; | |||
import java.awt.event.*; | |||
class RecordingFrame extends Frame | |||
implements WindowListener, ActionListener { | |||
boolean recording; | |||
TextField fnameField; | |||
Button browseButton; | |||
Label statusLabel; | |||
Button recordButton, nextButton, closeButton; | |||
VncViewer viewer; | |||
// | |||
// Check if current security manager allows to create a | |||
// RecordingFrame object. | |||
// | |||
public static boolean checkSecurity() { | |||
SecurityManager security = System.getSecurityManager(); | |||
if (security != null) { | |||
try { | |||
security.checkPropertyAccess("user.dir"); | |||
security.checkPropertyAccess("file.separator"); | |||
// Work around (rare) checkPropertyAccess bug | |||
System.getProperty("user.dir"); | |||
} catch (SecurityException e) { | |||
System.out.println("SecurityManager restricts session recording."); | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
// | |||
// Constructor. | |||
// | |||
RecordingFrame(VncViewer v) { | |||
super("TightVNC Session Recording"); | |||
viewer = v; | |||
// Determine initial filename for next saved session. | |||
// FIXME: Check SecurityManager. | |||
String fname = nextNewFilename(System.getProperty("user.dir") + | |||
System.getProperty("file.separator") + | |||
"vncsession.fbs"); | |||
// Construct new panel with file name field and "Browse" button. | |||
Panel fnamePanel = new Panel(); | |||
GridBagLayout fnameGridbag = new GridBagLayout(); | |||
fnamePanel.setLayout(fnameGridbag); | |||
GridBagConstraints fnameConstraints = new GridBagConstraints(); | |||
fnameConstraints.gridwidth = GridBagConstraints.RELATIVE; | |||
fnameConstraints.fill = GridBagConstraints.BOTH; | |||
fnameConstraints.weightx = 4.0; | |||
fnameField = new TextField(fname, 64); | |||
fnameGridbag.setConstraints(fnameField, fnameConstraints); | |||
fnamePanel.add(fnameField); | |||
fnameField.addActionListener(this); | |||
fnameConstraints.gridwidth = GridBagConstraints.REMAINDER; | |||
fnameConstraints.weightx = 1.0; | |||
browseButton = new Button("Browse"); | |||
fnameGridbag.setConstraints(browseButton, fnameConstraints); | |||
fnamePanel.add(browseButton); | |||
browseButton.addActionListener(this); | |||
// Construct the frame. | |||
GridBagLayout gridbag = new GridBagLayout(); | |||
setLayout(gridbag); | |||
GridBagConstraints gbc = new GridBagConstraints(); | |||
gbc.gridwidth = GridBagConstraints.REMAINDER; | |||
gbc.fill = GridBagConstraints.BOTH; | |||
gbc.weighty = 1.0; | |||
gbc.insets = new Insets(10, 0, 0, 0); | |||
Label helpLabel = | |||
new Label("File name to save next recorded session in:", Label.CENTER); | |||
gridbag.setConstraints(helpLabel, gbc); | |||
add(helpLabel); | |||
gbc.fill = GridBagConstraints.HORIZONTAL; | |||
gbc.weighty = 0.0; | |||
gbc.insets = new Insets(0, 0, 0, 0); | |||
gridbag.setConstraints(fnamePanel, gbc); | |||
add(fnamePanel); | |||
gbc.fill = GridBagConstraints.BOTH; | |||
gbc.weighty = 1.0; | |||
gbc.insets = new Insets(10, 0, 10, 0); | |||
statusLabel = new Label("", Label.CENTER); | |||
gridbag.setConstraints(statusLabel, gbc); | |||
add(statusLabel); | |||
gbc.fill = GridBagConstraints.HORIZONTAL; | |||
gbc.weightx = 1.0; | |||
gbc.weighty = 0.0; | |||
gbc.gridwidth = 1; | |||
gbc.insets = new Insets(0, 0, 0, 0); | |||
recordButton = new Button("Record"); | |||
gridbag.setConstraints(recordButton, gbc); | |||
add(recordButton); | |||
recordButton.addActionListener(this); | |||
nextButton = new Button("Next file"); | |||
gridbag.setConstraints(nextButton, gbc); | |||
add(nextButton); | |||
nextButton.addActionListener(this); | |||
closeButton = new Button("Close"); | |||
gridbag.setConstraints(closeButton, gbc); | |||
add(closeButton); | |||
closeButton.addActionListener(this); | |||
// Set correct text, font and color for the statusLabel. | |||
stopRecording(); | |||
pack(); | |||
addWindowListener(this); | |||
} | |||
// | |||
// If the given string ends with ".NNN" where NNN is a decimal | |||
// number, increase this number by one. Otherwise, append ".001" | |||
// to the given string. | |||
// | |||
protected String nextFilename(String fname) { | |||
int len = fname.length(); | |||
int suffixPos = len; | |||
int suffixNum = 1; | |||
if (len > 4 && fname.charAt(len - 4) == '.') { | |||
try { | |||
suffixNum = Integer.parseInt(fname.substring(len - 3, len)) + 1; | |||
suffixPos = len - 4; | |||
} catch (NumberFormatException e) { } | |||
} | |||
char[] zeroes = {'0', '0', '0'}; | |||
String suffix = String.valueOf(suffixNum); | |||
if (suffix.length() < 3) { | |||
suffix = new String(zeroes, 0, 3 - suffix.length()) + suffix; | |||
} | |||
return fname.substring(0, suffixPos) + '.' + suffix; | |||
} | |||
// | |||
// Find next name of a file which does not exist yet. | |||
// | |||
protected String nextNewFilename(String fname) { | |||
String newName = fname; | |||
File f; | |||
try { | |||
do { | |||
newName = nextFilename(newName); | |||
f = new File(newName); | |||
} while (f.exists()); | |||
} catch (SecurityException e) { } | |||
return newName; | |||
} | |||
// | |||
// Let the user choose a file name showing a FileDialog. | |||
// | |||
protected boolean browseFile() { | |||
File currentFile = new File(fnameField.getText()); | |||
FileDialog fd = | |||
new FileDialog(this, "Save next session as...", FileDialog.SAVE); | |||
fd.setDirectory(currentFile.getParent()); | |||
fd.setVisible(true); | |||
if (fd.getFile() != null) { | |||
String newDir = fd.getDirectory(); | |||
String sep = System.getProperty("file.separator"); | |||
if (newDir.length() > 0) { | |||
if (!sep.equals(newDir.substring(newDir.length() - sep.length()))) | |||
newDir += sep; | |||
} | |||
String newFname = newDir + fd.getFile(); | |||
if (newFname.equals(fnameField.getText())) { | |||
fnameField.setText(newFname); | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
// | |||
// Start recording. | |||
// | |||
public void startRecording() { | |||
statusLabel.setText("Status: Recording..."); | |||
statusLabel.setFont(new Font("Helvetica", Font.BOLD, 12)); | |||
statusLabel.setForeground(Color.red); | |||
recordButton.setLabel("Stop recording"); | |||
recording = true; | |||
viewer.setRecordingStatus(fnameField.getText()); | |||
} | |||
// | |||
// Stop recording. | |||
// | |||
public void stopRecording() { | |||
statusLabel.setText("Status: Not recording."); | |||
statusLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); | |||
statusLabel.setForeground(Color.black); | |||
recordButton.setLabel("Record"); | |||
recording = false; | |||
viewer.setRecordingStatus(null); | |||
} | |||
// | |||
// 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 windowDeactivated (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() == browseButton) { | |||
if (browseFile() && recording) | |||
startRecording(); | |||
} else if (evt.getSource() == recordButton) { | |||
if (!recording) { | |||
startRecording(); | |||
} else { | |||
stopRecording(); | |||
fnameField.setText(nextNewFilename(fnameField.getText())); | |||
} | |||
} else if (evt.getSource() == nextButton) { | |||
fnameField.setText(nextNewFilename(fnameField.getText())); | |||
if (recording) | |||
startRecording(); | |||
} else if (evt.getSource() == closeButton) { | |||
setVisible(false); | |||
} | |||
} | |||
} |
@@ -0,0 +1,65 @@ | |||
// | |||
// Copyright (C) 2002 Cendio Systems. All Rights Reserved. | |||
// Copyright (C) 2002 Constantin Kaplinsky. 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. | |||
// | |||
// | |||
// ReloginPanel class implements panel with a button for logging in again, | |||
// after fatal errors or disconnect | |||
// | |||
import java.awt.*; | |||
import java.awt.event.*; | |||
import java.applet.*; | |||
// | |||
// The panel which implements the Relogin button | |||
// | |||
class ReloginPanel extends Panel implements ActionListener { | |||
Button reloginButton; | |||
Button closeButton; | |||
VncViewer viewer; | |||
// | |||
// Constructor. | |||
// | |||
public ReloginPanel(VncViewer v) { | |||
viewer = v; | |||
setLayout(new FlowLayout(FlowLayout.CENTER)); | |||
reloginButton = new Button("Login again"); | |||
add(reloginButton); | |||
reloginButton.addActionListener(this); | |||
if (viewer.inSeparateFrame) { | |||
closeButton = new Button("Close window"); | |||
add(closeButton); | |||
closeButton.addActionListener(this); | |||
} | |||
} | |||
// | |||
// This method is called when a button is pressed. | |||
// | |||
public synchronized void actionPerformed(ActionEvent evt) { | |||
if (viewer.inSeparateFrame) | |||
viewer.vncFrame.dispose(); | |||
if (evt.getSource() == reloginButton) | |||
viewer.getAppletContext().showDocument(viewer.getDocumentBase()); | |||
} | |||
} |
@@ -0,0 +1,193 @@ | |||
// | |||
// Copyright (C) 2002 Constantin Kaplinsky. 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. | |||
// | |||
// | |||
// SessionRecorder is a class to write FBS (FrameBuffer Stream) files. | |||
// FBS files are used to save RFB sessions for later playback. | |||
// | |||
import java.io.*; | |||
class SessionRecorder { | |||
protected FileOutputStream f; | |||
protected DataOutputStream df; | |||
protected long startTime, lastTimeOffset; | |||
protected byte[] buffer; | |||
protected int bufferSize; | |||
protected int bufferBytes; | |||
public SessionRecorder(String name, int bufsize) throws IOException { | |||
f = new FileOutputStream(name); | |||
df = new DataOutputStream(f); | |||
startTime = System.currentTimeMillis(); | |||
lastTimeOffset = 0; | |||
bufferSize = bufsize; | |||
bufferBytes = 0; | |||
buffer = new byte[bufferSize]; | |||
} | |||
public SessionRecorder(String name) throws IOException { | |||
this(name, 65536); | |||
} | |||
// | |||
// Close the file, free resources. | |||
// | |||
public void close() throws IOException { | |||
try { | |||
flush(); | |||
} catch (IOException e) { | |||
} | |||
df = null; | |||
f.close(); | |||
f = null; | |||
buffer = null; | |||
} | |||
// | |||
// Write the FBS file header as defined in the rfbproxy utility. | |||
// | |||
public void writeHeader() throws IOException { | |||
df.write("FBS 001.000\n".getBytes()); | |||
} | |||
// | |||
// Write one byte. | |||
// | |||
public void writeByte(int b) throws IOException { | |||
prepareWriting(); | |||
buffer[bufferBytes++] = (byte)b; | |||
} | |||
// | |||
// Write 16-bit value, big-endian. | |||
// | |||
public void writeShortBE(int v) throws IOException { | |||
prepareWriting(); | |||
buffer[bufferBytes++] = (byte)(v >> 8); | |||
buffer[bufferBytes++] = (byte)v; | |||
} | |||
// | |||
// Write 32-bit value, big-endian. | |||
// | |||
public void writeIntBE(int v) throws IOException { | |||
prepareWriting(); | |||
buffer[bufferBytes] = (byte)(v >> 24); | |||
buffer[bufferBytes + 1] = (byte)(v >> 16); | |||
buffer[bufferBytes + 2] = (byte)(v >> 8); | |||
buffer[bufferBytes + 3] = (byte)v; | |||
bufferBytes += 4; | |||
} | |||
// | |||
// Write 16-bit value, little-endian. | |||
// | |||
public void writeShortLE(int v) throws IOException { | |||
prepareWriting(); | |||
buffer[bufferBytes++] = (byte)v; | |||
buffer[bufferBytes++] = (byte)(v >> 8); | |||
} | |||
// | |||
// Write 32-bit value, little-endian. | |||
// | |||
public void writeIntLE(int v) throws IOException { | |||
prepareWriting(); | |||
buffer[bufferBytes] = (byte)v; | |||
buffer[bufferBytes + 1] = (byte)(v >> 8); | |||
buffer[bufferBytes + 2] = (byte)(v >> 16); | |||
buffer[bufferBytes + 3] = (byte)(v >> 24); | |||
bufferBytes += 4; | |||
} | |||
// | |||
// Write byte arrays. | |||
// | |||
public void write(byte b[], int off, int len) throws IOException { | |||
prepareWriting(); | |||
while (len > 0) { | |||
if (bufferBytes > bufferSize - 4) | |||
flush(false); | |||
int partLen; | |||
if (bufferBytes + len > bufferSize) { | |||
partLen = bufferSize - bufferBytes; | |||
} else { | |||
partLen = len; | |||
} | |||
System.arraycopy(b, off, buffer, bufferBytes, partLen); | |||
bufferBytes += partLen; | |||
off += partLen; | |||
len -= partLen; | |||
} | |||
} | |||
public void write(byte b[]) throws IOException { | |||
write(b, 0, b.length); | |||
} | |||
// | |||
// Flush the output. This method saves buffered data in the | |||
// underlying file object adding data sizes and timestamps. If the | |||
// updateTimeOffset is set to false, then the current time offset | |||
// will not be changed for next write operation. | |||
// | |||
public void flush(boolean updateTimeOffset) throws IOException { | |||
if (bufferBytes > 0) { | |||
df.writeInt(bufferBytes); | |||
df.write(buffer, 0, (bufferBytes + 3) & 0x7FFFFFFC); | |||
df.writeInt((int)lastTimeOffset); | |||
bufferBytes = 0; | |||
if (updateTimeOffset) | |||
lastTimeOffset = -1; | |||
} | |||
} | |||
public void flush() throws IOException { | |||
flush(true); | |||
} | |||
// | |||
// Before writing any data, remember time offset and flush the | |||
// buffer before it becomes full. | |||
// | |||
protected void prepareWriting() throws IOException { | |||
if (lastTimeOffset == -1) | |||
lastTimeOffset = System.currentTimeMillis() - startTime; | |||
if (bufferBytes > bufferSize - 4) | |||
flush(false); | |||
} | |||
} | |||
@@ -0,0 +1,36 @@ | |||
// | |||
// 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. | |||
// | |||
// | |||
// SocketFactory.java describes an interface used to substitute the | |||
// standard Socket class by its alternative implementations. | |||
// | |||
import java.applet.*; | |||
import java.net.*; | |||
import java.io.*; | |||
public interface SocketFactory { | |||
public Socket createSocket(String host, int port, Applet applet) | |||
throws IOException; | |||
public Socket createSocket(String host, int port, String[] args) | |||
throws IOException; | |||
} |
@@ -0,0 +1,63 @@ | |||
// | |||
// Copyright (C) 2006 Constantin Kaplinsky. 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.io.*; | |||
// | |||
// VncCanvas2 is a special version of VncCanvas which may use Java 2 API. | |||
// | |||
class VncCanvas2 extends VncCanvas { | |||
public VncCanvas2(VncViewer v) throws IOException { | |||
super(v); | |||
disableFocusTraversalKeys(); | |||
} | |||
public VncCanvas2(VncViewer v, int maxWidth_, int maxHeight_) | |||
throws IOException { | |||
super(v, maxWidth_, maxHeight_); | |||
disableFocusTraversalKeys(); | |||
} | |||
public void paintScaledFrameBuffer(Graphics g) { | |||
Graphics2D g2d = (Graphics2D)g; | |||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, | |||
RenderingHints.VALUE_RENDER_QUALITY); | |||
g2d.drawImage(memImage, 0, 0, scaledWidth, scaledHeight, null); | |||
} | |||
// | |||
// Try to disable focus traversal keys (JVMs 1.4 and higher). | |||
// | |||
private void disableFocusTraversalKeys() { | |||
try { | |||
Class[] argClasses = { Boolean.TYPE }; | |||
java.lang.reflect.Method method = | |||
getClass().getMethod("setFocusTraversalKeysEnabled", argClasses); | |||
Object[] argObjects = { new Boolean(false) }; | |||
method.invoke(this, argObjects); | |||
} catch (Exception e) {} | |||
} | |||
} | |||
@@ -0,0 +1,111 @@ | |||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. | |||
* | |||
* This is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
// | |||
// A ZlibInStream reads from a zlib.io.InputStream | |||
// | |||
public class ZlibInStream extends InStream { | |||
static final int defaultBufSize = 16384; | |||
public ZlibInStream(int bufSize_) { | |||
bufSize = bufSize_; | |||
b = new byte[bufSize]; | |||
ptr = end = ptrOffset = 0; | |||
inflater = new java.util.zip.Inflater(); | |||
} | |||
public ZlibInStream() { this(defaultBufSize); } | |||
public void setUnderlying(InStream is, int bytesIn_) { | |||
underlying = is; | |||
bytesIn = bytesIn_; | |||
ptr = end = 0; | |||
} | |||
public void reset() throws Exception { | |||
ptr = end = 0; | |||
if (underlying == null) return; | |||
while (bytesIn > 0) { | |||
decompress(); | |||
end = 0; // throw away any data | |||
} | |||
underlying = null; | |||
} | |||
public int pos() { return ptrOffset + ptr; } | |||
protected int overrun(int itemSize, int nItems) throws Exception { | |||
if (itemSize > bufSize) | |||
throw new Exception("ZlibInStream overrun: max itemSize exceeded"); | |||
if (underlying == null) | |||
throw new Exception("ZlibInStream overrun: no underlying stream"); | |||
if (end - ptr != 0) | |||
System.arraycopy(b, ptr, b, 0, end - ptr); | |||
ptrOffset += ptr; | |||
end -= ptr; | |||
ptr = 0; | |||
while (end < itemSize) { | |||
decompress(); | |||
} | |||
if (itemSize * nItems > end) | |||
nItems = end / itemSize; | |||
return nItems; | |||
} | |||
// decompress() calls the decompressor once. Note that this won't | |||
// necessarily generate any output data - it may just consume some input | |||
// data. Returns false if wait is false and we would block on the underlying | |||
// stream. | |||
private void decompress() throws Exception { | |||
try { | |||
underlying.check(1); | |||
int avail_in = underlying.getend() - underlying.getptr(); | |||
if (avail_in > bytesIn) | |||
avail_in = bytesIn; | |||
if (inflater.needsInput()) { | |||
inflater.setInput(underlying.getbuf(), underlying.getptr(), avail_in); | |||
} | |||
int n = inflater.inflate(b, end, bufSize - end); | |||
end += n; | |||
if (inflater.needsInput()) { | |||
bytesIn -= avail_in; | |||
underlying.setptr(underlying.getptr() + avail_in); | |||
} | |||
} catch (java.util.zip.DataFormatException e) { | |||
throw new Exception("ZlibInStream: inflate failed"); | |||
} | |||
} | |||
private InStream underlying; | |||
private int bufSize; | |||
private int ptrOffset; | |||
private java.util.zip.Inflater inflater; | |||
private int bytesIn; | |||
} |
@@ -0,0 +1,29 @@ | |||
<!-- | |||
index.html - an example HTML page for TightVNC Java viewer applet, to be | |||
used with a standalone Web server running on the same machine where the | |||
TightVNC server is running. Before using this example, please MAKE SURE | |||
to check the following: | |||
* the value of the PORT parameter should be set correctly (normally, the | |||
port number is 5900 + display number); | |||
* the CODE and ARCHIVE attributes of the <APPLET> tag should point to | |||
the correct directory (this example assumes that this page is in the | |||
same directory with .jar and .class files); | |||
* the WIDTH and HEIGHT attributes of the <APPLET> tag correspond to the | |||
actual desktop size on the server (height should be increased to leave | |||
enough space for the button panel). | |||
--> | |||
<HTML> | |||
<TITLE> | |||
TightVNC desktop | |||
</TITLE> | |||
<APPLET CODE="VncViewer.class" ARCHIVE="VncViewer.jar" | |||
WIDTH="800" HEIGHT="632"> | |||
<PARAM NAME="PORT" VALUE="5901"> | |||
</APPLET> | |||
<BR> | |||
<A href="http://www.tightvnc.com/">TightVNC site</A> | |||
</HTML> |
@@ -0,0 +1,25 @@ | |||
<!-- | |||
index.vnc - default HTML page for TightVNC Java viewer applet, to be | |||
used with Xvnc. 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, | |||
PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated | |||
HTML page. | |||
NOTE: the $PARAMS variable is not supported by the standard VNC, so | |||
make sure you have TightVNC on the server side, if you're using this | |||
variable. | |||
--> | |||
<HTML> | |||
<TITLE> | |||
$USER's $DESKTOP desktop ($DISPLAY) | |||
</TITLE> | |||
<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar | |||
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT> | |||
<param name=PORT value=$PORT> | |||
$PARAMS | |||
</APPLET> | |||
<BR> | |||
<A href="http://www.tightvnc.com/">TightVNC site</A> | |||
</HTML> |