Browse Source

Method cleanup.

Sync various methods and filenames with C++ versions
tags/v1.7.90
Brian P. Hinz 7 years ago
parent
commit
bcaadbe7ae

+ 0
- 14
java/com/tigervnc/rdr/InStream.java View File

@@ -159,20 +159,6 @@ abstract public class InStream {
}
}

public final int readCompactLength() {
int b = readU8();
int result = b & 0x7F;
if ((b & 0x80) != 0) {
b = readU8();
result |= (b & 0x7F) << 7;
if ((b & 0x80) != 0) {
b = readU8();
result |= (b & 0xFF) << 14;
}
}
return result;
}

// pos() returns the position in the stream.

abstract public int pos();

+ 12
- 0
java/com/tigervnc/rdr/ZlibInStream.java View File

@@ -62,6 +62,18 @@ public class ZlibInStream extends InStream {
ptr = end = start;
}

public void removeUnderlying()
{
ptr = end = start;
if (underlying == null) return;

while (bytesIn > 0) {
decompress(true);
end = start; // throw away any data
}
underlying = null;
}

public int pos()
{
return offset + ptr - start;

+ 135
- 78
java/com/tigervnc/rfb/CConnection.java View File

@@ -19,7 +19,11 @@

package com.tigervnc.rfb;

import java.awt.color.*;
import java.awt.image.*;
import java.nio.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

import com.tigervnc.network.*;
import com.tigervnc.rdr.*;
@@ -28,21 +32,86 @@ abstract public class CConnection extends CMsgHandler {

public CConnection()
{
csecurity = null; is = null; os = null; reader_ = null;
writer_ = null; shared = false;
super();
csecurity = null; is = null; os = null; reader_ = null; writer_ = null;
shared = false;
state_ = RFBSTATE_UNINITIALISED; useProtocol3_3 = false;
framebuffer = null; decoder = new DecodeManager(this);
security = new SecurityClient();
}

// deleteReaderAndWriter() deletes the reader and writer associated with
// this connection. This may be useful if you want to delete the streams
// before deleting the SConnection to make sure that no attempt by the
// SConnection is made to read or write.
// XXX Do we really need this at all???
public void deleteReaderAndWriter()
// Methods to initialise the connection

// setServerName() is used to provide a unique(ish) name for the server to
// which we are connected. This might be the result of getPeerEndpoint on
// a TcpSocket, for example, or a host specified by DNS name & port.
// The serverName is used when verifying the Identity of a host (see RA2).
public final void setServerName(String name) {
serverName = name;
}

// setShared sets the value of the shared flag which will be sent to the
// server upon initialisation.
public final void setShared(boolean s) { shared = s; }

// setProtocol3_3 configures whether or not the CConnection should
// only ever support protocol version 3.3
public final void setProtocol3_3(boolean s) { useProtocol3_3 = s; }

// setStreams() sets the streams to be used for the connection. These must
// be set before initialiseProtocol() and processMsg() are called. The
// CSecurity object may call setStreams() again to provide alternative
// streams over which the RFB protocol is sent (i.e. encrypting/decrypting
// streams). Ownership of the streams remains with the caller
// (i.e. SConnection will not delete them).
public final void setStreams(InStream is_, OutStream os_)
{
is = is_;
os = os_;
}

// setFramebuffer configures the PixelBuffer that the CConnection
// should render all pixel data in to. Note that the CConnection
// takes ownership of the PixelBuffer and it must not be deleted by
// anyone else. Call setFramebuffer again with NULL or a different
// PixelBuffer to delete the previous one.
public void setFramebuffer(ModifiablePixelBuffer fb)
{
reader_ = null;
writer_ = null;
decoder.flush();

if ((framebuffer != null) && (fb != null)) {
Rect rect = new Rect();

Raster data;

byte[] black = new byte[4];

// Copy still valid area

rect.setXYWH(0, 0,
Math.min(fb.width(), framebuffer.width()),
Math.min(fb.height(), framebuffer.height()));
data = framebuffer.getBuffer(rect);
fb.imageRect(framebuffer.getPF(), rect, data);

// Black out any new areas

if (fb.width() > framebuffer.width()) {
rect.setXYWH(framebuffer.width(), 0,
fb.width() - framebuffer.width(),
fb.height());
fb.fillRect(rect, black);
}

if (fb.height() > framebuffer.height()) {
rect.setXYWH(0, framebuffer.height(),
fb.width(),
fb.height() - framebuffer.height());
fb.fillRect(rect, black);
}
}

framebuffer = fb;
}

// initialiseProtocol() should be called once the streams and security
@@ -75,11 +144,12 @@ abstract public class CConnection extends CMsgHandler {
private void processVersionMsg()
{
vlog.debug("reading protocol version");
if (!cp.readVersion(is)) {
AtomicBoolean done = new AtomicBoolean();
if (!cp.readVersion(is, done)) {
state_ = RFBSTATE_INVALID;
throw new Exception("reading version failed: not an RFB server?");
}
if (!cp.done) return;
if (!done.get()) return;

vlog.info("Server supports RFB protocol version "
+cp.majorVersion+"."+ cp.minorVersion);
@@ -241,52 +311,30 @@ abstract public class CConnection extends CMsgHandler {

private void securityCompleted() {
state_ = RFBSTATE_INITIALISATION;
reader_ = new CMsgReaderV3(this, is);
writer_ = new CMsgWriterV3(cp, os);
reader_ = new CMsgReader(this, is);
writer_ = new CMsgWriter(cp, os);
vlog.debug("Authentication success!");
authSuccess();
writer_.writeClientInit(shared);
}

// Methods to initialise the connection

// setServerName() is used to provide a unique(ish) name for the server to
// which we are connected. This might be the result of getPeerEndpoint on
// a TcpSocket, for example, or a host specified by DNS name & port.
// The serverName is used when verifying the Identity of a host (see RA2).
public final void setServerName(String name) {
serverName = name;
}

// setStreams() sets the streams to be used for the connection. These must
// be set before initialiseProtocol() and processMsg() are called. The
// CSecurity object may call setStreams() again to provide alternative
// streams over which the RFB protocol is sent (i.e. encrypting/decrypting
// streams). Ownership of the streams remains with the caller
// (i.e. SConnection will not delete them).
public final void setStreams(InStream is_, OutStream os_)
{
is = is_;
os = os_;
}
// Methods to be overridden in a derived class

// setShared sets the value of the shared flag which will be sent to the
// server upon initialisation.
public final void setShared(boolean s) { shared = s; }
// Note: These must be called by any deriving classes

// setProtocol3_3 configures whether or not the CConnection should
// only ever support protocol version 3.3
public final void setProtocol3_3(boolean s) { useProtocol3_3 = s; }
public void setDesktopSize(int w, int h) {
decoder.flush();

public void setServerPort(int port) {
serverPort = port;
super.setDesktopSize(w,h);
}

public void initSecTypes() {
nSecTypes = 0;
}
public void setExtendedDesktopSize(int reason,
int result, int w, int h,
ScreenSet layout) {
decoder.flush();

// Methods to be overridden in a derived class
super.setExtendedDesktopSize(reason, result, w, h, layout);
}

// getIdVerifier() returns the identity verifier associated with the connection.
// Ownership of the IdentityVerifier is retained by the CConnection instance.
@@ -299,11 +347,20 @@ abstract public class CConnection extends CMsgHandler {

public void framebufferUpdateEnd()
{
decoder.flush();

super.framebufferUpdateEnd();
}

public void dataRect(Rect r, int encoding)
{
decoder.decodeRect(r, encoding, framebuffer);
}

// authSuccess() is called when authentication has succeeded.
public void authSuccess() {}
public void authSuccess()
{
}

// serverInit() is called when the ServerInit message is received. The
// derived class must call on to CConnection::serverInit().
@@ -313,34 +370,17 @@ abstract public class CConnection extends CMsgHandler {
vlog.debug("initialisation done");
}

// getCSecurity() gets the CSecurity object for the given type. The type
// is guaranteed to be one of the secTypes passed in to addSecType(). The
// CSecurity object's destroy() method will be called by the CConnection
// from its destructor.
//abstract public CSecurity getCSecurity(int secType);

// getCurrentCSecurity() gets the CSecurity instance used for this
// connection.
//public CSecurity getCurrentCSecurity() { return security; }

// setClientSecTypeOrder() determines whether the client should obey the
// server's security type preference, by picking the first server security
// type that the client supports, or whether it should pick the first type
// that the server supports, from the client-supported list of types.
public void setClientSecTypeOrder( boolean csto ) {
clientSecTypeOrder = csto;
}

// Other methods

public CMsgReaderV3 reader() { return reader_; }
public CMsgWriterV3 writer() { return writer_; }
public CMsgReader reader() { return reader_; }
public CMsgWriter writer() { return writer_; }

public InStream getInStream() { return is; }
public OutStream getOutStream() { return os; }

// Access method used by SSecurity implementations that can verify servers'
// Identities, to determine the unique(ish) name of the server.
public String getServerName() { return serverName; }
public int getServerPort() { return serverPort; }

public static final int RFBSTATE_UNINITIALISED = 0;
public static final int RFBSTATE_PROTOCOL_VERSION = 1;
@@ -353,7 +393,17 @@ abstract public class CConnection extends CMsgHandler {

public int state() { return state_; }

protected final void setState(int s) { state_ = s; }
public int getServerPort() { return serverPort; }
public void setServerPort(int port) {
serverPort = port;
}

protected void setState(int s) { state_ = s; }

protected void setReader(CMsgReader r) { reader_ = r; }
protected void setWriter(CMsgWriter w) { writer_ = w; }

protected ModifiablePixelBuffer getFramebuffer() { return framebuffer; }

public void fence(int flags, int len, byte[] data)
{
@@ -383,20 +433,27 @@ abstract public class CConnection extends CMsgHandler {
throw new AuthFailureException(reason);
}

InStream is;
OutStream os;
CMsgReaderV3 reader_;
CMsgWriterV3 writer_;
boolean shared;
private InStream is;
private OutStream os;
private CMsgReader reader_;
private CMsgWriter writer_;
private boolean deleteStreamsWhenDone;
private boolean shared;
private int state_ = RFBSTATE_UNINITIALISED;

private String serverName;

private boolean useProtocol3_3;

protected ModifiablePixelBuffer framebuffer;
private DecodeManager decoder;

public CSecurity csecurity;
public SecurityClient security;
public static final int maxSecTypes = 8;
int nSecTypes;
int[] secTypes;
int state_ = RFBSTATE_UNINITIALISED;
String serverName;
int serverPort;
boolean useProtocol3_3;
boolean clientSecTypeOrder;

static LogWriter vlog = new LogWriter("CConnection");

+ 2
- 9
java/com/tigervnc/rfb/CMsgHandler.java View File

@@ -78,25 +78,18 @@ abstract public class CMsgHandler {
String x509subject) {}

public void setCursor(int width, int height, Point hotspot,
int[] data, byte[] mask) {}
byte[] data, byte[] mask) {}
public void serverInit() {}

public void framebufferUpdateStart() {}
public void framebufferUpdateEnd() {}
public void beginRect(Rect r, int encoding) {}
public void endRect(Rect r, int encoding) {}
public void dataRect(Rect r, int encoding) {}

public void setColourMapEntries(int firstColour, int nColours,
int[] rgbs) { }
public void bell() {}
public void serverCutText(String str, int len) {}

public void fillRect(Rect r, int pix) {}
public void imageRect(Rect r, Object pixels) {}
public void copyRect(Rect r, int srcX, int srcY) {}

abstract public PixelFormat getPreferredPF();

public ConnParams cp;

static LogWriter vlog = new LogWriter("CMsgHandler");

+ 155
- 39
java/com/tigervnc/rfb/CMsgReader.java View File

@@ -28,7 +28,7 @@ import java.nio.CharBuffer;
import java.nio.charset.Charset;
import com.tigervnc.rdr.*;

abstract public class CMsgReader {
public class CMsgReader {

protected CMsgReader(CMsgHandler handler_, InStream is_)
{
@@ -37,7 +37,82 @@ abstract public class CMsgReader {
is = is_;
imageBuf = null;
imageBufSize = 0;
decoders = new Decoder[Encodings.encodingMax+1];
nUpdateRectsLeft = 0;
}

public void readServerInit()
{
int width = is.readU16();
int height = is.readU16();
handler.setDesktopSize(width, height);
PixelFormat pf = new PixelFormat();
pf.read(is);
handler.setPixelFormat(pf);
String name = is.readString();
handler.setName(name);
handler.serverInit();
}

public void readMsg()
{
if (nUpdateRectsLeft == 0) {
int type = is.readU8();

switch (type) {
case MsgTypes.msgTypeSetColourMapEntries:
readSetColourMapEntries();
break;
case MsgTypes.msgTypeBell:
readBell();
break;
case MsgTypes.msgTypeServerCutText:
readServerCutText();
break;
case MsgTypes.msgTypeFramebufferUpdate:
readFramebufferUpdate();
break;
case MsgTypes.msgTypeServerFence:
readFence();
break;
case MsgTypes.msgTypeEndOfContinuousUpdates:
readEndOfContinuousUpdates();
break;
default:
//fprintf(stderr, "unknown message type %d\n", type);
throw new Exception("unknown message type");
}
} else {
int x = is.readU16();
int y = is.readU16();
int w = is.readU16();
int h = is.readU16();
int encoding = is.readS32();

switch (encoding) {
case Encodings.pseudoEncodingLastRect:
nUpdateRectsLeft = 1; // this rectangle is the last one
break;
case Encodings.pseudoEncodingCursor:
readSetCursor(w, h, new Point(x,y));
break;
case Encodings.pseudoEncodingDesktopName:
readSetDesktopName(x, y, w, h);
break;
case Encodings.pseudoEncodingDesktopSize:
handler.setDesktopSize(w, h);
break;
case Encodings.pseudoEncodingExtendedDesktopSize:
readExtendedDesktopSize(x, y, w, h);
break;
default:
readRect(new Rect(x, y, x+w, y+h), encoding);
break;
};

nUpdateRectsLeft--;
if (nUpdateRectsLeft == 0)
handler.framebufferUpdateEnd();
}
}

protected void readSetColourMapEntries()
@@ -72,6 +147,43 @@ abstract public class CMsgReader {
handler.serverCutText(chars.toString(), len);
}

protected void readFence()
{
int flags;
int len;
byte[] data = new byte[64];

is.skip(3);

flags = is.readU32();

len = is.readU8();
if (len > data.length) {
System.out.println("Ignoring fence with too large payload\n");
is.skip(len);
return;
}

is.readBytes(data, 0, len);

handler.fence(flags, len, data);
}

protected void readEndOfContinuousUpdates()
{
handler.endOfContinuousUpdates();
}

protected void readFramebufferUpdate()
{
is.skip(1);
nUpdateRectsLeft = is.readU16();
handler.framebufferUpdateStart();
}



/*
protected void readFramebufferUpdateStart()
{
handler.framebufferUpdateStart();
@@ -81,6 +193,7 @@ abstract public class CMsgReader {
{
handler.framebufferUpdateEnd();
}
*/

protected void readRect(Rect r, int encoding)
{
@@ -94,43 +207,56 @@ abstract public class CMsgReader {
if (r.is_empty())
vlog.error("Ignoring zero size rect");

handler.beginRect(r, encoding);
handler.dataRect(r, encoding);
}

if (encoding == Encodings.encodingCopyRect) {
readCopyRect(r);
} else {
protected void readSetCursor(int width, int height, Point hotspot)
{
int data_len = width * height * (handler.cp.pf().bpp/8);
int mask_len = ((width+7)/8) * height;
byte[] data = new byte[data_len];
byte[] mask = new byte[mask_len];

if (decoders[encoding] == null) {
decoders[encoding] = Decoder.createDecoder(encoding, this);
if (decoders[encoding] == null) {
vlog.error("Unknown rect encoding "+encoding);
throw new Exception("Unknown rect encoding");
}
}
decoders[encoding].readRect(r, handler);
}
is.readBytes(data, 0, data_len);
is.readBytes(mask, 0, mask_len);

handler.endRect(r, encoding);
handler.setCursor(width, height, hotspot, data, mask);
}

protected void readCopyRect(Rect r)
protected void readSetDesktopName(int x, int y, int w, int h)
{
int srcX = is.readU16();
int srcY = is.readU16();
handler.copyRect(r, srcX, srcY);
String name = is.readString();

if (x != 0 || y != 0 || w != 0 || h != 0) {
vlog.error("Ignoring DesktopName rect with non-zero position/size");
} else {
handler.setName(name);
}

}

protected void readSetCursor(int width, int height, Point hotspot)
protected void readExtendedDesktopSize(int x, int y, int w, int h)
{
int data_len = width * height;
int mask_len = ((width+7)/8) * height;
int[] data = new int[data_len];
byte[] mask = new byte[mask_len];
int screens, i;
int id, flags;
int sx, sy, sw, sh;
ScreenSet layout = new ScreenSet();

is.readPixels(data, data_len, (handler.cp.pf().bpp/8), handler.cp.pf().bigEndian);
is.readBytes(mask, 0, mask_len);
screens = is.readU8();
is.skip(3);

handler.setCursor(width, height, hotspot, data, mask);
for (i = 0;i < screens;i++) {
id = is.readU32();
sx = is.readU16();
sy = is.readU16();
sw = is.readU16();
sh = is.readU16();
flags = is.readU32();

layout.add_screen(new Screen(id, sx, sy, sw, sh, flags));
}

handler.setExtendedDesktopSize(x, y, w, h, layout);
}

public int[] getImageBuf(int required) { return getImageBuf(required, 0, 0); }
@@ -154,23 +280,13 @@ abstract public class CMsgReader {
return imageBuf;
}

public final int bpp()
{
return handler.cp.pf().bpp;
}

abstract public void readServerInit();

// readMsg() reads a message, calling the handler as appropriate.
abstract public void readMsg();

public InStream getInStream() { return is; }

public int imageBufIdealSize;

protected CMsgHandler handler;
protected InStream is;
protected Decoder[] decoders;
protected int nUpdateRectsLeft;
protected int[] imageBuf;
protected int imageBufSize;


+ 94
- 18
java/com/tigervnc/rfb/CMsgWriter.java View File

@@ -20,13 +20,23 @@

package com.tigervnc.rfb;

import com.tigervnc.rdr.*;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import com.tigervnc.rdr.*;
import java.util.Iterator;

abstract public class CMsgWriter {
public class CMsgWriter {

abstract public void writeClientInit(boolean shared);
protected CMsgWriter(ConnParams cp_, OutStream os_)
{
cp = cp_;
os = os_;
}

synchronized public void writeClientInit(boolean shared) {
os.writeU8(shared?1:0);
endMsg();
}

synchronized public void writeSetPixelFormat(PixelFormat pf)
{
@@ -53,6 +63,7 @@ abstract public class CMsgWriter {
{
int nEncodings = 0;
int[] encodings = new int[Encodings.encodingMax+3];

if (cp.supportsLocalCursor)
encodings[nEncodings++] = Encodings.pseudoEncodingCursor;
if (cp.supportsDesktopResize)
@@ -68,7 +79,6 @@ abstract public class CMsgWriter {
encodings[nEncodings++] = Encodings.pseudoEncodingContinuousUpdates;
encodings[nEncodings++] = Encodings.pseudoEncodingFence;


if (Decoder.supported(preferredEncoding)) {
encodings[nEncodings++] = preferredEncoding;
}
@@ -98,9 +108,11 @@ abstract public class CMsgWriter {
// Remaining encodings
for (int i = Encodings.encodingMax; i >= 0; i--) {
switch (i) {
case Encodings.encodingCopyRect:
case Encodings.encodingTight:
case Encodings.encodingZRLE:
case Encodings.encodingHextile:
/* These have already been sent earlier */
break;
default:
if ((i != preferredEncoding) && Decoder.supported(i))
@@ -108,15 +120,44 @@ abstract public class CMsgWriter {
}
}

encodings[nEncodings++] = Encodings.pseudoEncodingLastRect;
if (cp.customCompressLevel && cp.compressLevel >= 0 && cp.compressLevel <= 9)
encodings[nEncodings++] = Encodings.pseudoEncodingCompressLevel0 + cp.compressLevel;
if (!cp.noJpeg && cp.qualityLevel >= 0 && cp.qualityLevel <= 9)
encodings[nEncodings++] = Encodings.pseudoEncodingQualityLevel0 + cp.qualityLevel;
if (cp.compressLevel >= 0 && cp.compressLevel <= 9)
encodings[nEncodings++] =
Encodings.pseudoEncodingCompressLevel0 + cp.compressLevel;
if (cp.qualityLevel >= 0 && cp.qualityLevel <= 9)
encodings[nEncodings++] =
Encodings.pseudoEncodingQualityLevel0 + cp.qualityLevel;

writeSetEncodings(nEncodings, encodings);
}

synchronized public void writeSetDesktopSize(int width, int height,
ScreenSet layout)
{
if (!cp.supportsSetDesktopSize)
throw new Exception("Server does not support SetDesktopSize");

startMsg(MsgTypes.msgTypeSetDesktopSize);
os.pad(1);

os.writeU16(width);
os.writeU16(height);

os.writeU8(layout.num_screens());
os.pad(1);

for (Iterator<Screen> iter = layout.screens.iterator(); iter.hasNext(); ) {
Screen refScreen = (Screen)iter.next();
os.writeU32(refScreen.id);
os.writeU16(refScreen.dimensions.tl.x);
os.writeU16(refScreen.dimensions.tl.y);
os.writeU16(refScreen.dimensions.width());
os.writeU16(refScreen.dimensions.height());
os.writeU32(refScreen.flags);
}

endMsg();
}

synchronized public void writeFramebufferUpdateRequest(Rect r, boolean incremental)
{
startMsg(MsgTypes.msgTypeFramebufferUpdateRequest);
@@ -128,6 +169,44 @@ abstract public class CMsgWriter {
endMsg();
}

synchronized public void writeEnableContinuousUpdates(boolean enable,
int x, int y, int w, int h)
{
if (!cp.supportsContinuousUpdates)
throw new Exception("Server does not support continuous updates");

startMsg(MsgTypes.msgTypeEnableContinuousUpdates);

os.writeU8((enable?1:0));

os.writeU16(x);
os.writeU16(y);
os.writeU16(w);
os.writeU16(h);

endMsg();
}

synchronized public void writeFence(int flags, int len, byte[] data)
{
if (!cp.supportsFence)
throw new Exception("Server does not support fences");
if (len > 64)
throw new Exception("Too large fence payload");
if ((flags & ~fenceTypes.fenceFlagsSupported) != 0)
throw new Exception("Unknown fence flags");

startMsg(MsgTypes.msgTypeClientFence);
os.pad(3);

os.writeU32(flags);

os.writeU8(len);
os.writeBytes(data, 0, len);

endMsg();
}

synchronized public void writeKeyEvent(int key, boolean down)
{
startMsg(MsgTypes.msgTypeKeyEvent);
@@ -163,17 +242,14 @@ abstract public class CMsgWriter {
endMsg();
}

abstract public void startMsg(int type);
abstract public void endMsg();

synchronized public void setOutStream(OutStream os_) { os = os_; }

ConnParams getConnParams() { return cp; }
OutStream getOutStream() { return os; }
synchronized public void startMsg(int type) {
os.writeU8(type);
}

protected CMsgWriter(ConnParams cp_, OutStream os_) {cp = cp_; os = os_;}
synchronized public void endMsg() {
os.flush();
}

ConnParams cp;
OutStream os;
static LogWriter vlog = new LogWriter("CMsgWriter");
}

+ 92
- 69
java/com/tigervnc/rfb/ConnParams.java View File

@@ -1,6 +1,6 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
* Copyright (C) 2012 Brian P. Hinz
* Copyright (C) 2012-2016 Brian P. Hinz
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,11 +21,21 @@
package com.tigervnc.rfb;

import com.tigervnc.rdr.*;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

public class ConnParams {
static LogWriter vlog = new LogWriter("ConnParams");

public ConnParams() {
private static final int subsampleUndefined = -1;
private static final int subsampleNone = 0;
private static final int subsampleGray = 1;
private static final int subsample2X = 2;
private static final int subsample4X = 3;
private static final int subsample8X = 4;
private static final int subsample16X = 5;

public ConnParams()
{
majorVersion = 0; minorVersion = 0;
width = 0; height = 0; useCopyRect = false;
supportsLocalCursor = false; supportsLocalXCursor = false;
@@ -34,19 +44,17 @@ public class ConnParams {
supportsSetDesktopSize = false; supportsFence = false;
supportsContinuousUpdates = false;
supportsClientRedirect = false;
customCompressLevel = false; compressLevel = 6;
noJpeg = false; qualityLevel = -1; fineQualityLevel = -1;
subsampling = "SUBSAMP_UNDEFINED";
name_ = null; nEncodings_ = 0; encodings_ = null;
currentEncoding_ = Encodings.encodingRaw; verStrPos = 0;
compressLevel = 6; qualityLevel = -1; fineQualityLevel = -1;
subsampling = subsampleUndefined; name_ = null; verStrPos = 0;

encodings_ = new ArrayList();
screenLayout = new ScreenSet();

setName("");
}

public boolean readVersion(InStream is)
public boolean readVersion(InStream is, AtomicBoolean done)
{
done = false;
if (verStrPos >= 12) return false;
verStr = new StringBuilder(13);
while (is.checkNoWait(1) && verStrPos < 12) {
@@ -54,10 +62,10 @@ public class ConnParams {
}

if (verStrPos < 12) {
done = false;
done.set(false);
return true;
}
done = true;
done.set(true);
verStr.insert(12,'0');
verStrPos = 0;
if (verStr.toString().matches("RFB \\d{3}\\.\\d{3}\\n0")) {
@@ -68,7 +76,8 @@ public class ConnParams {
return false;
}

public void writeVersion(OutStream os) {
public void writeVersion(OutStream os)
{
String str = String.format("RFB %03d.%03d\n", majorVersion, minorVersion);
os.writeBytes(str.getBytes(), 0, 12);
os.flush();
@@ -97,10 +106,11 @@ public class ConnParams {

public PixelFormat pf() { return pf_; }
public void setPF(PixelFormat pf) {

pf_ = pf;
if (pf.bpp != 8 && pf.bpp != 16 && pf.bpp != 32) {

if (pf.bpp != 8 && pf.bpp != 16 && pf.bpp != 32)
throw new Exception("setPF: not 8, 16 or 32 bpp?");
}
}

public String name() { return name_; }
@@ -109,80 +119,96 @@ public class ConnParams {
name_ = name;
}

public int currentEncoding() { return currentEncoding_; }
public int nEncodings() { return nEncodings_; }
public int[] encodings() { return encodings_; }
public boolean supportsEncoding(int encoding)
{
return encodings_.indexOf(encoding) != -1;
}

public void setEncodings(int nEncodings, int[] encodings)
{
if (nEncodings > nEncodings_) {
encodings_ = new int[nEncodings];
}
nEncodings_ = nEncodings;
useCopyRect = false;
supportsLocalCursor = false;
supportsDesktopResize = false;
supportsExtendedDesktopSize = false;
supportsLocalXCursor = false;
supportsLastRect = false;
customCompressLevel = false;
compressLevel = -1;
noJpeg = true;
qualityLevel = -1;
fineQualityLevel = -1;
subsampling = "SUBSAMP_UNDEFINED";
currentEncoding_ = Encodings.encodingRaw;
subsampling = subsampleUndefined;

for (int i = nEncodings-1; i >= 0; i--) {
encodings_[i] = encodings[i];
encodings_.clear();
encodings_.add(Encodings.encodingRaw);

if (encodings[i] == Encodings.encodingCopyRect)
for (int i = nEncodings-1; i >= 0; i--) {
switch (encodings[i]) {
case Encodings.encodingCopyRect:
useCopyRect = true;
else if (encodings[i] == Encodings.pseudoEncodingCursor)
break;
case Encodings.pseudoEncodingCursor:
supportsLocalCursor = true;
else if (encodings[i] == Encodings.pseudoEncodingXCursor)
break;
case Encodings.pseudoEncodingXCursor:
supportsLocalXCursor = true;
else if (encodings[i] == Encodings.pseudoEncodingDesktopSize)
break;
case Encodings.pseudoEncodingDesktopSize:
supportsDesktopResize = true;
else if (encodings[i] == Encodings.pseudoEncodingExtendedDesktopSize)
break;
case Encodings.pseudoEncodingExtendedDesktopSize:
supportsExtendedDesktopSize = true;
else if (encodings[i] == Encodings.pseudoEncodingDesktopName)
break;
case Encodings.pseudoEncodingDesktopName:
supportsDesktopRename = true;
else if (encodings[i] == Encodings.pseudoEncodingLastRect)
break;
case Encodings.pseudoEncodingLastRect:
supportsLastRect = true;
else if (encodings[i] == Encodings.pseudoEncodingFence)
break;
case Encodings.pseudoEncodingFence:
supportsFence = true;
else if (encodings[i] == Encodings.pseudoEncodingContinuousUpdates)
break;
case Encodings.pseudoEncodingContinuousUpdates:
supportsContinuousUpdates = true;
else if (encodings[i] == Encodings.pseudoEncodingClientRedirect)
break;
case Encodings.pseudoEncodingClientRedirect:
supportsClientRedirect = true;
else if (encodings[i] >= Encodings.pseudoEncodingCompressLevel0 &&
encodings[i] <= Encodings.pseudoEncodingCompressLevel9) {
customCompressLevel = true;
break;
case Encodings.pseudoEncodingSubsamp1X:
subsampling = subsampleNone;
break;
case Encodings.pseudoEncodingSubsampGray:
subsampling = subsampleGray;
break;
case Encodings.pseudoEncodingSubsamp2X:
subsampling = subsample2X;
break;
case Encodings.pseudoEncodingSubsamp4X:
subsampling = subsample4X;
break;
case Encodings.pseudoEncodingSubsamp8X:
subsampling = subsample8X;
break;
case Encodings.pseudoEncodingSubsamp16X:
subsampling = subsample16X;
break;
}

if (encodings[i] >= Encodings.pseudoEncodingCompressLevel0 &&
encodings[i] <= Encodings.pseudoEncodingCompressLevel9)
compressLevel = encodings[i] - Encodings.pseudoEncodingCompressLevel0;
} else if (encodings[i] >= Encodings.pseudoEncodingQualityLevel0 &&
encodings[i] <= Encodings.pseudoEncodingQualityLevel9) {
noJpeg = false;
if (encodings[i] >= Encodings.pseudoEncodingQualityLevel0 &&
encodings[i] <= Encodings.pseudoEncodingQualityLevel9)
qualityLevel = encodings[i] - Encodings.pseudoEncodingQualityLevel0;
} else if (encodings[i] <= Encodings.encodingMax &&
Encoder.supported(encodings[i]))
currentEncoding_ = encodings[i];
}

// If the TurboVNC fine quality/subsampling encodings exist, let them
// override the coarse TightVNC quality level
for (int i = nEncodings-1; i >= 0; i--) {
if (encodings[i] >= Encodings.pseudoEncodingFineQualityLevel0 + 1 &&
encodings[i] <= Encodings.pseudoEncodingFineQualityLevel100) {
noJpeg = false;
if (encodings[i] >= Encodings.pseudoEncodingFineQualityLevel0 &&
encodings[i] <= Encodings.pseudoEncodingFineQualityLevel100)
fineQualityLevel = encodings[i] - Encodings.pseudoEncodingFineQualityLevel0;
} else if (encodings[i] >= Encodings.pseudoEncodingSubsamp1X &&
encodings[i] <= Encodings.pseudoEncodingSubsampGray) {
noJpeg = false;
subsampling = JpegCompressor.subsamplingName(encodings[i] - Encodings.pseudoEncodingSubsamp1X);
}

if (encodings[i] > 0)
encodings_.add(encodings[i]);
}
}
public boolean done;
public boolean useCopyRect;

public boolean supportsLocalCursor;
@@ -190,25 +216,22 @@ public class ConnParams {
public boolean supportsDesktopResize;
public boolean supportsExtendedDesktopSize;
public boolean supportsDesktopRename;
public boolean supportsClientRedirect;
public boolean supportsFence;
public boolean supportsContinuousUpdates;
public boolean supportsLastRect;
public boolean supportsClientRedirect;

public boolean supportsSetDesktopSize;
public boolean supportsFence;
public boolean supportsContinuousUpdates;

public boolean customCompressLevel;
public int compressLevel;
public boolean noJpeg;
public int qualityLevel;
public int fineQualityLevel;
public String subsampling;
public int subsampling;

private PixelFormat pf_;
private String name_;
private int nEncodings_;
private int[] encodings_;
private int currentEncoding_;
private Cursor cursor_;
private ArrayList encodings_;
private StringBuilder verStr;
private int verStrPos;
}

+ 10
- 4
java/com/tigervnc/rfb/ScreenSet.java View File

@@ -31,13 +31,18 @@ public class ScreenSet {
screens = new ArrayList<Screen>();
}

public final ListIterator<Screen> begin() { return screens.listIterator(0); }
public final ListIterator<Screen> end() {
return screens.listIterator(screens.size());
}
public final int num_screens() { return screens.size(); }

public final void add_screen(Screen screen) { screens.add(screen); }
public final void remove_screen(int id) {
for (Iterator<Screen> iter = screens.iterator(); iter.hasNext(); ) {
Screen refScreen = (Screen)iter.next();
if (refScreen.id == id)
ListIterator iter, nextiter;
for (iter = begin(); iter != end(); iter = nextiter) {
nextiter = iter; nextiter.next();
if (((Screen)iter.next()).id == id)
iter.remove();
}
}
@@ -68,9 +73,10 @@ public class ScreenSet {
}

public final void debug_print() {
vlog.debug(num_screens()+" screen(s)");
for (Iterator<Screen> iter = screens.iterator(); iter.hasNext(); ) {
Screen refScreen = (Screen)iter.next();
vlog.error(" "+refScreen.id+" (0x"+refScreen.id+"): "+
vlog.debug(" "+refScreen.id+" (0x"+refScreen.id+"): "+
refScreen.dimensions.width()+"x"+refScreen.dimensions.height()+
"+"+refScreen.dimensions.tl.x+"+"+refScreen.dimensions.tl.y+
" (flags 0x"+refScreen.flags+")");

Loading…
Cancel
Save