git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4203 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v1.0.90
@@ -38,13 +38,6 @@ class ButtonPanel extends Panel implements ActionListener { | |||
Button clipboardButton; | |||
Button ctrlAltDelButton; | |||
Button refreshButton; | |||
Button selectButton; | |||
Button videoFreezeButton; | |||
final String enableVideoFreezeLabel = "Ignore Video"; | |||
final String disableVideoFreezeLabel = "Enable Video"; | |||
final String selectEnterLabel = "Select Video Area"; | |||
final String selectLeaveLabel = "Hide Selection"; | |||
ButtonPanel(VncViewer v) { | |||
viewer = v; | |||
@@ -76,25 +69,6 @@ class ButtonPanel extends Panel implements ActionListener { | |||
refreshButton.addActionListener(this); | |||
} | |||
/** | |||
* Add video selection button to the ButtonPanel. | |||
*/ | |||
public void addSelectButton() { | |||
selectButton = new Button(selectEnterLabel); | |||
selectButton.setEnabled(false); | |||
add(selectButton); | |||
selectButton.addActionListener(this); | |||
} | |||
/** | |||
* Add video ignore button to the ButtonPanel. | |||
*/ | |||
public void addVideoFreezeButton() { | |||
videoFreezeButton = new Button(enableVideoFreezeLabel); | |||
add(videoFreezeButton); | |||
videoFreezeButton.addActionListener(this); | |||
} | |||
// | |||
// Enable buttons on successful connection. | |||
// | |||
@@ -103,9 +77,6 @@ class ButtonPanel extends Panel implements ActionListener { | |||
disconnectButton.setEnabled(true); | |||
clipboardButton.setEnabled(true); | |||
refreshButton.setEnabled(true); | |||
if (selectButton != null) { | |||
selectButton.setEnabled(true); | |||
} | |||
} | |||
// | |||
@@ -123,9 +94,6 @@ class ButtonPanel extends Panel implements ActionListener { | |||
clipboardButton.setEnabled(false); | |||
ctrlAltDelButton.setEnabled(false); | |||
refreshButton.setEnabled(false); | |||
if (selectButton != null) { | |||
selectButton.setEnabled(false); | |||
} | |||
} | |||
// | |||
@@ -156,32 +124,7 @@ class ButtonPanel extends Panel implements ActionListener { | |||
} else if (evt.getSource() == clipboardButton) { | |||
viewer.clipboard.setVisible(!viewer.clipboard.isVisible()); | |||
} else if (evt.getSource() == videoFreezeButton) { | |||
// | |||
// Send video freeze message to server and change caption of button | |||
// | |||
// | |||
// TODO: Move this code to another place. | |||
// | |||
boolean sendOk = true; | |||
boolean currentFreezeState = | |||
videoFreezeButton.getLabel().equals(disableVideoFreezeLabel); | |||
try { | |||
viewer.rfb.trySendVideoFreeze(!currentFreezeState); | |||
} catch (IOException ex) { | |||
sendOk = false; | |||
ex.printStackTrace(); | |||
} | |||
if (sendOk) { | |||
if (!currentFreezeState) { | |||
videoFreezeButton.setLabel(disableVideoFreezeLabel); | |||
} else { | |||
videoFreezeButton.setLabel(enableVideoFreezeLabel); | |||
} | |||
} | |||
} else if (evt.getSource() == ctrlAltDelButton) { | |||
try { | |||
final int modifiers = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; | |||
@@ -205,17 +148,6 @@ class ButtonPanel extends Panel implements ActionListener { | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} else if (selectButton != null && evt.getSource() == selectButton) { | |||
if (viewer.vc != null) { | |||
boolean isSelecting = viewer.vc.isInSelectionMode(); | |||
if (!isSelecting) { | |||
selectButton.setLabel(selectLeaveLabel); | |||
viewer.vc.enableSelection(true); | |||
} else { | |||
selectButton.setLabel(selectEnterLabel); | |||
viewer.vc.enableSelection(false); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -1,89 +0,0 @@ | |||
// | |||
// 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. | |||
// | |||
package com.tigervnc.vncviewer; | |||
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; | |||
} |
@@ -1,105 +0,0 @@ | |||
// | |||
// 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 | |||
// | |||
package com.tigervnc.vncviewer; | |||
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; | |||
} | |||
@@ -14,7 +14,7 @@ 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 \ | |||
DesCipher.class \ | |||
RecordingFrame.class SessionRecorder.class \ | |||
SocketFactory.class HTTPConnectSocketFactory.class \ | |||
HTTPConnectSocket.class ReloginPanel.class \ | |||
@@ -24,7 +24,7 @@ CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \ | |||
SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \ | |||
VncCanvas2.java \ | |||
OptionsFrame.java ClipboardFrame.java ButtonPanel.java \ | |||
DesCipher.java CapabilityInfo.java CapsContainer.java \ | |||
DesCipher.java \ | |||
RecordingFrame.java SessionRecorder.java \ | |||
SocketFactory.java HTTPConnectSocketFactory.java \ | |||
HTTPConnectSocket.java ReloginPanel.java \ |
@@ -41,7 +41,6 @@ class OptionsFrame extends Frame | |||
"JPEG image quality", | |||
"Cursor shape updates", | |||
"Use CopyRect", | |||
"Continuous updates", | |||
"Restricted colors", | |||
"Mouse buttons 2 and 3", | |||
"View only", | |||
@@ -57,7 +56,6 @@ class OptionsFrame extends Frame | |||
{ "Enable", "Ignore", "Disable" }, | |||
{ "Yes", "No" }, | |||
{ "Yes", "No" }, | |||
{ "Yes", "No" }, | |||
{ "Normal", "Reversed" }, | |||
{ "Yes", "No" }, | |||
{ "Auto", "1%", "5%", "10%", "20%", "25%", "50%", "75%", "100%"}, | |||
@@ -71,13 +69,12 @@ class OptionsFrame extends Frame | |||
jpegQualityIndex = 2, | |||
cursorUpdatesIndex = 3, | |||
useCopyRectIndex = 4, | |||
contUpdatesIndex = 5, | |||
eightBitColorsIndex = 6, | |||
mouseButtonIndex = 7, | |||
viewOnlyIndex = 8, | |||
scalingFactorIndex = 9, | |||
scaleCursorIndex = 10, | |||
shareDesktopIndex = 11; | |||
eightBitColorsIndex = 5, | |||
mouseButtonIndex = 6, | |||
viewOnlyIndex = 7, | |||
scalingFactorIndex = 8, | |||
scaleCursorIndex = 9, | |||
shareDesktopIndex = 10; | |||
Label[] labels = new Label[names.length]; | |||
Choice[] choices = new Choice[names.length]; | |||
@@ -93,7 +90,6 @@ class OptionsFrame extends Frame | |||
int compressLevel; | |||
int jpegQuality; | |||
boolean useCopyRect; | |||
boolean continuousUpdates; | |||
boolean requestCursorUpdates; | |||
boolean ignoreCursorUpdates; | |||
@@ -157,7 +153,6 @@ class OptionsFrame extends Frame | |||
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"); | |||
@@ -193,7 +188,6 @@ class OptionsFrame extends Frame | |||
setEncodings(); | |||
setColorFormat(); | |||
setContinuousUpdates(); | |||
setOtherOptions(); | |||
} | |||
@@ -243,21 +237,6 @@ class OptionsFrame extends Frame | |||
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 | |||
@@ -355,18 +334,6 @@ class OptionsFrame extends Frame | |||
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 | |||
@@ -433,10 +400,6 @@ class OptionsFrame extends Frame | |||
setColorFormat(); | |||
} else if (source == choices[contUpdatesIndex]) { | |||
setContinuousUpdates(); | |||
} else if (source == choices[mouseButtonIndex] || | |||
source == choices[shareDesktopIndex] || | |||
source == choices[viewOnlyIndex] || |
@@ -39,12 +39,6 @@ class RfbProto { | |||
versionMsg_3_7 = "RFB 003.007\n", | |||
versionMsg_3_8 = "RFB 003.008\n"; | |||
// Vendor signatures: standard VNC/RealVNC, TridiaVNC, and TightVNC | |||
final static String | |||
StandardVendor = "STDV", | |||
TridiaVncVendor = "TRDV", | |||
TightVncVendor = "TGHT"; | |||
// Security types | |||
final static int | |||
SecTypeInvalid = 0, | |||
@@ -60,22 +54,6 @@ class RfbProto { | |||
SecTypeX509Vnc = 261, | |||
SecTypeX509Plain = 262; | |||
// Supported tunneling types | |||
final static int | |||
NoTunneling = 0; | |||
final static String | |||
SigNoTunneling = "NOTUNNEL"; | |||
// Supported authentication types | |||
final static int | |||
AuthNone = 1, | |||
AuthVNC = 2, | |||
AuthUnixLogin = 129; | |||
final static String | |||
SigAuthNone = "NOAUTH__", | |||
SigAuthVNC = "VNCAUTH_", | |||
SigAuthUnixLogin = "ULGNAUTH"; | |||
// VNC authentication results | |||
final static int | |||
VncAuthOK = 0, | |||
@@ -89,12 +67,6 @@ class RfbProto { | |||
Bell = 2, | |||
ServerCutText = 3; | |||
// Non-standard server-to-client messages | |||
final static int | |||
EndOfContinuousUpdates = 150; | |||
final static String | |||
SigEndOfContinuousUpdates = "CUS_EOCU"; | |||
// Standard client-to-server messages | |||
final static int | |||
SetPixelFormat = 0, | |||
@@ -105,14 +77,6 @@ class RfbProto { | |||
PointerEvent = 5, | |||
ClientCutText = 6; | |||
// Non-standard client-to-server messages | |||
final static int EnableContinuousUpdates = 150; | |||
final static int VideoRectangleSelection = 151; | |||
final static int VideoFreeze = 152; | |||
final static String SigVideoFreeze = "VD_FREEZ"; | |||
final static String SigEnableContinuousUpdates = "CUC_ENCU"; | |||
final static String SigVideoRectangleSelection = "VRECTSEL"; | |||
// Supported encodings and pseudo-encodings | |||
final static int | |||
EncodingRaw = 0, | |||
@@ -130,22 +94,6 @@ class RfbProto { | |||
EncodingPointerPos = 0xFFFFFF18, | |||
EncodingLastRect = 0xFFFFFF20, | |||
EncodingNewFBSize = 0xFFFFFF21; | |||
final static String | |||
SigEncodingRaw = "RAW_____", | |||
SigEncodingCopyRect = "COPYRECT", | |||
SigEncodingRRE = "RRE_____", | |||
SigEncodingCoRRE = "CORRE___", | |||
SigEncodingHextile = "HEXTILE_", | |||
SigEncodingZlib = "ZLIB____", | |||
SigEncodingTight = "TIGHT___", | |||
SigEncodingZRLE = "ZRLE____", | |||
SigEncodingCompressLevel0 = "COMPRLVL", | |||
SigEncodingQualityLevel0 = "JPEGQLVL", | |||
SigEncodingXCursor = "X11CURSR", | |||
SigEncodingRichCursor = "RCHCURSR", | |||
SigEncodingPointerPos = "POINTPOS", | |||
SigEncodingLastRect = "LASTRECT", | |||
SigEncodingNewFBSize = "NEWFBSIZ"; | |||
final static int MaxNormalEncoding = 255; | |||
@@ -215,20 +163,6 @@ class RfbProto { | |||
// Protocol version and TightVNC-specific protocol options. | |||
int serverMajor, serverMinor; | |||
int clientMajor, clientMinor; | |||
boolean protocolTightVNC; | |||
CapsContainer tunnelCaps, authCaps; | |||
CapsContainer serverMsgCaps, clientMsgCaps; | |||
CapsContainer encodingCaps; | |||
// "Continuous updates" is a TightVNC-specific feature that allows | |||
// receiving framebuffer updates continuously, without sending update | |||
// requests. The variables below track the state of this feature. | |||
// Initially, continuous updates are disabled. They can be enabled | |||
// by calling tryEnableContinuousUpdates() method, and only if this | |||
// feature is supported by the server. To disable continuous updates, | |||
// tryDisableContinuousUpdates() should be called. | |||
private boolean continuousUpdatesActive = false; | |||
private boolean continuousUpdatesEnding = false; | |||
// If true, informs that the RFB socket was closed. | |||
private boolean closed; | |||
@@ -331,8 +265,6 @@ class RfbProto { | |||
clientMinor = 3; | |||
os.write(versionMsg_3_3.getBytes()); | |||
} | |||
protocolTightVNC = false; | |||
initCapabilities(); | |||
} | |||
@@ -380,17 +312,6 @@ class RfbProto { | |||
byte[] secTypes = new byte[nSecTypes]; | |||
readFully(secTypes); | |||
/* | |||
// Find out if the server supports TightVNC protocol extensions | |||
for (int i = 0; i < nSecTypes; i++) { | |||
if (secTypes[i] == SecTypeTight) { | |||
protocolTightVNC = true; | |||
os.write(SecTypeTight); | |||
return SecTypeTight; | |||
} | |||
} | |||
*/ | |||
// Find first supported security type. | |||
for (int i = 0; i < nSecTypes; i++) { | |||
if (secTypes[i] == SecTypeNone || secTypes[i] == SecTypeVncAuth | |||
@@ -540,122 +461,6 @@ class RfbProto { | |||
throw new Exception(new String(reason)); | |||
} | |||
// | |||
// Initialize capability lists (TightVNC protocol extensions). | |||
// | |||
void initCapabilities() { | |||
tunnelCaps = new CapsContainer(); | |||
authCaps = new CapsContainer(); | |||
serverMsgCaps = new CapsContainer(); | |||
clientMsgCaps = new CapsContainer(); | |||
encodingCaps = new CapsContainer(); | |||
// Supported authentication methods | |||
authCaps.add(AuthNone, StandardVendor, SigAuthNone, | |||
"No authentication"); | |||
authCaps.add(AuthVNC, StandardVendor, SigAuthVNC, | |||
"Standard VNC password authentication"); | |||
// Supported non-standard server-to-client messages | |||
serverMsgCaps.add(EndOfContinuousUpdates, TightVncVendor, | |||
SigEndOfContinuousUpdates, | |||
"End of continuous updates notification"); | |||
// Supported non-standard client-to-server messages | |||
clientMsgCaps.add(EnableContinuousUpdates, TightVncVendor, | |||
SigEnableContinuousUpdates, | |||
"Enable/disable continuous updates"); | |||
clientMsgCaps.add(VideoRectangleSelection, TightVncVendor, | |||
SigVideoRectangleSelection, | |||
"Select a rectangle to be treated as video"); | |||
clientMsgCaps.add(VideoFreeze, TightVncVendor, | |||
SigVideoFreeze, | |||
"Disable/enable video rectangle"); | |||
// Supported encoding types | |||
encodingCaps.add(EncodingCopyRect, StandardVendor, | |||
SigEncodingCopyRect, "Standard CopyRect encoding"); | |||
encodingCaps.add(EncodingRRE, StandardVendor, | |||
SigEncodingRRE, "Standard RRE encoding"); | |||
encodingCaps.add(EncodingCoRRE, StandardVendor, | |||
SigEncodingCoRRE, "Standard CoRRE encoding"); | |||
encodingCaps.add(EncodingHextile, StandardVendor, | |||
SigEncodingHextile, "Standard Hextile encoding"); | |||
encodingCaps.add(EncodingZRLE, StandardVendor, | |||
SigEncodingZRLE, "Standard ZRLE encoding"); | |||
encodingCaps.add(EncodingZlib, TridiaVncVendor, | |||
SigEncodingZlib, "Zlib encoding"); | |||
encodingCaps.add(EncodingTight, TightVncVendor, | |||
SigEncodingTight, "Tight encoding"); | |||
// Supported pseudo-encoding types | |||
encodingCaps.add(EncodingCompressLevel0, TightVncVendor, | |||
SigEncodingCompressLevel0, "Compression level"); | |||
encodingCaps.add(EncodingQualityLevel0, TightVncVendor, | |||
SigEncodingQualityLevel0, "JPEG quality level"); | |||
encodingCaps.add(EncodingXCursor, TightVncVendor, | |||
SigEncodingXCursor, "X-style cursor shape update"); | |||
encodingCaps.add(EncodingRichCursor, TightVncVendor, | |||
SigEncodingRichCursor, "Rich-color cursor shape update"); | |||
encodingCaps.add(EncodingPointerPos, TightVncVendor, | |||
SigEncodingPointerPos, "Pointer position update"); | |||
encodingCaps.add(EncodingLastRect, TightVncVendor, | |||
SigEncodingLastRect, "LastRect protocol extension"); | |||
encodingCaps.add(EncodingNewFBSize, TightVncVendor, | |||
SigEncodingNewFBSize, "Framebuffer size change"); | |||
} | |||
// | |||
// Setup tunneling (TightVNC protocol extensions) | |||
// | |||
void setupTunneling() throws IOException { | |||
int nTunnelTypes = readU32(); | |||
if (nTunnelTypes != 0) { | |||
readCapabilityList(tunnelCaps, nTunnelTypes); | |||
// We don't support tunneling yet. | |||
writeInt(NoTunneling); | |||
} | |||
} | |||
// | |||
// Negotiate authentication scheme (TightVNC protocol extensions) | |||
// | |||
int negotiateAuthenticationTight() throws Exception { | |||
int nAuthTypes = readU32(); | |||
if (nAuthTypes == 0) | |||
return AuthNone; | |||
readCapabilityList(authCaps, nAuthTypes); | |||
for (int i = 0; i < authCaps.numEnabled(); i++) { | |||
int authType = authCaps.getByOrder(i); | |||
if (authType == AuthNone || authType == AuthVNC) { | |||
writeInt(authType); | |||
return authType; | |||
} | |||
} | |||
throw new Exception("No suitable authentication scheme found"); | |||
} | |||
// | |||
// Read a capability list (TightVNC protocol extensions) | |||
// | |||
void readCapabilityList(CapsContainer caps, int count) throws IOException { | |||
int code; | |||
byte[] vendor = new byte[4]; | |||
byte[] name = new byte[8]; | |||
for (int i = 0; i < count; i++) { | |||
code = readU32(); | |||
readFully(vendor); | |||
readFully(name); | |||
caps.enable(new CapabilityInfo(code, vendor, name)); | |||
} | |||
} | |||
// | |||
// Write a 32-bit integer into the output stream. | |||
// | |||
@@ -712,22 +517,6 @@ class RfbProto { | |||
byte[] name = new byte[nameLength]; | |||
readFully(name); | |||
desktopName = new String(name); | |||
// Read interaction capabilities (TightVNC protocol extensions) | |||
if (protocolTightVNC) { | |||
int nServerMessageTypes = readU16(); | |||
int nClientMessageTypes = readU16(); | |||
int nEncodingTypes = readU16(); | |||
readU16(); | |||
readCapabilityList(serverMsgCaps, nServerMessageTypes); | |||
readCapabilityList(clientMsgCaps, nClientMessageTypes); | |||
readCapabilityList(encodingCaps, nEncodingTypes); | |||
} | |||
if (!clientMsgCaps.isEnabled(EnableContinuousUpdates)) { | |||
viewer.options.disableContUpdates(); | |||
} | |||
inNormalProtocol = true; | |||
} | |||
@@ -1316,164 +1105,6 @@ class RfbProto { | |||
} | |||
// | |||
// Enable continuous updates for the specified area of the screen (but | |||
// only if EnableContinuousUpdates message is supported by the server). | |||
// | |||
void tryEnableContinuousUpdates(int x, int y, int w, int h) | |||
throws IOException | |||
{ | |||
if (!clientMsgCaps.isEnabled(EnableContinuousUpdates)) { | |||
System.out.println("Continuous updates not supported by the server"); | |||
return; | |||
} | |||
if (continuousUpdatesActive) { | |||
System.out.println("Continuous updates already active"); | |||
return; | |||
} | |||
byte[] b = new byte[10]; | |||
b[0] = (byte) EnableContinuousUpdates; | |||
b[1] = (byte) 1; // enable | |||
b[2] = (byte) ((x >> 8) & 0xff); | |||
b[3] = (byte) (x & 0xff); | |||
b[4] = (byte) ((y >> 8) & 0xff); | |||
b[5] = (byte) (y & 0xff); | |||
b[6] = (byte) ((w >> 8) & 0xff); | |||
b[7] = (byte) (w & 0xff); | |||
b[8] = (byte) ((h >> 8) & 0xff); | |||
b[9] = (byte) (h & 0xff); | |||
os.write(b); | |||
continuousUpdatesActive = true; | |||
System.out.println("Continuous updates activated"); | |||
} | |||
// | |||
// Disable continuous updates (only if EnableContinuousUpdates message | |||
// is supported by the server). | |||
// | |||
void tryDisableContinuousUpdates() throws IOException | |||
{ | |||
if (!clientMsgCaps.isEnabled(EnableContinuousUpdates)) { | |||
System.out.println("Continuous updates not supported by the server"); | |||
return; | |||
} | |||
if (!continuousUpdatesActive) { | |||
System.out.println("Continuous updates already disabled"); | |||
return; | |||
} | |||
if (continuousUpdatesEnding) | |||
return; | |||
byte[] b = { (byte)EnableContinuousUpdates, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | |||
os.write(b); | |||
if (!serverMsgCaps.isEnabled(EndOfContinuousUpdates)) { | |||
// If the server did not advertise support for the | |||
// EndOfContinuousUpdates message (should not normally happen | |||
// when EnableContinuousUpdates is supported), then we clear | |||
// 'continuousUpdatesActive' variable immediately. Normally, | |||
// it will be reset on receiving EndOfContinuousUpdates message | |||
// from the server. | |||
continuousUpdatesActive = false; | |||
} else { | |||
// Indicate that we are waiting for EndOfContinuousUpdates. | |||
continuousUpdatesEnding = true; | |||
} | |||
} | |||
// | |||
// Process EndOfContinuousUpdates message received from the server. | |||
// | |||
void endOfContinuousUpdates() | |||
{ | |||
continuousUpdatesActive = false; | |||
continuousUpdatesEnding = false; | |||
} | |||
// | |||
// Check if continuous updates are in effect. | |||
// | |||
boolean continuousUpdatesAreActive() | |||
{ | |||
return continuousUpdatesActive; | |||
} | |||
/** | |||
* Send a rectangle selection to be treated as video by the server (but | |||
* only if VideoRectangleSelection message is supported by the server). | |||
* @param rect specifies coordinates and size of the rectangule. | |||
* @throws java.io.IOException | |||
*/ | |||
void trySendVideoSelection(Rectangle rect) throws IOException | |||
{ | |||
if (!clientMsgCaps.isEnabled(VideoRectangleSelection)) { | |||
System.out.println("Video area selection is not supported by the server"); | |||
return; | |||
} | |||
// Send zero coordinates if the rectangle is empty. | |||
if (rect.isEmpty()) { | |||
rect = new Rectangle(); | |||
} | |||
int x = rect.x; | |||
int y = rect.y; | |||
int w = rect.width; | |||
int h = rect.height; | |||
byte[] b = new byte[10]; | |||
b[0] = (byte) VideoRectangleSelection; | |||
b[1] = (byte) 0; // reserved | |||
b[2] = (byte) ((x >> 8) & 0xff); | |||
b[3] = (byte) (x & 0xff); | |||
b[4] = (byte) ((y >> 8) & 0xff); | |||
b[5] = (byte) (y & 0xff); | |||
b[6] = (byte) ((w >> 8) & 0xff); | |||
b[7] = (byte) (w & 0xff); | |||
b[8] = (byte) ((h >> 8) & 0xff); | |||
b[9] = (byte) (h & 0xff); | |||
os.write(b); | |||
System.out.println("Video rectangle selection message sent"); | |||
} | |||
void trySendVideoFreeze(boolean freeze) throws IOException | |||
{ | |||
if (!clientMsgCaps.isEnabled(VideoFreeze)) { | |||
System.out.println("Video freeze is not supported by the server"); | |||
return; | |||
} | |||
byte[] b = new byte[2]; | |||
byte fb = 0; | |||
if (freeze) { | |||
fb = 1; | |||
} | |||
b[0] = (byte) VideoFreeze; | |||
b[1] = (byte) fb; | |||
os.write(b); | |||
System.out.println("Video freeze selection message sent"); | |||
} | |||
public void startTiming() { | |||
timing = true; | |||
@@ -164,7 +164,6 @@ class VncCanvas extends Canvas | |||
} | |||
setPixelFormat(); | |||
resetSelection(); | |||
inputEnabled = false; | |||
if (!viewer.options.viewOnly) | |||
@@ -224,17 +223,6 @@ class VncCanvas extends Canvas | |||
g.drawImage(softCursor, x0, y0, null); | |||
} | |||
} | |||
if (isInSelectionMode()) { | |||
Rectangle r = getSelection(true); | |||
if (r.width > 0 && r.height > 0) { | |||
// Don't forget to correct the coordinates for the right and bottom | |||
// borders, so that the borders are the part of the selection. | |||
r.width -= 1; | |||
r.height -= 1; | |||
g.setXORMode(Color.yellow); | |||
g.drawRect(r.x, r.y, r.width, r.height); | |||
} | |||
} | |||
} | |||
public void paintScaledFrameBuffer(Graphics g) { | |||
@@ -437,11 +425,6 @@ class VncCanvas extends Canvas | |||
rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, | |||
rfb.framebufferHeight, false); | |||
if (viewer.options.continuousUpdates) { | |||
rfb.tryEnableContinuousUpdates(0, 0, rfb.framebufferWidth, | |||
rfb.framebufferHeight); | |||
} | |||
resetStats(); | |||
boolean statsRestarted = false; | |||
@@ -578,36 +561,15 @@ class VncCanvas extends Canvas | |||
// format should be changed. | |||
if (viewer.options.eightBitColors != (bytesPixel == 1)) { | |||
// Pixel format should be changed. | |||
if (!rfb.continuousUpdatesAreActive()) { | |||
// Continuous updates are not used. In this case, we just | |||
// set new pixel format and request full update. | |||
setPixelFormat(); | |||
fullUpdateNeeded = true; | |||
} else { | |||
// Otherwise, disable continuous updates first. Pixel | |||
// format will be set later when we are sure that there | |||
// will be no unsolicited framebuffer updates. | |||
rfb.tryDisableContinuousUpdates(); | |||
break; // skip the code below | |||
} | |||
setPixelFormat(); | |||
fullUpdateNeeded = true; | |||
} | |||
// Enable/disable continuous updates to reflect the GUI setting. | |||
boolean enable = viewer.options.continuousUpdates; | |||
if (enable != rfb.continuousUpdatesAreActive()) { | |||
if (enable) { | |||
rfb.tryEnableContinuousUpdates(0, 0, rfb.framebufferWidth, | |||
rfb.framebufferHeight); | |||
} else { | |||
rfb.tryDisableContinuousUpdates(); | |||
} | |||
} | |||
// Finally, request framebuffer update if needed. | |||
if (fullUpdateNeeded) { | |||
rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, | |||
rfb.framebufferHeight, false); | |||
} else if (!rfb.continuousUpdatesAreActive()) { | |||
} else { | |||
rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, | |||
rfb.framebufferHeight, true); | |||
} | |||
@@ -626,25 +588,6 @@ class VncCanvas extends Canvas | |||
viewer.clipboard.setCutText(s); | |||
break; | |||
case RfbProto.EndOfContinuousUpdates: | |||
if (rfb.continuousUpdatesAreActive()) { | |||
rfb.endOfContinuousUpdates(); | |||
// Change pixel format if such change was pending. Note that we | |||
// could not change pixel format while continuous updates were | |||
// in effect. | |||
boolean incremental = true; | |||
if (viewer.options.eightBitColors != (bytesPixel == 1)) { | |||
setPixelFormat(); | |||
incremental = false; | |||
} | |||
// From this point, we ask for updates explicitly. | |||
rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, | |||
rfb.framebufferHeight, | |||
incremental); | |||
} | |||
break; | |||
default: | |||
throw new Exception("Unknown RFB message type " + msgType); | |||
} | |||
@@ -840,21 +783,17 @@ class VncCanvas extends Canvas | |||
private void processLocalMouseEvent(MouseEvent evt, boolean moved) { | |||
if (viewer.rfb != null && rfb.inNormalProtocol) { | |||
if (!inSelectionMode) { | |||
if (inputEnabled) { | |||
// If mouse not moved, but it's click event then | |||
// send it to server immideanlty. | |||
// Else, it's mouse movement - we can send it in | |||
// our thread later. | |||
if (!moved) { | |||
sendMouseEvent(evt, moved); | |||
} else { | |||
mouseEvent = evt; | |||
needToSendMouseEvent = true; | |||
} | |||
if (inputEnabled) { | |||
// If mouse not moved, but it's click event then | |||
// send it to server immideanlty. | |||
// Else, it's mouse movement - we can send it in | |||
// our thread later. | |||
if (!moved) { | |||
sendMouseEvent(evt, moved); | |||
} else { | |||
mouseEvent = evt; | |||
needToSendMouseEvent = true; | |||
} | |||
} else { | |||
handleSelectionMouseEvent(evt); | |||
} | |||
} | |||
} | |||
@@ -1032,7 +971,7 @@ class VncCanvas extends Canvas | |||
rfb.readFully(maskBuf); | |||
// Decode pixel data into softCursorPixels[]. | |||
byte pixByte, maskByte; | |||
byte maskByte; | |||
int x, y, n, result; | |||
int i = 0; | |||
for (y = 0; y < height; y++) { | |||
@@ -1150,166 +1089,4 @@ class VncCanvas extends Canvas | |||
cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); | |||
} | |||
} | |||
////////////////////////////////////////////////////////////////// | |||
// | |||
// Support for selecting a rectangular video area. | |||
// | |||
/** This flag is false in normal operation, and true in the selection mode. */ | |||
private boolean inSelectionMode; | |||
/** The point where the selection was started. */ | |||
private Point selectionStart; | |||
/** The second point of the selection. */ | |||
private Point selectionEnd; | |||
/** | |||
* We change cursor when enabling the selection mode. In this variable, we | |||
* save the original cursor so we can restore it on returning to the normal | |||
* mode. | |||
*/ | |||
private Cursor savedCursor; | |||
/** | |||
* Initialize selection-related varibles. | |||
*/ | |||
private synchronized void resetSelection() { | |||
inSelectionMode = false; | |||
selectionStart = new Point(0, 0); | |||
selectionEnd = new Point(0, 0); | |||
savedCursor = getCursor(); | |||
} | |||
/** | |||
* Check current state of the selection mode. | |||
* @return true in the selection mode, false otherwise. | |||
*/ | |||
public boolean isInSelectionMode() { | |||
return inSelectionMode; | |||
} | |||
/** | |||
* Get current selection. | |||
* @param useScreenCoords use screen coordinates if true, or framebuffer | |||
* coordinates if false. This makes difference when scaling factor is not 100. | |||
* @return The selection as a {@link Rectangle}. | |||
*/ | |||
private synchronized Rectangle getSelection(boolean useScreenCoords) { | |||
int x0 = selectionStart.x; | |||
int x1 = selectionEnd.x; | |||
int y0 = selectionStart.y; | |||
int y1 = selectionEnd.y; | |||
// Make x and y point to the upper left corner of the selection. | |||
if (x1 < x0) { | |||
int t = x0; x0 = x1; x1 = t; | |||
} | |||
if (y1 < y0) { | |||
int t = y0; y0 = y1; y1 = t; | |||
} | |||
// Include the borders in the selection (unless it's empty). | |||
if (x0 != x1 && y0 != y1) { | |||
x1 += 1; | |||
y1 += 1; | |||
} | |||
// Translate from screen coordinates to framebuffer coordinates. | |||
if (rfb.framebufferWidth != scaledWidth) { | |||
x0 = (x0 * 100 + scalingFactor/2) / scalingFactor; | |||
y0 = (y0 * 100 + scalingFactor/2) / scalingFactor; | |||
x1 = (x1 * 100 + scalingFactor/2) / scalingFactor; | |||
y1 = (y1 * 100 + scalingFactor/2) / scalingFactor; | |||
} | |||
// Clip the selection to framebuffer. | |||
if (x0 < 0) | |||
x0 = 0; | |||
if (y0 < 0) | |||
y0 = 0; | |||
if (x1 > rfb.framebufferWidth) | |||
x1 = rfb.framebufferWidth; | |||
if (y1 > rfb.framebufferHeight) | |||
y1 = rfb.framebufferHeight; | |||
// Make width a multiple of 16. | |||
int widthBlocks = (x1 - x0 + 8) / 16; | |||
if (selectionStart.x <= selectionEnd.x) { | |||
x1 = x0 + widthBlocks * 16; | |||
if (x1 > rfb.framebufferWidth) { | |||
x1 -= 16; | |||
} | |||
} else { | |||
x0 = x1 - widthBlocks * 16; | |||
if (x0 < 0) { | |||
x0 += 16; | |||
} | |||
} | |||
// Make height a multiple of 8. | |||
int heightBlocks = (y1 - y0 + 4) / 8; | |||
if (selectionStart.y <= selectionEnd.y) { | |||
y1 = y0 + heightBlocks * 8; | |||
if (y1 > rfb.framebufferHeight) { | |||
y1 -= 8; | |||
} | |||
} else { | |||
y0 = y1 - heightBlocks * 8; | |||
if (y0 < 0) { | |||
y0 += 8; | |||
} | |||
} | |||
// Translate the selection back to screen coordinates if requested. | |||
if (useScreenCoords && rfb.framebufferWidth != scaledWidth) { | |||
x0 = (x0 * scalingFactor + 50) / 100; | |||
y0 = (y0 * scalingFactor + 50) / 100; | |||
x1 = (x1 * scalingFactor + 50) / 100; | |||
y1 = (y1 * scalingFactor + 50) / 100; | |||
} | |||
// Construct and return the result. | |||
return new Rectangle(x0, y0, x1 - x0, y1 - y0); | |||
} | |||
/** | |||
* Enable or disable the selection mode. | |||
* @param enable enables the selection mode if true, disables if fasle. | |||
*/ | |||
public synchronized void enableSelection(boolean enable) { | |||
if (enable && !inSelectionMode) { | |||
// Enter the selection mode. | |||
inSelectionMode = true; | |||
savedCursor = getCursor(); | |||
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); | |||
repaint(); | |||
} else if (!enable && inSelectionMode) { | |||
// Leave the selection mode. | |||
inSelectionMode = false; | |||
setCursor(savedCursor); | |||
repaint(); | |||
} | |||
} | |||
/** | |||
* Process mouse events in the selection mode. | |||
* | |||
* @param evt mouse event that was originally passed to | |||
* {@link MouseListener} or {@link MouseMotionListener}. | |||
*/ | |||
private synchronized void handleSelectionMouseEvent(MouseEvent evt) { | |||
int id = evt.getID(); | |||
boolean button1 = (evt.getModifiers() & InputEvent.BUTTON1_MASK) != 0; | |||
if (id == MouseEvent.MOUSE_PRESSED && button1) { | |||
selectionStart = selectionEnd = evt.getPoint(); | |||
repaint(); | |||
} | |||
if (id == MouseEvent.MOUSE_DRAGGED && button1) { | |||
selectionEnd = evt.getPoint(); | |||
repaint(); | |||
} | |||
if (id == MouseEvent.MOUSE_RELEASED && button1) { | |||
try { | |||
rfb.trySendVideoSelection(getSelection(false)); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
} |
@@ -162,16 +162,6 @@ public class VncViewer extends java.applet.Applet | |||
connectAndAuthenticate(); | |||
doProtocolInitialisation(); | |||
if (showControls && | |||
rfb.clientMsgCaps.isEnabled(RfbProto.VideoRectangleSelection)) { | |||
buttonPanel.addSelectButton(); | |||
} | |||
if (showControls && | |||
rfb.clientMsgCaps.isEnabled(RfbProto.VideoFreeze)) { | |||
buttonPanel.addVideoFreezeButton(); | |||
} | |||
// FIXME: Use auto-scaling not only in a separate frame. | |||
if (options.autoScale && inSeparateFrame) { | |||
Dimension screenSize; | |||
@@ -352,16 +342,7 @@ public class VncViewer extends java.applet.Applet | |||
rfb.clientMajor + "." + rfb.clientMinor); | |||
int secType = rfb.negotiateSecurity(); | |||
int authType; | |||
if (secType == RfbProto.SecTypeTight) { | |||
showConnectionStatus("Enabling TightVNC protocol extensions"); | |||
rfb.setupTunneling(); | |||
authType = rfb.negotiateAuthenticationTight(); | |||
} else { | |||
authType = secType; | |||
} | |||
doAuthentification(authType); | |||
doAuthentification(secType); | |||
} | |||
void doAuthentification(int secType) throws Exception { |