diff options
author | Adam Tkac <atkac@redhat.com> | 2009-03-13 13:11:51 +0000 |
---|---|---|
committer | Adam Tkac <atkac@redhat.com> | 2009-03-13 13:11:51 +0000 |
commit | d0e84634e0058af86d39f1609dff2089684247d7 (patch) | |
tree | c74c060f6cc64f5318f330e70861c2d7ce4e5b6f /java/src/com/tightvnc | |
parent | b184fc81d62fab3c2f909e8a15961ec0ca491b99 (diff) | |
download | tigervnc-d0e84634e0058af86d39f1609dff2089684247d7.tar.gz tigervnc-d0e84634e0058af86d39f1609dff2089684247d7.zip |
Rename java/src/com/tightvnc to java/src/com/tigervnc.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3672 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'java/src/com/tightvnc')
37 files changed, 0 insertions, 9344 deletions
diff --git a/java/src/com/tightvnc/decoder/CoRREDecoder.java b/java/src/com/tightvnc/decoder/CoRREDecoder.java deleted file mode 100644 index bc086686..00000000 --- a/java/src/com/tightvnc/decoder/CoRREDecoder.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.vncviewer.RfbInputStream; -import java.awt.Graphics; -import java.awt.Color; -import java.io.IOException; - -// -// Class that used for decoding CoRRE encoded data. -// - -public class CoRREDecoder extends RawDecoder { - - final static int EncodingCoRRE = 4; - - public CoRREDecoder(Graphics g, RfbInputStream is) { - super(g, is); - } - - public CoRREDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - } - - // - // Override handleRect method to decode CoRRE encoded data insted of - // raw pixel data. - // - - public void handleRect(int x, int y, int w, int h) throws IOException { - - // - // Write encoding ID to record output stream - // - - if (dos != null) { - dos.writeInt(CoRREDecoder.EncodingCoRRE); - } - - int nSubrects = rfbis.readU32(); - - byte[] bg_buf = new byte[bytesPerPixel]; - rfbis.readFully(bg_buf); - Color pixel; - if (bytesPerPixel == 1) { - pixel = getColor256()[bg_buf[0] & 0xFF]; - } else { - pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF); - } - graphics.setColor(pixel); - graphics.fillRect(x, y, w, h); - - byte[] buf = new byte[nSubrects * (bytesPerPixel + 4)]; - rfbis.readFully(buf); - - // - // Save decoded data to data output stream - // - - if (dos != null) { - dos.writeInt(nSubrects); - dos.write(bg_buf); - dos.write(buf); - } - - int sx, sy, sw, sh; - int i = 0; - - for (int j = 0; j < nSubrects; j++) { - if (bytesPerPixel == 1) { - pixel = getColor256()[buf[i++] & 0xFF]; - } else { - pixel = new Color(buf[i+2] & 0xFF, buf[i+1] & 0xFF, buf[i] & 0xFF); - i += 4; - } - sx = x + (buf[i++] & 0xFF); - sy = y + (buf[i++] & 0xFF); - sw = buf[i++] & 0xFF; - sh = buf[i++] & 0xFF; - - graphics.setColor(pixel); - graphics.fillRect(sx, sy, sw, sh); - } - } -} diff --git a/java/src/com/tightvnc/decoder/CopyRectDecoder.java b/java/src/com/tightvnc/decoder/CopyRectDecoder.java deleted file mode 100644 index 07a14bdb..00000000 --- a/java/src/com/tightvnc/decoder/CopyRectDecoder.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.vncviewer.RfbInputStream; -import java.awt.Graphics; -import java.io.IOException; - -// -// Class that used for decoding CopyRect encoded data. -// - -public class CopyRectDecoder extends RawDecoder { - - final static int EncodingCopyRect = 1; - - public CopyRectDecoder(Graphics g, RfbInputStream is) { - super(g, is); - } - - public CopyRectDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - } - - // - // Override handleRect method handle CopyRect - // - - public void handleRect(int x, int y, int w, int h) throws IOException { - - // - // Write encoding ID to record output stream - // - - if (dos != null) { - dos.writeInt(CopyRectDecoder.EncodingCopyRect); - } - - int copyRectSrcX = rfbis.readU16(); - int copyRectSrcY = rfbis.readU16(); - - // If the session is being recorded: - if (dos != null) { - dos.writeShort(copyRectSrcX); - dos.writeShort(copyRectSrcY); - } - - graphics.copyArea(copyRectSrcX, copyRectSrcY, w, h, - x - copyRectSrcX, y - copyRectSrcY); - } -} diff --git a/java/src/com/tightvnc/decoder/HextileDecoder.java b/java/src/com/tightvnc/decoder/HextileDecoder.java deleted file mode 100644 index da7e7781..00000000 --- a/java/src/com/tightvnc/decoder/HextileDecoder.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.decoder.common.Repaintable; -import com.tightvnc.vncviewer.RfbInputStream; -import java.awt.Color; -import java.awt.Graphics; -import java.io.IOException; - -// -// Class that used for decoding hextile encoded data. -// - -public class HextileDecoder extends RawDecoder { - - final static int EncodingHextile = 5; - - // Contstants used in the Hextile decoder - final static int - HextileRaw = 1, - HextileBackgroundSpecified = 2, - HextileForegroundSpecified = 4, - HextileAnySubrects = 8, - HextileSubrectsColoured = 16; - - public HextileDecoder(Graphics g, RfbInputStream is) { - super(g, is); - } - - public HextileDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - } - - // - // Set private members methods - // - - public void setRepainableControl(Repaintable r) { - repainableControl = r; - } - - // - // Override handleRect method to decode Hextile encoded data insted of - // raw pixel data. - // - - public void handleRect(int x, int y, int w, int h) throws IOException, - Exception { - - // - // Write encoding ID to record output stream - // - - if (dos != null) { - dos.writeInt(HextileDecoder.EncodingHextile); - } - - hextile_bg = new Color(0); - hextile_fg = new Color(0); - - for (int ty = y; ty < y + h; ty += 16) { - int th = 16; - if (y + h - ty < 16) - th = y + h - ty; - - for (int tx = x; tx < x + w; tx += 16) { - int tw = 16; - if (x + w - tx < 16) - tw = x + w - tx; - - handleHextileSubrect(tx, ty, tw, th); - } - if (repainableControl != null) - repainableControl.scheduleRepaint(x, y, w, h); - } - if (repainableControl != null) - repainableControl.scheduleRepaint(x, y, w, h); - } - - // - // Handle one tile in the Hextile-encoded data. - // - - private void handleHextileSubrect(int tx, int ty, int tw, int th) - throws IOException, Exception { - - int subencoding = rfbis.readU8(); - - // - // Save decoded data to data output stream - // - - if (dos != null) { - dos.writeByte((byte)subencoding); - } - - // Is it a raw-encoded sub-rectangle? - if ((subencoding & HextileRaw) != 0) { - // - // Disable encoding id writting to record stream - // in super (RawDecoder) class, cause we write subencoding ID - // in this class (see code above). - // - - super.enableEncodingRecordWritting(false); - super.handleRect(tx, ty, tw, th); - super.handleUpdatedPixels(tx, ty, tw, th); - super.enableEncodingRecordWritting(true); - return; - } - - // Read and draw the background if specified. - byte[] cbuf = new byte[bytesPerPixel]; - if ((subencoding & HextileBackgroundSpecified) != 0) { - rfbis.readFully(cbuf); - if (bytesPerPixel == 1) { - hextile_bg = getColor256()[cbuf[0] & 0xFF]; - } else { - hextile_bg = new Color(cbuf[2] & 0xFF, cbuf[1] & 0xFF, cbuf[0] & 0xFF); - } - - // - // Save decoded data to data output stream - // - - if (dos != null) { - dos.write(cbuf); - } - } - graphics.setColor(hextile_bg); - graphics.fillRect(tx, ty, tw, th); - - // Read the foreground color if specified. - if ((subencoding & HextileForegroundSpecified) != 0) { - rfbis.readFully(cbuf); - if (bytesPerPixel == 1) { - hextile_fg = getColor256()[cbuf[0] & 0xFF]; - } else { - hextile_fg = new Color(cbuf[2] & 0xFF, cbuf[1] & 0xFF, cbuf[0] & 0xFF); - } - - // - // Save decoded data to data output stream - // - - if (dos != null) { - dos.write(cbuf); - } - } - - // Done with this tile if there is no sub-rectangles. - if ((subencoding & HextileAnySubrects) == 0) - return; - - int nSubrects = rfbis.readU8(); - int bufsize = nSubrects * 2; - if ((subencoding & HextileSubrectsColoured) != 0) { - bufsize += nSubrects * bytesPerPixel; - } - byte[] buf = new byte[bufsize]; - rfbis.readFully(buf); - - // - // Save decoded data to data output stream - // - - if (dos != null) { - dos.writeByte((byte)nSubrects); - dos.write(buf); - } - - int b1, b2, sx, sy, sw, sh; - int i = 0; - - if ((subencoding & HextileSubrectsColoured) == 0) { - - // Sub-rectangles are all of the same color. - graphics.setColor(hextile_fg); - for (int j = 0; j < nSubrects; j++) { - b1 = buf[i++] & 0xFF; - b2 = buf[i++] & 0xFF; - sx = tx + (b1 >> 4); - sy = ty + (b1 & 0xf); - sw = (b2 >> 4) + 1; - sh = (b2 & 0xf) + 1; - graphics.fillRect(sx, sy, sw, sh); - } - } else if (bytesPerPixel == 1) { - - // BGR233 (8-bit color) version for colored sub-rectangles. - for (int j = 0; j < nSubrects; j++) { - hextile_fg = getColor256()[buf[i++] & 0xFF]; - b1 = buf[i++] & 0xFF; - b2 = buf[i++] & 0xFF; - sx = tx + (b1 >> 4); - sy = ty + (b1 & 0xf); - sw = (b2 >> 4) + 1; - sh = (b2 & 0xf) + 1; - graphics.setColor(hextile_fg); - graphics.fillRect(sx, sy, sw, sh); - } - - } else { - - // Full-color (24-bit) version for colored sub-rectangles. - for (int j = 0; j < nSubrects; j++) { - hextile_fg = new Color(buf[i+2] & 0xFF, - buf[i+1] & 0xFF, - buf[i] & 0xFF); - i += 4; - b1 = buf[i++] & 0xFF; - b2 = buf[i++] & 0xFF; - sx = tx + (b1 >> 4); - sy = ty + (b1 & 0xf); - sw = (b2 >> 4) + 1; - sh = (b2 & 0xf) + 1; - graphics.setColor(hextile_fg); - graphics.fillRect(sx, sy, sw, sh); - } - - } - } - - // These colors should be kept between handleHextileSubrect() calls. - private Color hextile_bg, hextile_fg; - // Repaitable object - private Repaintable repainableControl = null; -} diff --git a/java/src/com/tightvnc/decoder/RREDecoder.java b/java/src/com/tightvnc/decoder/RREDecoder.java deleted file mode 100644 index 02eb513f..00000000 --- a/java/src/com/tightvnc/decoder/RREDecoder.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.vncviewer.RfbInputStream; -import java.awt.Graphics; -import java.awt.Color; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -// -// Class that used for decoding RRE encoded data. -// - -public class RREDecoder extends RawDecoder { - - final static int EncodingRRE = 2; - - public RREDecoder(Graphics g, RfbInputStream is) { - super(g, is); - } - - public RREDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - } - - // - // Override handleRect method to decode RRE encoded data insted of - // raw pixel data. - // - - public void handleRect(int x, int y, int w, int h) throws IOException { - - // - // Write encoding ID to record output stream - // - - if (dos != null) { - dos.writeInt(RREDecoder.EncodingRRE); - } - - int nSubrects = rfbis.readU32(); - byte[] bg_buf = new byte[bytesPerPixel]; - rfbis.readFully(bg_buf); - Color pixel; - if (bytesPerPixel == 1) { - pixel = getColor256()[bg_buf[0] & 0xFF]; - } else { - pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF); - } - graphics.setColor(pixel); - graphics.fillRect(x, y, w, h); - byte[] buf = new byte[nSubrects * (bytesPerPixel + 8)]; - rfbis.readFully(buf); - DataInputStream ds = new DataInputStream(new ByteArrayInputStream(buf)); - - // - // Save decoded data to data output stream - // - if (dos != null) { - dos.writeInt(nSubrects); - dos.write(bg_buf); - dos.write(buf); - } - - int sx, sy, sw, sh; - for (int j = 0; j < nSubrects; j++) { - if (bytesPerPixel == 1) { - pixel = getColor256()[ds.readUnsignedByte()]; - } else { - ds.skip(4); - pixel = new Color(buf[j*12+2] & 0xFF, - buf[j*12+1] & 0xFF, - buf[j*12] & 0xFF); - } - sx = x + ds.readUnsignedShort(); - sy = y + ds.readUnsignedShort(); - sw = ds.readUnsignedShort(); - sh = ds.readUnsignedShort(); - - graphics.setColor(pixel); - graphics.fillRect(sx, sy, sw, sh); - } - } -} diff --git a/java/src/com/tightvnc/decoder/RawDecoder.java b/java/src/com/tightvnc/decoder/RawDecoder.java deleted file mode 100644 index 9ef167a7..00000000 --- a/java/src/com/tightvnc/decoder/RawDecoder.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.vncviewer.RfbInputStream; -import java.io.IOException; -import java.io.DataOutput; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.image.ColorModel; -import java.awt.image.DirectColorModel; -import java.awt.image.MemoryImageSource; -import java.awt.Color; -import java.awt.Toolkit; - -// -// This is base decoder class. -// Other classes will be childs of RawDecoder. -// - -public class RawDecoder { - final static int EncodingRaw = 0; - - public RawDecoder(Graphics g, RfbInputStream is) { - setGraphics(g); - setRfbInputStream(is); - } - - public RawDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - setGraphics(g); - setRfbInputStream(is); - setFrameBufferSize(frameBufferW, frameBufferH); - // FIXME: cm24 created in getColorModel24. - // Remove if no bugs - cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF); - } - - // - // Set methods to set value of non-static protected members of class - // - - public void setRfbInputStream(RfbInputStream is) { - rfbis = is; - } - - public void setGraphics(Graphics g) { - graphics = g; - } - - public void setBPP(int bpp) { - bytesPerPixel = bpp; - } - - public void setFrameBufferSize(int w, int h) { - framebufferWidth = w; - framebufferHeight = h; - } - - // - // FIXME: Rename this method after we don't need RecordInterface - // in RawDecoder class to record session - // - - public void setDataOutputStream(DataOutput os) { - dos = os; - } - - // - // Decodes Raw Pixels data and draw it into graphics - // - - public void handleRect(int x, int y, int w, int h) throws IOException, Exception { - - // - // Write encoding ID to record output stream - // - - if ((dos != null) && (enableEncodingRecordWritting)) { - dos.writeInt(RawDecoder.EncodingRaw); - } - - if (bytesPerPixel == 1) { - for (int dy = y; dy < y + h; dy++) { - if (pixels8 != null) { - rfbis.readFully(pixels8, dy * framebufferWidth + x, w); - } - // - // Save decoded data to record output stream - // - if (dos != null) { - dos.write(pixels8, dy * framebufferWidth + x, w); - } - } - } else { - byte[] buf = new byte[w * 4]; - int i, offset; - for (int dy = y; dy < y + h; dy++) { - rfbis.readFully(buf); - // - // Save decoded data to record output stream - // - if (dos != null) { - dos.write(buf); - } - offset = dy * framebufferWidth + x; - if (pixels24 != null) { - for (i = 0; i < w; i++) { - pixels24[offset + i] = - (buf[i * 4 + 2] & 0xFF) << 16 | - (buf[i * 4 + 1] & 0xFF) << 8 | - (buf[i * 4] & 0xFF); - } //for - } // if - } // for - } // else - handleUpdatedPixels(x, y, w, h); - } // void - - // - // Display newly updated area of pixels. - // - - protected void handleUpdatedPixels(int x, int y, int w, int h) { - // Draw updated pixels of the off-screen image. - pixelsSource.newPixels(x, y, w, h); - graphics.setClip(x, y, w, h); - graphics.drawImage(rawPixelsImage, 0, 0, null); - graphics.setClip(0, 0, framebufferWidth, framebufferHeight); - } - - // - // Updates pixels data. - // This method must be called when framebuffer is resized - // or BPP is changed. - // - - public void update() { - // Images with raw pixels should be re-allocated on every change - // of geometry or pixel format. - int fbWidth = framebufferWidth; - int fbHeight = framebufferHeight; - - if (bytesPerPixel == 1) { - pixels24 = null; - pixels8 = new byte[fbWidth * fbHeight]; - pixelsSource = new MemoryImageSource(fbWidth, fbHeight, getColorModel8(), - pixels8, 0, fbWidth); - } else { - pixels8 = null; - pixels24 = new int[fbWidth * fbHeight]; - pixelsSource = - new MemoryImageSource(fbWidth, fbHeight, cm24, pixels24, 0, fbWidth); - } - pixelsSource.setAnimated(true); - rawPixelsImage = Toolkit.getDefaultToolkit().createImage(pixelsSource); - } - - // - // Private static members access methods - // - - protected ColorModel getColorModel8() { - if (cm8 == null) { - cm8 = cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6)); - } - return cm8; - } - - protected ColorModel getColorModel24() { - if (cm24 == null) { - cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF); - } - return cm24; - } - - protected Color[]getColor256() { - if (color256 == null) { - color256 = new Color[256]; - for (int i = 0; i < 256; i++) - color256[i] = new Color(cm8.getRGB(i)); - } - return color256; - } - - // - // This method will be used by HextileDecoder to disable - // double writting encoding id to record stream. - // - // FIXME: Try to find better solution than this. - // - - protected void enableEncodingRecordWritting(boolean enable) { - enableEncodingRecordWritting = enable; - } - - // - // Unique data for every decoder (? maybe not ?) - // - - protected int bytesPerPixel = 4; - protected int framebufferWidth = 0; - protected int framebufferHeight = 0; - protected RfbInputStream rfbis = null; - protected Graphics graphics = null; - protected DataOutput dos = null; - protected boolean enableEncodingRecordWritting = true; - - // - // This data must be shared between decoders - // - - protected static byte []pixels8 = null; - protected static int []pixels24 = null; - protected static MemoryImageSource pixelsSource = null; - protected static Image rawPixelsImage = null; - - // - // Access to this static members only though protected methods - // - - private static ColorModel cm8 = null; - private static ColorModel cm24 = null; - private static Color []color256 = null; -} diff --git a/java/src/com/tightvnc/decoder/TightDecoder.java b/java/src/com/tightvnc/decoder/TightDecoder.java deleted file mode 100644 index 015f73cd..00000000 --- a/java/src/com/tightvnc/decoder/TightDecoder.java +++ /dev/null @@ -1,525 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.decoder.common.Repaintable; -import com.tightvnc.vncviewer.RfbInputStream; -import java.awt.Graphics; -import java.awt.Color; -import java.awt.Image; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.awt.image.ImageObserver; -import java.io.IOException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; - -// -// Class that used for decoding Tight encoded data. -// - -public class TightDecoder extends RawDecoder implements ImageObserver { - - final static int EncodingTight = 7; - - // - // Tight decoder constants - // - - final static int TightExplicitFilter = 0x04; - final static int TightFill = 0x08; - final static int TightJpeg = 0x09; - final static int TightMaxSubencoding = 0x09; - final static int TightFilterCopy = 0x00; - final static int TightFilterPalette = 0x01; - final static int TightFilterGradient = 0x02; - final static int TightMinToCompress = 12; - - // Tight encoder's data. - final static int tightZlibBufferSize = 512; - - public TightDecoder(Graphics g, RfbInputStream is) { - super(g, is); - tightInflaters = new Inflater[4]; - } - - public TightDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - tightInflaters = new Inflater[4]; - } - - // - // Set and get methods for private TightDecoder - // - - public void setRepainableControl(Repaintable r) { - repainatableControl = r; - } - - // - // JPEG processing statistic methods - // - - public long getNumJPEGRects() { - return statNumRectsTightJPEG; - } - - public void setNumJPEGRects(int v) { - statNumRectsTightJPEG = v; - } - - // - // Tight processing statistic methods - // - - public long getNumTightRects() { - return statNumRectsTight; - } - - public void setNumTightRects(int v) { - statNumRectsTight = v; - } - - // - // Handle a Tight-encoded rectangle. - // - - public void handleRect(int x, int y, int w, int h) throws Exception { - - // - // Write encoding ID to record output stream - // - - if (dos != null) { - dos.writeInt(TightDecoder.EncodingTight); - } - - int comp_ctl = rfbis.readU8(); - - if (dos != null) { - // Tell the decoder to flush each of the four zlib streams. - dos.writeByte(comp_ctl | 0x0F); - } - - // Flush zlib streams if we are told by the server to do so. - for (int stream_id = 0; stream_id < 4; stream_id++) { - if ((comp_ctl & 1) != 0 && tightInflaters[stream_id] != null) { - tightInflaters[stream_id] = null; - } - comp_ctl >>= 1; - } - - // Check correctness of subencoding value. - if (comp_ctl > TightDecoder.TightMaxSubencoding) { - throw new Exception("Incorrect tight subencoding: " + comp_ctl); - } - - // Handle solid-color rectangles. - if (comp_ctl == TightDecoder.TightFill) { - - if (bytesPerPixel == 1) { - int idx = rfbis.readU8(); - graphics.setColor(getColor256()[idx]); - if (dos != null) { - dos.writeByte(idx); - } - } else { - byte[] buf = new byte[3]; - rfbis.readFully(buf); - if (dos != null) { - dos.write(buf); - } - Color bg = new Color(0xFF000000 | (buf[0] & 0xFF) << 16 | - (buf[1] & 0xFF) << 8 | (buf[2] & 0xFF)); - graphics.setColor(bg); - } - graphics.fillRect(x, y, w, h); - repainatableControl.scheduleRepaint(x, y, w, h); - return; - - } - - if (comp_ctl == TightDecoder.TightJpeg) { - - statNumRectsTightJPEG++; - - // Read JPEG data. - byte[] jpegData = new byte[rfbis.readCompactLen()]; - rfbis.readFully(jpegData); - if (dos != null) { - recordCompactLen(jpegData.length); - dos.write(jpegData); - } - - // Create an Image object from the JPEG data. - Image jpegImage = Toolkit.getDefaultToolkit().createImage(jpegData); - - // Remember the rectangle where the image should be drawn. - jpegRect = new Rectangle(x, y, w, h); - - // Let the imageUpdate() method do the actual drawing, here just - // wait until the image is fully loaded and drawn. - synchronized(jpegRect) { - Toolkit.getDefaultToolkit().prepareImage(jpegImage, -1, -1, this); - try { - // Wait no longer than three seconds. - jpegRect.wait(3000); - } catch (InterruptedException e) { - throw new Exception("Interrupted while decoding JPEG image"); - } - } - - // Done, jpegRect is not needed any more. - jpegRect = null; - return; - - } else { - statNumRectsTight++; - } - - // Read filter id and parameters. - int numColors = 0, rowSize = w; - byte[] palette8 = new byte[2]; - int[] palette24 = new int[256]; - boolean useGradient = false; - if ((comp_ctl & TightDecoder.TightExplicitFilter) != 0) { - int filter_id = rfbis.readU8(); - if (dos != null) { - dos.writeByte(filter_id); - } - if (filter_id == TightDecoder.TightFilterPalette) { - numColors = rfbis.readU8() + 1; - if (dos != null) { - dos.writeByte((numColors - 1)); - } - if (bytesPerPixel == 1) { - if (numColors != 2) { - throw new Exception("Incorrect tight palette size: " + numColors); - } - rfbis.readFully(palette8); - if (dos != null) { - dos.write(palette8); - } - } else { - byte[] buf = new byte[numColors * 3]; - rfbis.readFully(buf); - if (dos != null) { - dos.write(buf); - } - for (int i = 0; i < numColors; i++) { - palette24[i] = ((buf[i * 3] & 0xFF) << 16 | - (buf[i * 3 + 1] & 0xFF) << 8 | - (buf[i * 3 + 2] & 0xFF)); - } - } - if (numColors == 2) { - rowSize = (w + 7) / 8; - } - } else if (filter_id == TightDecoder.TightFilterGradient) { - useGradient = true; - } else if (filter_id != TightDecoder.TightFilterCopy) { - throw new Exception("Incorrect tight filter id: " + filter_id); - } - } - if (numColors == 0 && bytesPerPixel == 4) - rowSize *= 3; - - // Read, optionally uncompress and decode data. - int dataSize = h * rowSize; - if (dataSize < TightDecoder.TightMinToCompress) { - // Data size is small - not compressed with zlib. - if (numColors != 0) { - // Indexed colors. - byte[] indexedData = new byte[dataSize]; - rfbis.readFully(indexedData); - if (dos != null) { - dos.write(indexedData); - } - if (numColors == 2) { - // Two colors. - if (bytesPerPixel == 1) { - decodeMonoData(x, y, w, h, indexedData, palette8); - } else { - decodeMonoData(x, y, w, h, indexedData, palette24); - } - } else { - // 3..255 colors (assuming bytesPixel == 4). - int i = 0; - for (int dy = y; dy < y + h; dy++) { - for (int dx = x; dx < x + w; dx++) { - pixels24[dy * framebufferWidth + dx] = - palette24[indexedData[i++] & 0xFF]; - } - } - } - } else if (useGradient) { - // "Gradient"-processed data - byte[] buf = new byte[w * h * 3]; - rfbis.readFully(buf); - if (dos != null) { - dos.write(buf); - } - decodeGradientData(x, y, w, h, buf); - } else { - // Raw truecolor data. - if (bytesPerPixel == 1) { - for (int dy = y; dy < y + h; dy++) { - rfbis.readFully(pixels8, dy * framebufferWidth + x, w); - if (dos != null) { - dos.write(pixels8, dy * framebufferWidth + x, w); - } - } - } else { - byte[] buf = new byte[w * 3]; - int i, offset; - for (int dy = y; dy < y + h; dy++) { - rfbis.readFully(buf); - if (dos != null) { - dos.write(buf); - } - offset = dy * framebufferWidth + x; - for (i = 0; i < w; i++) { - pixels24[offset + i] = - (buf[i * 3] & 0xFF) << 16 | - (buf[i * 3 + 1] & 0xFF) << 8 | - (buf[i * 3 + 2] & 0xFF); - } - } - } - } - } else { - // Data was compressed with zlib. - int zlibDataLen = rfbis.readCompactLen(); - byte[] zlibData = new byte[zlibDataLen]; - rfbis.readFully(zlibData); - int stream_id = comp_ctl & 0x03; - if (tightInflaters[stream_id] == null) { - tightInflaters[stream_id] = new Inflater(); - } - Inflater myInflater = tightInflaters[stream_id]; - myInflater.setInput(zlibData); - byte[] buf = new byte[dataSize]; - myInflater.inflate(buf); - if (dos != null) { - recordCompressedData(buf); - } - - if (numColors != 0) { - // Indexed colors. - if (numColors == 2) { - // Two colors. - if (bytesPerPixel == 1) { - decodeMonoData(x, y, w, h, buf, palette8); - } else { - decodeMonoData(x, y, w, h, buf, palette24); - } - } else { - // More than two colors (assuming bytesPixel == 4). - int i = 0; - for (int dy = y; dy < y + h; dy++) { - for (int dx = x; dx < x + w; dx++) { - pixels24[dy * framebufferWidth + dx] = - palette24[buf[i++] & 0xFF]; - } - } - } - } else if (useGradient) { - // Compressed "Gradient"-filtered data (assuming bytesPixel == 4). - decodeGradientData(x, y, w, h, buf); - } else { - // Compressed truecolor data. - if (bytesPerPixel == 1) { - int destOffset = y * framebufferWidth + x; - for (int dy = 0; dy < h; dy++) { - System.arraycopy(buf, dy * w, pixels8, destOffset, w); - destOffset += framebufferWidth; - } - } else { - int srcOffset = 0; - int destOffset, i; - for (int dy = 0; dy < h; dy++) { - myInflater.inflate(buf); - destOffset = (y + dy) * framebufferWidth + x; - for (i = 0; i < w; i++) { - RawDecoder.pixels24[destOffset + i] = - (buf[srcOffset] & 0xFF) << 16 | - (buf[srcOffset + 1] & 0xFF) << 8 | - (buf[srcOffset + 2] & 0xFF); - srcOffset += 3; - } - } - } - } - } - handleUpdatedPixels(x, y, w, h); - } - - // - // Decode 1bpp-encoded bi-color rectangle (8-bit and 24-bit versions). - // - - private void decodeMonoData(int x, int y, int w, int h, byte[] src, byte[] palette) { - - int dx, dy, n; - int i = y * framebufferWidth + x; - int rowBytes = (w + 7) / 8; - byte b; - - for (dy = 0; dy < h; dy++) { - for (dx = 0; dx < w / 8; dx++) { - b = src[dy*rowBytes+dx]; - for (n = 7; n >= 0; n--) - pixels8[i++] = palette[b >> n & 1]; - } - for (n = 7; n >= 8 - w % 8; n--) { - pixels8[i++] = palette[src[dy*rowBytes+dx] >> n & 1]; - } - i += (framebufferWidth - w); - } - } - - private void decodeMonoData(int x, int y, int w, int h, byte[] src, int[] palette) { - - int dx, dy, n; - int i = y * framebufferWidth + x; - int rowBytes = (w + 7) / 8; - byte b; - - for (dy = 0; dy < h; dy++) { - for (dx = 0; dx < w / 8; dx++) { - b = src[dy*rowBytes+dx]; - for (n = 7; n >= 0; n--) - pixels24[i++] = palette[b >> n & 1]; - } - for (n = 7; n >= 8 - w % 8; n--) { - pixels24[i++] = palette[src[dy*rowBytes+dx] >> n & 1]; - } - i += (framebufferWidth - w); - } - } - - // - // Decode data processed with the "Gradient" filter. - // - - private void decodeGradientData (int x, int y, int w, int h, byte[] buf) { - - int dx, dy, c; - byte[] prevRow = new byte[w * 3]; - byte[] thisRow = new byte[w * 3]; - byte[] pix = new byte[3]; - int[] est = new int[3]; - - int offset = y * framebufferWidth + x; - - for (dy = 0; dy < h; dy++) { - - /* First pixel in a row */ - for (c = 0; c < 3; c++) { - pix[c] = (byte)(prevRow[c] + buf[dy * w * 3 + c]); - thisRow[c] = pix[c]; - } - pixels24[offset++] = - (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF); - - /* Remaining pixels of a row */ - for (dx = 1; dx < w; dx++) { - for (c = 0; c < 3; c++) { - est[c] = ((prevRow[dx * 3 + c] & 0xFF) + (pix[c] & 0xFF) - - (prevRow[(dx-1) * 3 + c] & 0xFF)); - if (est[c] > 0xFF) { - est[c] = 0xFF; - } else if (est[c] < 0x00) { - est[c] = 0x00; - } - pix[c] = (byte)(est[c] + buf[(dy * w + dx) * 3 + c]); - thisRow[dx * 3 + c] = pix[c]; - } - pixels24[offset++] = - (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF); - } - - System.arraycopy(thisRow, 0, prevRow, 0, w * 3); - offset += (framebufferWidth - w); - } - } - - // - // Override the ImageObserver interface method to handle drawing of - // JPEG-encoded data. - // - - public boolean imageUpdate(Image img, int infoflags, - int x, int y, int width, int height) { - if ((infoflags & (ALLBITS | ABORT)) == 0) { - return true; // We need more image data. - } else { - // If the whole image is available, draw it now. - if ((infoflags & ALLBITS) != 0) { - if (jpegRect != null) { - synchronized(jpegRect) { - graphics.drawImage(img, jpegRect.x, jpegRect.y, null); - repainatableControl.scheduleRepaint(jpegRect.x, jpegRect.y, - jpegRect.width, jpegRect.height); - jpegRect.notify(); - } - } - } - return false; // All image data was processed. - } - } - - // - // Write an integer in compact representation (1..3 bytes) into the - // recorded session file. - // - - void recordCompactLen(int len) throws IOException { - byte[] buf = new byte[3]; - int bytes = 0; - buf[bytes++] = (byte)(len & 0x7F); - if (len > 0x7F) { - buf[bytes-1] |= 0x80; - buf[bytes++] = (byte)(len >> 7 & 0x7F); - if (len > 0x3FFF) { - buf[bytes-1] |= 0x80; - buf[bytes++] = (byte)(len >> 14 & 0xFF); - } - } - if (dos != null) dos.write(buf, 0, bytes); - } - - // - // Compress and write the data into the recorded session file. - // - - void recordCompressedData(byte[] data, int off, int len) throws IOException { - Deflater deflater = new Deflater(); - deflater.setInput(data, off, len); - int bufSize = len + len / 100 + 12; - byte[] buf = new byte[bufSize]; - deflater.finish(); - int compressedSize = deflater.deflate(buf); - recordCompactLen(compressedSize); - if (dos != null) dos.write(buf, 0, compressedSize); - } - - void recordCompressedData(byte[] data) throws IOException { - recordCompressedData(data, 0, data.length); - } - - // - // Private members - // - - private Inflater[] tightInflaters; - // Since JPEG images are loaded asynchronously, we have to remember - // their position in the framebuffer. Also, this jpegRect object is - // used for synchronization between the rfbThread and a JVM's thread - // which decodes and loads JPEG images. - private Rectangle jpegRect; - private Repaintable repainatableControl = null; - // Jpeg decoding statistics - private long statNumRectsTightJPEG = 0; - // Tight decoding statistics - private long statNumRectsTight = 0; -} diff --git a/java/src/com/tightvnc/decoder/ZRLEDecoder.java b/java/src/com/tightvnc/decoder/ZRLEDecoder.java deleted file mode 100644 index a22da908..00000000 --- a/java/src/com/tightvnc/decoder/ZRLEDecoder.java +++ /dev/null @@ -1,310 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.vncviewer.InStream; -import com.tightvnc.vncviewer.RfbInputStream; -import com.tightvnc.vncviewer.ZlibInStream; -import java.awt.Graphics; -import com.tightvnc.vncviewer.MemInStream; -import java.awt.Color; -import java.awt.Toolkit; -import java.awt.image.MemoryImageSource; -import java.io.IOException; - -// -// Class that used for decoding ZRLE encoded data. -// - -public class ZRLEDecoder extends RawDecoder { - - final static int EncodingZRLE = 16; - - public ZRLEDecoder(Graphics g, RfbInputStream is) { - super(g, is); - } - - public ZRLEDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - } - - // - // Handle a ZRLE-encoded rectangle. - // - // FIXME: Currently, session recording is not fully supported for ZRLE. - // - - public void handleRect(int x, int y, int w, int h) throws IOException, Exception { - - // - // Write encoding ID to record output stream - // - - if (dos != null) { - dos.writeInt(ZRLEDecoder.EncodingZRLE); - } - - if (zrleInStream == null) - zrleInStream = new ZlibInStream(); - - int nBytes = rfbis.readU32(); - if (nBytes > 64 * 1024 * 1024) - throw new Exception("ZRLE decoder: illegal compressed data size"); - - if (zrleBuf == null || zrleBufLen < nBytes) { - zrleBufLen = nBytes + 4096; - zrleBuf = new byte[zrleBufLen]; - } - - // FIXME: Do not wait for all the data before decompression. - rfbis.readFully(zrleBuf, 0, nBytes); - - // - // Override handleRect method to decode RRE encoded data insted of - // raw pixel data. - // - - if (dos != null) { - if (!zrleRecWarningShown) { - System.out.println("Warning: ZRLE session can be recorded" + - " only from the beginning"); - System.out.println("Warning: Recorded file may be corrupted"); - zrleRecWarningShown = true; - } - } - - zrleInStream.setUnderlying(new MemInStream(zrleBuf, 0, nBytes), nBytes); - - for (int ty = y; ty < y+h; ty += 64) { - - int th = Math.min(y+h-ty, 64); - - for (int tx = x; tx < x+w; tx += 64) { - - int tw = Math.min(x+w-tx, 64); - - int mode = zrleInStream.readU8(); - boolean rle = (mode & 128) != 0; - int palSize = mode & 127; - int[] palette = new int[128]; - - readZrlePalette(palette, palSize); - - if (palSize == 1) { - int pix = palette[0]; - Color c = (bytesPerPixel == 1) ? - getColor256()[pix] : new Color(0xFF000000 | pix); - graphics.setColor(c); - graphics.fillRect(tx, ty, tw, th); - continue; - } - - if (!rle) { - if (palSize == 0) { - readZrleRawPixels(tw, th); - } else { - readZrlePackedPixels(tw, th, palette, palSize); - } - } else { - if (palSize == 0) { - readZrlePlainRLEPixels(tw, th); - } else { - readZrlePackedRLEPixels(tw, th, palette); - } - } - handleUpdatedZrleTile(tx, ty, tw, th); - } - } - zrleInStream.reset(); - } - - // - // Override update() method cause we have own data that - // must be updated when framebuffer is resized or BPP is changed - // - - public void update() { - // Images with raw pixels should be re-allocated on every change - // of geometry or pixel format. - int fbWidth = framebufferWidth; - int fbHeight = framebufferHeight; - - if (bytesPerPixel == 1) { - RawDecoder.pixels24 = null; - RawDecoder.pixels8 = new byte[fbWidth * fbHeight]; - RawDecoder.pixelsSource = new MemoryImageSource(fbWidth, fbHeight, getColorModel8(), pixels8, 0, fbWidth); - zrleTilePixels24 = null; - zrleTilePixels8 = new byte[64 * 64]; - } else { - RawDecoder.pixels8 = null; - RawDecoder.pixels24 = new int[fbWidth * fbHeight]; - RawDecoder.pixelsSource = - new MemoryImageSource(fbWidth, fbHeight, getColorModel24(), pixels24, 0, fbWidth); - zrleTilePixels8 = null; - zrleTilePixels24 = new int[64 * 64]; - } - RawDecoder.pixelsSource.setAnimated(true); - RawDecoder.rawPixelsImage = Toolkit.getDefaultToolkit().createImage(pixelsSource); - } - - // - // Copy pixels from zrleTilePixels8 or zrleTilePixels24, then update. - // - - private void handleUpdatedZrleTile(int x, int y, int w, int h) { - Object src, dst; - if (bytesPerPixel == 1) { - src = zrleTilePixels8; dst = pixels8; - } else { - src = zrleTilePixels24; dst = pixels24; - } - int offsetSrc = 0; - int offsetDst = (y * framebufferWidth + x); - for (int j = 0; j < h; j++) { - System.arraycopy(src, offsetSrc, dst, offsetDst, w); - offsetSrc += w; - offsetDst += framebufferWidth; - } - handleUpdatedPixels(x, y, w, h); - } - - // - // Private methods for reading ZRLE data - // - - private int readPixel(InStream is) throws Exception { - int pix; - if (bytesPerPixel == 1) { - pix = is.readU8(); - } else { - int p1 = is.readU8(); - int p2 = is.readU8(); - int p3 = is.readU8(); - pix = (p3 & 0xFF) << 16 | (p2 & 0xFF) << 8 | (p1 & 0xFF); - } - return pix; - } - - private void readPixels(InStream is, int[] dst, int count) throws Exception { - if (bytesPerPixel == 1) { - byte[] buf = new byte[count]; - is.readBytes(buf, 0, count); - for (int i = 0; i < count; i++) { - dst[i] = (int)buf[i] & 0xFF; - } - } else { - byte[] buf = new byte[count * 3]; - is.readBytes(buf, 0, count * 3); - for (int i = 0; i < count; i++) { - dst[i] = ((buf[i*3+2] & 0xFF) << 16 | - (buf[i*3+1] & 0xFF) << 8 | - (buf[i*3] & 0xFF)); - } - } - } - - private void readZrlePalette(int[] palette, int palSize) throws Exception { - readPixels(zrleInStream, palette, palSize); - } - - private void readZrleRawPixels(int tw, int th) throws Exception { - if (bytesPerPixel == 1) { - zrleInStream.readBytes(zrleTilePixels8, 0, tw * th); - } else { - readPixels(zrleInStream, zrleTilePixels24, tw * th); /// - } - } - - private void readZrlePackedPixels(int tw, int th, int[] palette, int palSize) - throws Exception { - - int bppp = ((palSize > 16) ? 8 : - ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1))); - int ptr = 0; - - for (int i = 0; i < th; i++) { - int eol = ptr + tw; - int b = 0; - int nbits = 0; - - while (ptr < eol) { - if (nbits == 0) { - b = zrleInStream.readU8(); - nbits = 8; - } - nbits -= bppp; - int index = (b >> nbits) & ((1 << bppp) - 1) & 127; - if (bytesPerPixel == 1) { - zrleTilePixels8[ptr++] = (byte)palette[index]; - } else { - zrleTilePixels24[ptr++] = palette[index]; - } - } - } - } - - private void readZrlePlainRLEPixels(int tw, int th) throws Exception { - int ptr = 0; - int end = ptr + tw * th; - while (ptr < end) { - int pix = readPixel(zrleInStream); - int len = 1; - int b; - do { - b = zrleInStream.readU8(); - len += b; - } while (b == 255); - - if (!(len <= end - ptr)) - throw new Exception("ZRLE decoder: assertion failed" + - " (len <= end-ptr)"); - - if (bytesPerPixel == 1) { - while (len-- > 0) zrleTilePixels8[ptr++] = (byte)pix; - } else { - while (len-- > 0) zrleTilePixels24[ptr++] = pix; - } - } - } - - private void readZrlePackedRLEPixels(int tw, int th, int[] palette) - throws Exception { - - int ptr = 0; - int end = ptr + tw * th; - while (ptr < end) { - int index = zrleInStream.readU8(); - int len = 1; - if ((index & 128) != 0) { - int b; - do { - b = zrleInStream.readU8(); - len += b; - } while (b == 255); - - if (!(len <= end - ptr)) - throw new Exception("ZRLE decoder: assertion failed" + - " (len <= end - ptr)"); - } - - index &= 127; - int pix = palette[index]; - - if (bytesPerPixel == 1) { - while (len-- > 0) zrleTilePixels8[ptr++] = (byte)pix; - } else { - while (len-- > 0) zrleTilePixels24[ptr++] = pix; - } - } - } - - // - // ZRLE encoder's data. - // - - private byte[] zrleBuf; - private int zrleBufLen = 0; - private byte[] zrleTilePixels8; - private int[] zrleTilePixels24; - private ZlibInStream zrleInStream; - private boolean zrleRecWarningShown = false; -} diff --git a/java/src/com/tightvnc/decoder/ZlibDecoder.java b/java/src/com/tightvnc/decoder/ZlibDecoder.java deleted file mode 100644 index 1370da15..00000000 --- a/java/src/com/tightvnc/decoder/ZlibDecoder.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.tightvnc.decoder; - -import com.tightvnc.vncviewer.RfbInputStream; -import java.awt.Graphics; -import java.io.IOException; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -// -// Class that used for decoding ZLib encoded data. -// - -public class ZlibDecoder extends RawDecoder { - - final static int EncodingZlib = 6; - - public ZlibDecoder(Graphics g, RfbInputStream is) { - super(g, is); - } - - public ZlibDecoder(Graphics g, RfbInputStream is, int frameBufferW, - int frameBufferH) { - super(g, is, frameBufferW, frameBufferH); - } - - // - // Override handleRect method to decode ZLib encoded data insted of - // raw pixel data. - // - - public void handleRect(int x, int y, int w, int h) throws IOException { - - // - // Write encoding ID to record output stream. - // Remark: we forced changed encoding from zlib to raw - // cause at this moment we cannot save data in zlib encoding. - // - - if (dos != null) { - dos.writeInt(RawDecoder.EncodingRaw); - } - - int nBytes = rfbis.readU32(); - - if (zlibBuf == null || zlibBufLen < nBytes) { - zlibBufLen = nBytes * 2; - zlibBuf = new byte[zlibBufLen]; - } - - rfbis.readFully(zlibBuf, 0, nBytes); - - if (zlibInflater == null) { - zlibInflater = new Inflater(); - } - zlibInflater.setInput(zlibBuf, 0, nBytes); - - try { - if (bytesPerPixel == 1) { - for (int dy = y; dy < y + h; dy++) { - zlibInflater.inflate(pixels8, dy * framebufferWidth + x, w); - - // - // Save decoded raw data to data output stream - // - - if (dos != null) - dos.write(pixels8, dy * framebufferWidth + x, w); - } - } else { - byte[] buf = new byte[w * 4]; - int i, offset; - for (int dy = y; dy < y + h; dy++) { - zlibInflater.inflate(buf); - offset = dy * framebufferWidth + x; - for (i = 0; i < w; i++) { - RawDecoder.pixels24[offset + i] = - (buf[i * 4 + 2] & 0xFF) << 16 | - (buf[i * 4 + 1] & 0xFF) << 8 | - (buf[i * 4] & 0xFF); - } - - // - // Save decoded raw data to data output stream - // - - if (dos != null) - dos.write(buf); - } - } - } catch (DataFormatException ex) { - ex.printStackTrace(); - } - handleUpdatedPixels(x, y, w, h); - } - - // - // Zlib encoder's data. - // - - protected byte[] zlibBuf; - protected int zlibBufLen = 0; - protected Inflater zlibInflater; -} diff --git a/java/src/com/tightvnc/decoder/common/Repaintable.java b/java/src/com/tightvnc/decoder/common/Repaintable.java deleted file mode 100644 index de11f4c8..00000000 --- a/java/src/com/tightvnc/decoder/common/Repaintable.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.tightvnc.decoder.common; - -public interface Repaintable { - - public void scheduleRepaint(int x, int y, int w, int h); - -} diff --git a/java/src/com/tightvnc/vncviewer/AuthPanel.java b/java/src/com/tightvnc/vncviewer/AuthPanel.java deleted file mode 100644 index 28be7218..00000000 --- a/java/src/com/tightvnc/vncviewer/AuthPanel.java +++ /dev/null @@ -1,118 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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(); - } - -} diff --git a/java/src/com/tightvnc/vncviewer/ButtonPanel.java b/java/src/com/tightvnc/vncviewer/ButtonPanel.java deleted file mode 100644 index 985a9c2a..00000000 --- a/java/src/com/tightvnc/vncviewer/ButtonPanel.java +++ /dev/null @@ -1,222 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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; - 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; - - 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); - } - - /** - * 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. - // - - public void enableButtons() { - disconnectButton.setEnabled(true); - clipboardButton.setEnabled(true); - refreshButton.setEnabled(true); - if (selectButton != null) { - selectButton.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); - if (selectButton != null) { - selectButton.setEnabled(false); - } - } - - // - // 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() == 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; - - 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(); - } - } 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); - } - } - } - } -} - diff --git a/java/src/com/tightvnc/vncviewer/CapabilityInfo.java b/java/src/com/tightvnc/vncviewer/CapabilityInfo.java deleted file mode 100644 index 092f53e0..00000000 --- a/java/src/com/tightvnc/vncviewer/CapabilityInfo.java +++ /dev/null @@ -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.tightvnc.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; -} diff --git a/java/src/com/tightvnc/vncviewer/CapsContainer.java b/java/src/com/tightvnc/vncviewer/CapsContainer.java deleted file mode 100644 index b9acbf41..00000000 --- a/java/src/com/tightvnc/vncviewer/CapsContainer.java +++ /dev/null @@ -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.tightvnc.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; -} - diff --git a/java/src/com/tightvnc/vncviewer/ClipboardFrame.java b/java/src/com/tightvnc/vncviewer/ClipboardFrame.java deleted file mode 100644 index 2b11eb89..00000000 --- a/java/src/com/tightvnc/vncviewer/ClipboardFrame.java +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright (C) 2001 HorizonLive.com, Inc. All Rights Reserved. -// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -// -// This is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this software; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. -// - -// -// Clipboard frame. -// - -package com.tightvnc.vncviewer; - -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("TigerVNC Clipboard"); - - viewer = v; - - GridBagLayout gridbag = new GridBagLayout(); - setLayout(gridbag); - - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.fill = GridBagConstraints.BOTH; - gbc.weighty = 1.0; - - textArea = new TextArea(5, 40); - gridbag.setConstraints(textArea, gbc); - add(textArea); - - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.weightx = 1.0; - gbc.weighty = 0.0; - gbc.gridwidth = 1; - - clearButton = new Button("Clear"); - gridbag.setConstraints(clearButton, gbc); - add(clearButton); - clearButton.addActionListener(this); - - closeButton = new Button("Close"); - gridbag.setConstraints(closeButton, gbc); - add(closeButton); - closeButton.addActionListener(this); - - pack(); - - addWindowListener(this); - } - - - // - // Set the cut text from the RFB server. - // - - void setCutText(String text) { - selection = text; - textArea.setText(text); - if (isVisible()) { - textArea.selectAll(); - } - } - - - // - // When the focus leaves the window, see if we have new cut text and - // if so send it to the RFB server. - // - - public void windowDeactivated (WindowEvent evt) { - if (selection != null && !selection.equals(textArea.getText())) { - selection = textArea.getText(); - viewer.setCutText(selection); - } - } - - // - // Close our window properly. - // - - public void windowClosing(WindowEvent evt) { - setVisible(false); - } - - // - // Ignore window events we're not interested in. - // - - public void windowActivated(WindowEvent evt) {} - public void windowOpened(WindowEvent evt) {} - public void windowClosed(WindowEvent evt) {} - public void windowIconified(WindowEvent evt) {} - public void windowDeiconified(WindowEvent evt) {} - - - // - // Respond to button presses - // - - public void actionPerformed(ActionEvent evt) { - if (evt.getSource() == clearButton) { - textArea.setText(""); - } else if (evt.getSource() == closeButton) { - setVisible(false); - } - } -} diff --git a/java/src/com/tightvnc/vncviewer/DesCipher.java b/java/src/com/tightvnc/vncviewer/DesCipher.java deleted file mode 100644 index 9ebeaa87..00000000 --- a/java/src/com/tightvnc/vncviewer/DesCipher.java +++ /dev/null @@ -1,498 +0,0 @@ -// -// This DES class has been extracted from package Acme.Crypto for use in VNC. -// The bytebit[] array has been reversed so that the most significant bit -// in each byte of the key is ignored, not the least significant. Also the -// unnecessary odd parity code has been removed. -// -// These changes are: -// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// - -// DesCipher - the DES encryption method -// -// The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is: -// -// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. -// -// Permission to use, copy, modify, and distribute this software -// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and -// without fee is hereby granted, provided that this copyright notice is kept -// intact. -// -// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY -// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE -// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR -// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. -// -// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE -// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE -// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT -// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE -// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE -// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE -// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP -// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR -// HIGH RISK ACTIVITIES. -// -// -// The rest is: -// -// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. -// -// Visit the ACME Labs Java page for up-to-date versions of this and other -// fine Java utilities: http://www.acme.com/java/ - - -package com.tightvnc.vncviewer; - -import java.io.*; - -/// The DES encryption method. -// <P> -// This is surprisingly fast, for pure Java. On a SPARC 20, wrapped -// in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream, -// it does around 7000 bytes/second. -// <P> -// Most of this code is by Dave Zimmerman <dzimm@widget.com>, and is -// Copyright (c) 1996 Widget Workshop, Inc. See the source file for details. -// <P> -// <A HREF="/resources/classes/Acme/Crypto/DesCipher.java">Fetch the software.</A><BR> -// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A> -// <P> -// @see Des3Cipher -// @see EncryptedOutputStream -// @see EncryptedInputStream - -public class DesCipher - { - - // Constructor, byte-array key. - public DesCipher( byte[] key ) - { - setKey( key ); - } - - // Key routines. - - private int[] encryptKeys = new int[32]; - private int[] decryptKeys = new int[32]; - - /// Set the key. - public void setKey( byte[] key ) - { - deskey( key, true, encryptKeys ); - deskey( key, false, decryptKeys ); - } - - // Turn an 8-byte key into internal keys. - private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) - { - int i, j, l, m, n; - int[] pc1m = new int[56]; - int[] pcr = new int[56]; - int[] kn = new int[32]; - - for ( j = 0; j < 56; ++j ) - { - l = pc1[j]; - m = l & 07; - pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0; - } - - for ( i = 0; i < 16; ++i ) - { - if ( encrypting ) - m = i << 1; - else - m = (15-i) << 1; - n = m+1; - kn[m] = kn[n] = 0; - for ( j = 0; j < 28; ++j ) - { - l = j+totrot[i]; - if ( l < 28 ) - pcr[j] = pc1m[l]; - else - pcr[j] = pc1m[l-28]; - } - for ( j=28; j < 56; ++j ) - { - l = j+totrot[i]; - if ( l < 56 ) - pcr[j] = pc1m[l]; - else - pcr[j] = pc1m[l-28]; - } - for ( j = 0; j < 24; ++j ) - { - if ( pcr[pc2[j]] != 0 ) - kn[m] |= bigbyte[j]; - if ( pcr[pc2[j+24]] != 0 ) - kn[n] |= bigbyte[j]; - } - } - cookey( kn, KnL ); - } - - private void cookey( int[] raw, int KnL[] ) - { - int raw0, raw1; - int rawi, KnLi; - int i; - - for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) - { - raw0 = raw[rawi++]; - raw1 = raw[rawi++]; - KnL[KnLi] = (raw0 & 0x00fc0000) << 6; - KnL[KnLi] |= (raw0 & 0x00000fc0) << 10; - KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10; - KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6; - ++KnLi; - KnL[KnLi] = (raw0 & 0x0003f000) << 12; - KnL[KnLi] |= (raw0 & 0x0000003f) << 16; - KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4; - KnL[KnLi] |= (raw1 & 0x0000003f); - ++KnLi; - } - } - - - // Block encryption routines. - - private int[] tempInts = new int[2]; - - /// Encrypt a block of eight bytes. - public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) - { - squashBytesToInts( clearText, clearOff, tempInts, 0, 2 ); - des( tempInts, tempInts, encryptKeys ); - spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 ); - } - - /// Decrypt a block of eight bytes. - public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) - { - squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 ); - des( tempInts, tempInts, decryptKeys ); - spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 ); - } - - // The DES function. - private void des( int[] inInts, int[] outInts, int[] keys ) - { - int fval, work, right, leftt; - int round; - int keysi = 0; - - leftt = inInts[0]; - right = inInts[1]; - - work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f; - right ^= work; - leftt ^= (work << 4); - - work = ((leftt >>> 16) ^ right) & 0x0000ffff; - right ^= work; - leftt ^= (work << 16); - - work = ((right >>> 2) ^ leftt) & 0x33333333; - leftt ^= work; - right ^= (work << 2); - - work = ((right >>> 8) ^ leftt) & 0x00ff00ff; - leftt ^= work; - right ^= (work << 8); - right = (right << 1) | ((right >>> 31) & 1); - - work = (leftt ^ right) & 0xaaaaaaaa; - leftt ^= work; - right ^= work; - leftt = (leftt << 1) | ((leftt >>> 31) & 1); - - for ( round = 0; round < 8; ++round ) - { - work = (right << 28) | (right >>> 4); - work ^= keys[keysi++]; - fval = SP7[ work & 0x0000003f ]; - fval |= SP5[(work >>> 8) & 0x0000003f ]; - fval |= SP3[(work >>> 16) & 0x0000003f ]; - fval |= SP1[(work >>> 24) & 0x0000003f ]; - work = right ^ keys[keysi++]; - fval |= SP8[ work & 0x0000003f ]; - fval |= SP6[(work >>> 8) & 0x0000003f ]; - fval |= SP4[(work >>> 16) & 0x0000003f ]; - fval |= SP2[(work >>> 24) & 0x0000003f ]; - leftt ^= fval; - work = (leftt << 28) | (leftt >>> 4); - work ^= keys[keysi++]; - fval = SP7[ work & 0x0000003f ]; - fval |= SP5[(work >>> 8) & 0x0000003f ]; - fval |= SP3[(work >>> 16) & 0x0000003f ]; - fval |= SP1[(work >>> 24) & 0x0000003f ]; - work = leftt ^ keys[keysi++]; - fval |= SP8[ work & 0x0000003f ]; - fval |= SP6[(work >>> 8) & 0x0000003f ]; - fval |= SP4[(work >>> 16) & 0x0000003f ]; - fval |= SP2[(work >>> 24) & 0x0000003f ]; - right ^= fval; - } - - right = (right << 31) | (right >>> 1); - work = (leftt ^ right) & 0xaaaaaaaa; - leftt ^= work; - right ^= work; - leftt = (leftt << 31) | (leftt >>> 1); - work = ((leftt >>> 8) ^ right) & 0x00ff00ff; - right ^= work; - leftt ^= (work << 8); - work = ((leftt >>> 2) ^ right) & 0x33333333; - right ^= work; - leftt ^= (work << 2); - work = ((right >>> 16) ^ leftt) & 0x0000ffff; - leftt ^= work; - right ^= (work << 16); - work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f; - leftt ^= work; - right ^= (work << 4); - outInts[0] = right; - outInts[1] = leftt; - } - - - // Tables, permutations, S-boxes, etc. - - private static byte[] bytebit = { - (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08, - (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80 - }; - private static int[] bigbyte = { - 0x800000, 0x400000, 0x200000, 0x100000, - 0x080000, 0x040000, 0x020000, 0x010000, - 0x008000, 0x004000, 0x002000, 0x001000, - 0x000800, 0x000400, 0x000200, 0x000100, - 0x000080, 0x000040, 0x000020, 0x000010, - 0x000008, 0x000004, 0x000002, 0x000001 - }; - private static byte[] pc1 = { - (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8, - (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17, - (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26, - (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35, - (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14, - (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21, - (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28, - (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3 - }; - private static int[] totrot = { - 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 - }; - - private static byte[] pc2 = { - (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4, - (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9, - (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7, - (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1, - (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54, - (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47, - (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52, - (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31, - }; - - private static int[] SP1 = { - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 - }; - private static int[] SP2 = { - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 - }; - private static int[] SP3 = { - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 - }; - private static int[] SP4 = { - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 - }; - private static int[] SP5 = { - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 - }; - private static int[] SP6 = { - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 - }; - private static int[] SP7 = { - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 - }; - private static int[] SP8 = { - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 - }; - - // Routines taken from other parts of the Acme utilities. - - /// Squash bytes down to ints. - public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen ) - { - for ( int i = 0; i < intLen; ++i ) - outInts[outOff + i] = - ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) | - ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) | - ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) | - ( inBytes[inOff + i * 4 + 3] & 0xff ); - } - - /// Spread ints into bytes. - public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen ) - { - for ( int i = 0; i < intLen; ++i ) - { - outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 ); - outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 ); - outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 ); - outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i]; - } - } - } diff --git a/java/src/com/tightvnc/vncviewer/HTTPConnectSocket.java b/java/src/com/tightvnc/vncviewer/HTTPConnectSocket.java deleted file mode 100644 index c427b069..00000000 --- a/java/src/com/tightvnc/vncviewer/HTTPConnectSocket.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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); - } -} - diff --git a/java/src/com/tightvnc/vncviewer/HTTPConnectSocketFactory.java b/java/src/com/tightvnc/vncviewer/HTTPConnectSocketFactory.java deleted file mode 100644 index 3eae6f9e..00000000 --- a/java/src/com/tightvnc/vncviewer/HTTPConnectSocketFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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; - } -} - diff --git a/java/src/com/tightvnc/vncviewer/InStream.java b/java/src/com/tightvnc/vncviewer/InStream.java deleted file mode 100644 index ecb03d9a..00000000 --- a/java/src/com/tightvnc/vncviewer/InStream.java +++ /dev/null @@ -1,179 +0,0 @@ -/* 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). -// - -package com.tightvnc.vncviewer; - -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; -} diff --git a/java/src/com/tightvnc/vncviewer/LICENCE.TXT b/java/src/com/tightvnc/vncviewer/LICENCE.TXT deleted file mode 100644 index ae3b5319..00000000 --- a/java/src/com/tightvnc/vncviewer/LICENCE.TXT +++ /dev/null @@ -1,340 +0,0 @@ - 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. diff --git a/java/src/com/tightvnc/vncviewer/MANIFEST.MF b/java/src/com/tightvnc/vncviewer/MANIFEST.MF deleted file mode 100644 index 9ddbfbcc..00000000 --- a/java/src/com/tightvnc/vncviewer/MANIFEST.MF +++ /dev/null @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: VncViewer diff --git a/java/src/com/tightvnc/vncviewer/Makefile b/java/src/com/tightvnc/vncviewer/Makefile deleted file mode 100644 index f236eae4..00000000 --- a/java/src/com/tightvnc/vncviewer/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# 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 diff --git a/java/src/com/tightvnc/vncviewer/MemInStream.java b/java/src/com/tightvnc/vncviewer/MemInStream.java deleted file mode 100644 index 7427a9af..00000000 --- a/java/src/com/tightvnc/vncviewer/MemInStream.java +++ /dev/null @@ -1,34 +0,0 @@ -/* 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. - */ - -package com.tightvnc.vncviewer; - -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"); - } -} diff --git a/java/src/com/tightvnc/vncviewer/OptionsFrame.java b/java/src/com/tightvnc/vncviewer/OptionsFrame.java deleted file mode 100644 index e1125f4b..00000000 --- a/java/src/com/tightvnc/vncviewer/OptionsFrame.java +++ /dev/null @@ -1,478 +0,0 @@ -// -// Copyright (C) 2001 HorizonLive.com, Inc. All Rights Reserved. -// Copyright (C) 2001 Constantin Kaplinsky. All Rights Reserved. -// Copyright (C) 2000 Tridia Corporation. All Rights Reserved. -// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -// -// This is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this software; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. -// - -// -// Options frame. -// -// This deals with all the options the user can play with. -// It sets the encodings array and some booleans. -// - -package com.tightvnc.vncviewer; - -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", - "Scaling factor", - "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" }, - { "Auto", "1%", "5%", "10%", "20%", "25%", "50%", "75%", "100%"}, - { "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, - scalingFactorIndex = 9, - scaleCursorIndex = 10, - shareDesktopIndex = 11; - - 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("TigerVNC 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); - } - } - } - } - - // Get scaling factor from parameters and set it - // to gui and class member scalingFactor - - String s = viewer.readParameter("Scaling Factor", false); - if (s == null) s = "100%"; - setScalingFactor(s); - if (autoScale) { - choices[scalingFactorIndex].select("Auto"); - } else { - choices[scalingFactorIndex].select(s); - } - - // Make the booleans and encodings array correspond to the state of the GUI - - setEncodings(); - setColorFormat(); - setContinuousUpdates(); - setOtherOptions(); - } - - // - // Set scaling factor class member value - // - - void setScalingFactor(int sf) { - setScalingFactor(((Integer)sf).toString()); - } - - void setScalingFactor(String s) { - autoScale = false; - scalingFactor = 100; - 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; - } - } - } - } - - - // - // 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(); - - } else if (source == choices[scalingFactorIndex]){ - // Tell VNC canvas that scaling factor has changed - setScalingFactor(choices[scalingFactorIndex].getSelectedItem()); - if (viewer.vc != null) - viewer.vc.setScalingFactor(scalingFactor); - } - } - - // - // Respond to button press - // - - public void actionPerformed(ActionEvent evt) { - if (evt.getSource() == closeButton) - setVisible(false); - } - - // - // Respond to window events - // - - public void windowClosing(WindowEvent evt) { - setVisible(false); - } - - public void windowActivated(WindowEvent evt) {} - public void windowDeactivated(WindowEvent evt) {} - public void windowOpened(WindowEvent evt) {} - public void windowClosed(WindowEvent evt) {} - public void windowIconified(WindowEvent evt) {} - public void windowDeiconified(WindowEvent evt) {} -} diff --git a/java/src/com/tightvnc/vncviewer/README b/java/src/com/tightvnc/vncviewer/README deleted file mode 100644 index 18fd7dbd..00000000 --- a/java/src/com/tightvnc/vncviewer/README +++ /dev/null @@ -1,522 +0,0 @@ - - TigerVNC 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. TigerVNC 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 TigerVNC Java viewer: - - 1. Running applet as part of TigerVNC server installation. - - Both the Unix and Windows versions of TigerVNC 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 - TigerVNC 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 TigerVNC 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 -========== - -TigerVNC 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 TigerVNC 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 TigerVNC 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, applicable only 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 TigerVNC 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 TigerVNC 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/ diff --git a/java/src/com/tightvnc/vncviewer/RecordOutputStream.java b/java/src/com/tightvnc/vncviewer/RecordOutputStream.java deleted file mode 100644 index 3978dfc9..00000000 --- a/java/src/com/tightvnc/vncviewer/RecordOutputStream.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.tightvnc.vncviewer; - -import java.io.DataOutput; -import java.io.IOException; - -public class RecordOutputStream implements DataOutput { - - public RecordOutputStream(RfbProto rfbproto) { - rfb = rfbproto; - } - - private boolean canWrite() { - return ((rfb != null) && (rfb.rec != null)); - } - - public void write(byte[] b) throws IOException { - if (canWrite()) - rfb.rec.write(b); - } - - public void write(byte[] b, int off, int len) throws IOException { - if (canWrite()) - rfb.rec.write(b, off, len); - } - - public void write(int b) throws IOException { - if (canWrite()) - rfb.rec.writeIntBE(b); - } - - public void writeBoolean(boolean v) { } - - public void writeByte(int v) throws IOException { - if (canWrite()) { - rfb.rec.writeByte(v); - } - } - - public void writeBytes(String s) { } - public void writeChar(int v) { } - public void writeChars(String s) { } - public void writeDouble(double v) { } - public void writeFloat(float v) { } - - public void writeInt(int v) throws IOException { - if (canWrite()) - rfb.rec.writeIntBE(v); - } - - public void writeLong(long v) { } - - public void writeShort(int v) throws IOException { - if (canWrite()) - rfb.rec.writeShortBE(v); - } - - public void writeUTF(String str) { } - - private RfbProto rfb = null; -} diff --git a/java/src/com/tightvnc/vncviewer/RecordingFrame.java b/java/src/com/tightvnc/vncviewer/RecordingFrame.java deleted file mode 100644 index f2e1faed..00000000 --- a/java/src/com/tightvnc/vncviewer/RecordingFrame.java +++ /dev/null @@ -1,313 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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("TigerVNC 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); - - } - } -} diff --git a/java/src/com/tightvnc/vncviewer/ReloginPanel.java b/java/src/com/tightvnc/vncviewer/ReloginPanel.java deleted file mode 100644 index 4be454d8..00000000 --- a/java/src/com/tightvnc/vncviewer/ReloginPanel.java +++ /dev/null @@ -1,66 +0,0 @@ -// -// 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 -// - -package com.tightvnc.vncviewer; - -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()); - } -} diff --git a/java/src/com/tightvnc/vncviewer/RfbInputStream.java b/java/src/com/tightvnc/vncviewer/RfbInputStream.java deleted file mode 100644 index c14b1883..00000000 --- a/java/src/com/tightvnc/vncviewer/RfbInputStream.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.tightvnc.vncviewer; - -import java.io.IOException; - -// -// This class is layer between data of private RfbProto class -// and classes in other packages. -// -// For now this class is used by com.tightvnc.decoder.RawDecoder -// -public class RfbInputStream { - RfbInputStream(RfbProto rfbProto) { - rfb = rfbProto; - } - - // - // Read data methods - // - - public void readFully(byte b[]) throws IOException { - readFully(b, 0, b.length); - } - - public void readFully(byte b[], int off, int len) throws IOException { - rfb.readFully(b, off, len); - } - - public int readU32() throws IOException { - return rfb.readU32(); - } - - public int readU8() throws IOException { - return rfb.readU8(); - } - - public int readCompactLen() throws IOException { - return rfb.readCompactLen(); - } - - public int readU16() throws IOException { - return rfb.readU16(); - } - - private RfbProto rfb = null; -} diff --git a/java/src/com/tightvnc/vncviewer/RfbProto.java b/java/src/com/tightvnc/vncviewer/RfbProto.java deleted file mode 100644 index d1a94507..00000000 --- a/java/src/com/tightvnc/vncviewer/RfbProto.java +++ /dev/null @@ -1,1497 +0,0 @@ -// -// Copyright (C) 2001-2004 HorizonLive.com, Inc. All Rights Reserved. -// Copyright (C) 2001-2006 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. -// - -// -// RfbProto.java -// - -package com.tightvnc.vncviewer; - -import java.io.*; -import java.awt.*; -import java.awt.event.*; -import java.net.Socket; -import java.util.zip.*; - -class RfbProto { - - final static String - versionMsg_3_3 = "RFB 003.003\n", - 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, - SecTypeNone = 1, - SecTypeVncAuth = 2, - SecTypeTight = 16; - - // 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, - VncAuthFailed = 1, - VncAuthTooMany = 2; - - // Standard server-to-client messages - final static int - FramebufferUpdate = 0, - SetColourMapEntries = 1, - 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, - FixColourMapEntries = 1, - SetEncodings = 2, - FramebufferUpdateRequest = 3, - KeyboardEvent = 4, - 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, - EncodingCopyRect = 1, - EncodingRRE = 2, - EncodingCoRRE = 4, - EncodingHextile = 5, - EncodingZlib = 6, - EncodingTight = 7, - EncodingZRLE = 16, - EncodingCompressLevel0 = 0xFFFFFF00, - EncodingQualityLevel0 = 0xFFFFFFE0, - EncodingXCursor = 0xFFFFFF10, - EncodingRichCursor = 0xFFFFFF11, - 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; - - // Contstants used in the Hextile decoder - final static int - HextileRaw = 1, - HextileBackgroundSpecified = 2, - HextileForegroundSpecified = 4, - HextileAnySubrects = 8, - HextileSubrectsColoured = 16; - - // Contstants used in the Tight decoder - final static int TightMinToCompress = 12; - final static int - TightExplicitFilter = 0x04, - TightFill = 0x08, - TightJpeg = 0x09, - TightMaxSubencoding = 0x09, - TightFilterCopy = 0x00, - TightFilterPalette = 0x01, - TightFilterGradient = 0x02; - - - String host; - int port; - Socket sock; - OutputStream os; - SessionRecorder rec; - boolean inNormalProtocol = false; - VncViewer viewer; - - // Input stream is declared private to make sure it can be accessed - // only via RfbProto methods. We have to do this because we want to - // count how many bytes were read. - private DataInputStream is; - private long numBytesRead = 0; - public long getNumBytesRead() { return numBytesRead; } - - // Java on UNIX does not call keyPressed() on some keys, for example - // swedish keys To prevent our workaround to produce duplicate - // keypresses on JVMs that actually works, keep track of if - // keyPressed() for a "broken" key was called or not. - boolean brokenKeyPressed = false; - - // This will be set to true on the first framebuffer update - // containing Zlib-, ZRLE- or Tight-encoded data. - boolean wereZlibUpdates = false; - - // This fields are needed to show warnings about inefficiently saved - // sessions only once per each saved session file. - boolean zlibWarningShown; - boolean tightWarningShown; - - // Before starting to record each saved session, we set this field - // to 0, and increment on each framebuffer update. We don't flush - // the SessionRecorder data into the file before the second update. - // This allows us to write initial framebuffer update with zero - // timestamp, to let the player show initial desktop before - // playback. - int numUpdatesInSession; - - // Measuring network throughput. - boolean timing; - long timeWaitedIn100us; - long timedKbits; - - // 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; - - // - // Constructor. Make TCP connection to RFB server. - // - - RfbProto(String h, int p, VncViewer v) throws IOException { - viewer = v; - host = h; - port = p; - - if (viewer.socketFactory == null) { - sock = new Socket(host, port); - sock.setTcpNoDelay(true); - } else { - try { - Class factoryClass = Class.forName(viewer.socketFactory); - SocketFactory factory = (SocketFactory)factoryClass.newInstance(); - if (viewer.inAnApplet) - sock = factory.createSocket(host, port, viewer); - else - sock = factory.createSocket(host, port, viewer.mainArgs); - } catch(Exception e) { - e.printStackTrace(); - throw new IOException(e.getMessage()); - } - } - is = new DataInputStream(new BufferedInputStream(sock.getInputStream(), - 16384)); - os = sock.getOutputStream(); - - timing = false; - timeWaitedIn100us = 5; - timedKbits = 0; - } - - - synchronized void close() { - try { - sock.close(); - closed = true; - System.out.println("RFB socket closed"); - if (rec != null) { - rec.close(); - rec = null; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - synchronized boolean closed() { - return closed; - } - - // - // Read server's protocol version message - // - - void readVersionMsg() throws Exception { - - byte[] b = new byte[12]; - - readFully(b); - - if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') - || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') - || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') - || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') - || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) - { - throw new Exception("Host " + host + " port " + port + - " is not an RFB server"); - } - - serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); - serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); - - if (serverMajor < 3) { - throw new Exception("RFB server does not support protocol version 3"); - } - } - - - // - // Write our protocol version message - // - - void writeVersionMsg() throws IOException { - clientMajor = 3; - if (serverMajor > 3 || serverMinor >= 8) { - clientMinor = 8; - os.write(versionMsg_3_8.getBytes()); - } else if (serverMinor >= 7) { - clientMinor = 7; - os.write(versionMsg_3_7.getBytes()); - } else { - clientMinor = 3; - os.write(versionMsg_3_3.getBytes()); - } - protocolTightVNC = false; - initCapabilities(); - } - - - // - // Negotiate the authentication scheme. - // - - int negotiateSecurity() throws Exception { - return (clientMinor >= 7) ? - selectSecurityType() : readSecurityType(); - } - - // - // Read security type from the server (protocol version 3.3). - // - - int readSecurityType() throws Exception { - int secType = readU32(); - - switch (secType) { - case SecTypeInvalid: - readConnFailedReason(); - return SecTypeInvalid; // should never be executed - case SecTypeNone: - case SecTypeVncAuth: - return secType; - default: - throw new Exception("Unknown security type from RFB server: " + secType); - } - } - - // - // Select security type from the server's list (protocol versions 3.7/3.8). - // - - int selectSecurityType() throws Exception { - int secType = SecTypeInvalid; - - // Read the list of secutiry types. - int nSecTypes = readU8(); - if (nSecTypes == 0) { - readConnFailedReason(); - return SecTypeInvalid; // should never be executed - } - 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) { - secType = secTypes[i]; - break; - } - } - - if (secType == SecTypeInvalid) { - throw new Exception("Server did not offer supported security type"); - } else { - os.write(secType); - } - - return secType; - } - - // - // Perform "no authentication". - // - - void authenticateNone() throws Exception { - if (clientMinor >= 8) - readSecurityResult("No authentication"); - } - - // - // Perform standard VNC Authentication. - // - - void authenticateVNC(String pw) throws Exception { - byte[] challenge = new byte[16]; - readFully(challenge); - - if (pw.length() > 8) - pw = pw.substring(0, 8); // Truncate to 8 chars - - // Truncate password on the first zero byte. - int firstZero = pw.indexOf(0); - if (firstZero != -1) - pw = pw.substring(0, firstZero); - - byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; - System.arraycopy(pw.getBytes(), 0, key, 0, pw.length()); - - DesCipher des = new DesCipher(key); - - des.encrypt(challenge, 0, challenge, 0); - des.encrypt(challenge, 8, challenge, 8); - - os.write(challenge); - - readSecurityResult("VNC authentication"); - } - - // - // Read security result. - // Throws an exception on authentication failure. - // - - void readSecurityResult(String authType) throws Exception { - int securityResult = readU32(); - - switch (securityResult) { - case VncAuthOK: - System.out.println(authType + ": success"); - break; - case VncAuthFailed: - if (clientMinor >= 8) - readConnFailedReason(); - throw new Exception(authType + ": failed"); - case VncAuthTooMany: - throw new Exception(authType + ": failed, too many tries"); - default: - throw new Exception(authType + ": unknown result " + securityResult); - } - } - - // - // Read the string describing the reason for a connection failure, - // and throw an exception. - // - - void readConnFailedReason() throws Exception { - int reasonLen = readU32(); - byte[] reason = new byte[reasonLen]; - readFully(reason); - 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. - // - - void writeInt(int value) throws IOException { - byte[] b = new byte[4]; - b[0] = (byte) ((value >> 24) & 0xff); - b[1] = (byte) ((value >> 16) & 0xff); - b[2] = (byte) ((value >> 8) & 0xff); - b[3] = (byte) (value & 0xff); - os.write(b); - } - - // - // Write the client initialisation message - // - - void writeClientInit() throws IOException { - if (viewer.options.shareDesktop) { - os.write(1); - } else { - os.write(0); - } - viewer.options.disableShareDesktop(); - } - - - // - // Read the server initialisation message - // - - String desktopName; - int framebufferWidth, framebufferHeight; - int bitsPerPixel, depth; - boolean bigEndian, trueColour; - int redMax, greenMax, blueMax, redShift, greenShift, blueShift; - - void readServerInit() throws IOException { - framebufferWidth = readU16(); - framebufferHeight = readU16(); - bitsPerPixel = readU8(); - depth = readU8(); - bigEndian = (readU8() != 0); - trueColour = (readU8() != 0); - redMax = readU16(); - greenMax = readU16(); - blueMax = readU16(); - redShift = readU8(); - greenShift = readU8(); - blueShift = readU8(); - byte[] pad = new byte[3]; - readFully(pad); - int nameLength = readU32(); - 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; - } - - - // - // Create session file and write initial protocol messages into it. - // - - void startSession(String fname) throws IOException { - rec = new SessionRecorder(fname); - rec.writeHeader(); - rec.write(versionMsg_3_3.getBytes()); - rec.writeIntBE(SecTypeNone); - rec.writeShortBE(framebufferWidth); - rec.writeShortBE(framebufferHeight); - byte[] fbsServerInitMsg = { - 32, 24, 0, 1, 0, - (byte)0xFF, 0, (byte)0xFF, 0, (byte)0xFF, - 16, 8, 0, 0, 0, 0 - }; - rec.write(fbsServerInitMsg); - rec.writeIntBE(desktopName.length()); - rec.write(desktopName.getBytes()); - numUpdatesInSession = 0; - - // FIXME: If there were e.g. ZRLE updates only, that should not - // affect recording of Zlib and Tight updates. So, actually - // we should maintain separate flags for Zlib, ZRLE and - // Tight, instead of one ``wereZlibUpdates'' variable. - // - - zlibWarningShown = false; - tightWarningShown = false; - } - - // - // Close session file. - // - - void closeSession() throws IOException { - if (rec != null) { - rec.close(); - rec = null; - } - } - - - // - // Set new framebuffer size - // - - void setFramebufferSize(int width, int height) { - framebufferWidth = width; - framebufferHeight = height; - } - - - // - // Read the server message type - // - - int readServerMessageType() throws IOException { - int msgType = readU8(); - - // If the session is being recorded: - if (rec != null) { - if (msgType == Bell) { // Save Bell messages in session files. - rec.writeByte(msgType); - if (numUpdatesInSession > 0) - rec.flush(); - } - } - - return msgType; - } - - - // - // Read a FramebufferUpdate message - // - - int updateNRects; - - void readFramebufferUpdate() throws IOException { - skipBytes(1); - updateNRects = readU16(); - - // If the session is being recorded: - if (rec != null) { - rec.writeByte(FramebufferUpdate); - rec.writeByte(0); - rec.writeShortBE(updateNRects); - } - - numUpdatesInSession++; - } - - // - // Returns true if encoding is not pseudo - // - // FIXME: Find better way to differ pseudo and real encodings - // - - boolean isRealDecoderEncoding(int encoding) { - if ((encoding >= 1) && (encoding <= 16)) { - return true; - } - return false; - } - - // Read a FramebufferUpdate rectangle header - - int updateRectX, updateRectY, updateRectW, updateRectH, updateRectEncoding; - - void readFramebufferUpdateRectHdr() throws Exception { - updateRectX = readU16(); - updateRectY = readU16(); - updateRectW = readU16(); - updateRectH = readU16(); - updateRectEncoding = readU32(); - - if (updateRectEncoding == EncodingZlib || - updateRectEncoding == EncodingZRLE || - updateRectEncoding == EncodingTight) - wereZlibUpdates = true; - - // If the session is being recorded: - if (rec != null) { - if (numUpdatesInSession > 1) - rec.flush(); // Flush the output on each rectangle. - rec.writeShortBE(updateRectX); - rec.writeShortBE(updateRectY); - rec.writeShortBE(updateRectW); - rec.writeShortBE(updateRectH); - - // - // If this is pseudo encoding or CopyRect that write encoding ID - // in this place. All real encoding ID will be written to record stream - // in decoder classes. - - if (((!isRealDecoderEncoding(updateRectEncoding))) && (rec != null)) { - rec.writeIntBE(updateRectEncoding); - } - } - - if (updateRectEncoding < 0 || updateRectEncoding > MaxNormalEncoding) - return; - - if (updateRectX + updateRectW > framebufferWidth || - updateRectY + updateRectH > framebufferHeight) { - throw new Exception("Framebuffer update rectangle too large: " + - updateRectW + "x" + updateRectH + " at (" + - updateRectX + "," + updateRectY + ")"); - } - } - - // - // Read a ServerCutText message - // - - String readServerCutText() throws IOException { - skipBytes(3); - int len = readU32(); - byte[] text = new byte[len]; - readFully(text); - return new String(text); - } - - - // - // Read an integer in compact representation (1..3 bytes). - // Such format is used as a part of the Tight encoding. - // Also, this method records data if session recording is active and - // the viewer's recordFromBeginning variable is set to true. - // - - int readCompactLen() throws IOException { - int[] portion = new int[3]; - portion[0] = readU8(); - int byteCount = 1; - int len = portion[0] & 0x7F; - if ((portion[0] & 0x80) != 0) { - portion[1] = readU8(); - byteCount++; - len |= (portion[1] & 0x7F) << 7; - if ((portion[1] & 0x80) != 0) { - portion[2] = readU8(); - byteCount++; - len |= (portion[2] & 0xFF) << 14; - } - } - - return len; - } - - - // - // Write a FramebufferUpdateRequest message - // - - void writeFramebufferUpdateRequest(int x, int y, int w, int h, - boolean incremental) - throws IOException - { - byte[] b = new byte[10]; - - b[0] = (byte) FramebufferUpdateRequest; - b[1] = (byte) (incremental ? 1 : 0); - b[2] = (byte) ((x >> 8) & 0xff); - b[3] = (byte) (x & 0xff); - b[4] = (byte) ((y >> 8) & 0xff); - b[5] = (byte) (y & 0xff); - b[6] = (byte) ((w >> 8) & 0xff); - b[7] = (byte) (w & 0xff); - b[8] = (byte) ((h >> 8) & 0xff); - b[9] = (byte) (h & 0xff); - - os.write(b); - } - - - // - // Write a SetPixelFormat message - // - - void writeSetPixelFormat(int bitsPerPixel, int depth, boolean bigEndian, - boolean trueColour, - int redMax, int greenMax, int blueMax, - int redShift, int greenShift, int blueShift) - throws IOException - { - byte[] b = new byte[20]; - - b[0] = (byte) SetPixelFormat; - b[4] = (byte) bitsPerPixel; - b[5] = (byte) depth; - b[6] = (byte) (bigEndian ? 1 : 0); - b[7] = (byte) (trueColour ? 1 : 0); - b[8] = (byte) ((redMax >> 8) & 0xff); - b[9] = (byte) (redMax & 0xff); - b[10] = (byte) ((greenMax >> 8) & 0xff); - b[11] = (byte) (greenMax & 0xff); - b[12] = (byte) ((blueMax >> 8) & 0xff); - b[13] = (byte) (blueMax & 0xff); - b[14] = (byte) redShift; - b[15] = (byte) greenShift; - b[16] = (byte) blueShift; - - os.write(b); - } - - - // - // Write a FixColourMapEntries message. The values in the red, green and - // blue arrays are from 0 to 65535. - // - - void writeFixColourMapEntries(int firstColour, int nColours, - int[] red, int[] green, int[] blue) - throws IOException - { - byte[] b = new byte[6 + nColours * 6]; - - b[0] = (byte) FixColourMapEntries; - b[2] = (byte) ((firstColour >> 8) & 0xff); - b[3] = (byte) (firstColour & 0xff); - b[4] = (byte) ((nColours >> 8) & 0xff); - b[5] = (byte) (nColours & 0xff); - - for (int i = 0; i < nColours; i++) { - b[6 + i * 6] = (byte) ((red[i] >> 8) & 0xff); - b[6 + i * 6 + 1] = (byte) (red[i] & 0xff); - b[6 + i * 6 + 2] = (byte) ((green[i] >> 8) & 0xff); - b[6 + i * 6 + 3] = (byte) (green[i] & 0xff); - b[6 + i * 6 + 4] = (byte) ((blue[i] >> 8) & 0xff); - b[6 + i * 6 + 5] = (byte) (blue[i] & 0xff); - } - - os.write(b); - } - - - // - // Write a SetEncodings message - // - - void writeSetEncodings(int[] encs, int len) throws IOException { - byte[] b = new byte[4 + 4 * len]; - - b[0] = (byte) SetEncodings; - b[2] = (byte) ((len >> 8) & 0xff); - b[3] = (byte) (len & 0xff); - - for (int i = 0; i < len; i++) { - b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff); - b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff); - b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff); - b[7 + 4 * i] = (byte) (encs[i] & 0xff); - } - - os.write(b); - } - - - // - // Write a ClientCutText message - // - - void writeClientCutText(String text) throws IOException { - byte[] b = new byte[8 + text.length()]; - - b[0] = (byte) ClientCutText; - b[4] = (byte) ((text.length() >> 24) & 0xff); - b[5] = (byte) ((text.length() >> 16) & 0xff); - b[6] = (byte) ((text.length() >> 8) & 0xff); - b[7] = (byte) (text.length() & 0xff); - - System.arraycopy(text.getBytes(), 0, b, 8, text.length()); - - os.write(b); - } - - - // - // A buffer for putting pointer and keyboard events before being sent. This - // is to ensure that multiple RFB events generated from a single Java Event - // will all be sent in a single network packet. The maximum possible - // length is 4 modifier down events, a single key event followed by 4 - // modifier up events i.e. 9 key events or 72 bytes. - // - - byte[] eventBuf = new byte[72]; - int eventBufLen; - - - // Useful shortcuts for modifier masks. - - final static int CTRL_MASK = InputEvent.CTRL_MASK; - final static int SHIFT_MASK = InputEvent.SHIFT_MASK; - final static int META_MASK = InputEvent.META_MASK; - final static int ALT_MASK = InputEvent.ALT_MASK; - - - // - // Write a pointer event message. We may need to send modifier key events - // around it to set the correct modifier state. - // - - int pointerMask = 0; - - void writePointerEvent(MouseEvent evt) throws IOException { - int modifiers = evt.getModifiers(); - - int mask2 = 2; - int mask3 = 4; - if (viewer.options.reverseMouseButtons2And3) { - mask2 = 4; - mask3 = 2; - } - - // Note: For some reason, AWT does not set BUTTON1_MASK on left - // button presses. Here we think that it was the left button if - // modifiers do not include BUTTON2_MASK or BUTTON3_MASK. - - if (evt.getID() == MouseEvent.MOUSE_PRESSED) { - if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { - pointerMask = mask2; - modifiers &= ~ALT_MASK; - } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { - pointerMask = mask3; - modifiers &= ~META_MASK; - } else { - pointerMask = 1; - } - } else if (evt.getID() == MouseEvent.MOUSE_RELEASED) { - pointerMask = 0; - if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { - modifiers &= ~ALT_MASK; - } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { - modifiers &= ~META_MASK; - } - } - - eventBufLen = 0; - writeModifierKeyEvents(modifiers); - - int x = evt.getX(); - int y = evt.getY(); - - if (x < 0) x = 0; - if (y < 0) y = 0; - - eventBuf[eventBufLen++] = (byte) PointerEvent; - eventBuf[eventBufLen++] = (byte) pointerMask; - eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff); - eventBuf[eventBufLen++] = (byte) (x & 0xff); - eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff); - eventBuf[eventBufLen++] = (byte) (y & 0xff); - - // - // Always release all modifiers after an "up" event - // - - if (pointerMask == 0) { - writeModifierKeyEvents(0); - } - - os.write(eventBuf, 0, eventBufLen); - } - - - // - // Write a key event message. We may need to send modifier key events - // around it to set the correct modifier state. Also we need to translate - // from the Java key values to the X keysym values used by the RFB protocol. - // - - void writeKeyEvent(KeyEvent evt) throws IOException { - - int keyChar = evt.getKeyChar(); - - // - // Ignore event if only modifiers were pressed. - // - - // Some JVMs return 0 instead of CHAR_UNDEFINED in getKeyChar(). - if (keyChar == 0) - keyChar = KeyEvent.CHAR_UNDEFINED; - - if (keyChar == KeyEvent.CHAR_UNDEFINED) { - int code = evt.getKeyCode(); - if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_SHIFT || - code == KeyEvent.VK_META || code == KeyEvent.VK_ALT) - return; - } - - // - // Key press or key release? - // - - boolean down = (evt.getID() == KeyEvent.KEY_PRESSED); - - int key; - if (evt.isActionKey()) { - - // - // An action key should be one of the following. - // If not then just ignore the event. - // - - switch(evt.getKeyCode()) { - case KeyEvent.VK_HOME: key = 0xff50; break; - case KeyEvent.VK_LEFT: key = 0xff51; break; - case KeyEvent.VK_UP: key = 0xff52; break; - case KeyEvent.VK_RIGHT: key = 0xff53; break; - case KeyEvent.VK_DOWN: key = 0xff54; break; - case KeyEvent.VK_PAGE_UP: key = 0xff55; break; - case KeyEvent.VK_PAGE_DOWN: key = 0xff56; break; - case KeyEvent.VK_END: key = 0xff57; break; - case KeyEvent.VK_INSERT: key = 0xff63; break; - case KeyEvent.VK_F1: key = 0xffbe; break; - case KeyEvent.VK_F2: key = 0xffbf; break; - case KeyEvent.VK_F3: key = 0xffc0; break; - case KeyEvent.VK_F4: key = 0xffc1; break; - case KeyEvent.VK_F5: key = 0xffc2; break; - case KeyEvent.VK_F6: key = 0xffc3; break; - case KeyEvent.VK_F7: key = 0xffc4; break; - case KeyEvent.VK_F8: key = 0xffc5; break; - case KeyEvent.VK_F9: key = 0xffc6; break; - case KeyEvent.VK_F10: key = 0xffc7; break; - case KeyEvent.VK_F11: key = 0xffc8; break; - case KeyEvent.VK_F12: key = 0xffc9; break; - default: - return; - } - - } else { - - // - // A "normal" key press. Ordinary ASCII characters go straight through. - // For CTRL-<letter>, CTRL is sent separately so just send <letter>. - // Backspace, tab, return, escape and delete have special keysyms. - // Anything else we ignore. - // - - key = keyChar; - - if (key < 0x20) { - if (evt.isControlDown()) { - key += 0x60; - } else { - switch(key) { - case KeyEvent.VK_BACK_SPACE: key = 0xff08; break; - case KeyEvent.VK_TAB: key = 0xff09; break; - case KeyEvent.VK_ENTER: key = 0xff0d; break; - case KeyEvent.VK_ESCAPE: key = 0xff1b; break; - } - } - } else if (key == 0x7f) { - // Delete - key = 0xffff; - } else if (key > 0xff) { - // JDK1.1 on X incorrectly passes some keysyms straight through, - // so we do too. JDK1.1.4 seems to have fixed this. - // The keysyms passed are 0xff00 .. XK_BackSpace .. XK_Delete - // Also, we pass through foreign currency keysyms (0x20a0..0x20af). - if ((key < 0xff00 || key > 0xffff) && - !(key >= 0x20a0 && key <= 0x20af)) - return; - } - } - - // Fake keyPresses for keys that only generates keyRelease events - if ((key == 0xe5) || (key == 0xc5) || // XK_aring / XK_Aring - (key == 0xe4) || (key == 0xc4) || // XK_adiaeresis / XK_Adiaeresis - (key == 0xf6) || (key == 0xd6) || // XK_odiaeresis / XK_Odiaeresis - (key == 0xa7) || (key == 0xbd) || // XK_section / XK_onehalf - (key == 0xa3)) { // XK_sterling - // Make sure we do not send keypress events twice on platforms - // with correct JVMs (those that actually report KeyPress for all - // keys) - if (down) - brokenKeyPressed = true; - - if (!down && !brokenKeyPressed) { - // We've got a release event for this key, but haven't received - // a press. Fake it. - eventBufLen = 0; - writeModifierKeyEvents(evt.getModifiers()); - writeKeyEvent(key, true); - os.write(eventBuf, 0, eventBufLen); - } - - if (!down) - brokenKeyPressed = false; - } - - eventBufLen = 0; - writeModifierKeyEvents(evt.getModifiers()); - writeKeyEvent(key, down); - - // Always release all modifiers after an "up" event - if (!down) - writeModifierKeyEvents(0); - - os.write(eventBuf, 0, eventBufLen); - } - - - // - // Add a raw key event with the given X keysym to eventBuf. - // - - void writeKeyEvent(int keysym, boolean down) { - eventBuf[eventBufLen++] = (byte) KeyboardEvent; - eventBuf[eventBufLen++] = (byte) (down ? 1 : 0); - eventBuf[eventBufLen++] = (byte) 0; - eventBuf[eventBufLen++] = (byte) 0; - eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff); - eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff); - eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff); - eventBuf[eventBufLen++] = (byte) (keysym & 0xff); - } - - - // - // Write key events to set the correct modifier state. - // - - int oldModifiers = 0; - - void writeModifierKeyEvents(int newModifiers) { - if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK)) - writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0); - - if ((newModifiers & SHIFT_MASK) != (oldModifiers & SHIFT_MASK)) - writeKeyEvent(0xffe1, (newModifiers & SHIFT_MASK) != 0); - - if ((newModifiers & META_MASK) != (oldModifiers & META_MASK)) - writeKeyEvent(0xffe7, (newModifiers & META_MASK) != 0); - - if ((newModifiers & ALT_MASK) != (oldModifiers & ALT_MASK)) - writeKeyEvent(0xffe9, (newModifiers & ALT_MASK) != 0); - - oldModifiers = newModifiers; - } - - - // - // 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; - - // Carry over up to 1s worth of previous rate for smoothing. - - if (timeWaitedIn100us > 10000) { - timedKbits = timedKbits * 10000 / timeWaitedIn100us; - timeWaitedIn100us = 10000; - } - } - - public void stopTiming() { - timing = false; - if (timeWaitedIn100us < timedKbits/2) - timeWaitedIn100us = timedKbits/2; // upper limit 20Mbit/s - } - - public long kbitsPerSecond() { - return timedKbits * 10000 / timeWaitedIn100us; - } - - public long timeWaited() { - return timeWaitedIn100us; - } - - // - // Methods for reading data via our DataInputStream member variable (is). - // - // In addition to reading data, the readFully() methods updates variables - // used to estimate data throughput. - // - - public void readFully(byte b[]) throws IOException { - readFully(b, 0, b.length); - } - - public void readFully(byte b[], int off, int len) throws IOException { - long before = 0; - if (timing) - before = System.currentTimeMillis(); - - is.readFully(b, off, len); - - if (timing) { - long after = System.currentTimeMillis(); - long newTimeWaited = (after - before) * 10; - int newKbits = len * 8 / 1000; - - // limit rate to between 10kbit/s and 40Mbit/s - - if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000; - if (newTimeWaited < newKbits/4) newTimeWaited = newKbits/4; - - timeWaitedIn100us += newTimeWaited; - timedKbits += newKbits; - } - - numBytesRead += len; - } - - final int available() throws IOException { - return is.available(); - } - - // FIXME: DataInputStream::skipBytes() is not guaranteed to skip - // exactly n bytes. Probably we don't want to use this method. - final int skipBytes(int n) throws IOException { - int r = is.skipBytes(n); - numBytesRead += r; - return r; - } - - final int readU8() throws IOException { - int r = is.readUnsignedByte(); - numBytesRead++; - return r; - } - - final int readU16() throws IOException { - int r = is.readUnsignedShort(); - numBytesRead += 2; - return r; - } - - final int readU32() throws IOException { - int r = is.readInt(); - numBytesRead += 4; - return r; - } -} diff --git a/java/src/com/tightvnc/vncviewer/SessionRecorder.java b/java/src/com/tightvnc/vncviewer/SessionRecorder.java deleted file mode 100644 index 9e735310..00000000 --- a/java/src/com/tightvnc/vncviewer/SessionRecorder.java +++ /dev/null @@ -1,195 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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); - } - -} - diff --git a/java/src/com/tightvnc/vncviewer/SocketFactory.java b/java/src/com/tightvnc/vncviewer/SocketFactory.java deleted file mode 100644 index 966d1d3d..00000000 --- a/java/src/com/tightvnc/vncviewer/SocketFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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; -} diff --git a/java/src/com/tightvnc/vncviewer/VncCanvas.java b/java/src/com/tightvnc/vncviewer/VncCanvas.java deleted file mode 100644 index 4e5460f5..00000000 --- a/java/src/com/tightvnc/vncviewer/VncCanvas.java +++ /dev/null @@ -1,1315 +0,0 @@ -// -// Copyright (C) 2004 Horizon Wimba. All Rights Reserved. -// Copyright (C) 2001-2003 HorizonLive.com, Inc. All Rights Reserved. -// Copyright (C) 2001,2002 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. -// - -package com.tightvnc.vncviewer; - -import com.tightvnc.decoder.CoRREDecoder; -import com.tightvnc.decoder.CopyRectDecoder; -import com.tightvnc.decoder.HextileDecoder; -import com.tightvnc.decoder.RREDecoder; -import com.tightvnc.decoder.RawDecoder; -import com.tightvnc.decoder.TightDecoder; -import com.tightvnc.decoder.ZRLEDecoder; -import com.tightvnc.decoder.ZlibDecoder; -import com.tightvnc.decoder.common.Repaintable; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.io.*; -import java.lang.*; -import java.util.zip.*; - - -// -// VncCanvas is a subclass of Canvas which draws a VNC desktop on it. -// - -class VncCanvas extends Canvas - implements KeyListener, MouseListener, MouseMotionListener, Repaintable, Runnable { - - VncViewer viewer; - RfbProto rfb; - ColorModel cm8, cm24; - int bytesPixel; - - int maxWidth = 0, maxHeight = 0; - int scalingFactor; - int scaledWidth, scaledHeight; - - Image memImage; - Graphics memGraphics; - - // - // Decoders - // - - RawDecoder rawDecoder; - RREDecoder rreDecoder; - CoRREDecoder correDecoder; - ZlibDecoder zlibDecoder; - HextileDecoder hextileDecoder; - ZRLEDecoder zrleDecoder; - TightDecoder tightDecoder; - CopyRectDecoder copyRectDecoder; - - // Base decoder decoders array - RawDecoder []decoders = null; - - // Update statistics. - long statStartTime; // time on first framebufferUpdateRequest - long statNumUpdates; // counter for FramebufferUpdate messages - long statNumTotalRects; // rectangles in FramebufferUpdate messages - long statNumPixelRects; // the same, but excluding pseudo-rectangles - long statNumRectsTight; // Tight-encoded rectangles (including JPEG) - long statNumRectsTightJPEG; // JPEG-compressed Tight-encoded rectangles - long statNumRectsZRLE; // ZRLE-encoded rectangles - long statNumRectsHextile; // Hextile-encoded rectangles - long statNumRectsRaw; // Raw-encoded rectangles - long statNumRectsCopy; // CopyRect rectangles - long statNumBytesEncoded; // number of bytes in updates, as received - long statNumBytesDecoded; // number of bytes, as if Raw encoding was used - - // True if we process keyboard and mouse events. - boolean inputEnabled; - - // True if was no one auto resize of canvas - boolean isFirstSizeAutoUpdate = true; - - // Members for limiting sending mouse events to server - long lastMouseEventSendTime = System.currentTimeMillis(); - long mouseMaxFreq = 20; - - // - // The constructors. - // - - public VncCanvas(VncViewer v, int maxWidth_, int maxHeight_) - throws IOException { - - viewer = v; - maxWidth = maxWidth_; - maxHeight = maxHeight_; - - rfb = viewer.rfb; - scalingFactor = viewer.options.scalingFactor; - - cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6)); - cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF); - - // - // Create decoders - // - - // Input stream for decoders - RfbInputStream rfbis = new RfbInputStream(rfb); - // Create output stream for session recording - RecordOutputStream ros = new RecordOutputStream(rfb); - - rawDecoder = new RawDecoder(memGraphics, rfbis); - rreDecoder = new RREDecoder(memGraphics, rfbis); - correDecoder = new CoRREDecoder(memGraphics, rfbis); - hextileDecoder = new HextileDecoder(memGraphics, rfbis); - tightDecoder = new TightDecoder(memGraphics, rfbis); - zlibDecoder = new ZlibDecoder(memGraphics, rfbis); - zrleDecoder = new ZRLEDecoder(memGraphics, rfbis); - copyRectDecoder = new CopyRectDecoder(memGraphics, rfbis); - - // - // Set data for decoders that needs extra parameters - // - - hextileDecoder.setRepainableControl(this); - tightDecoder.setRepainableControl(this); - - // - // Create array that contains our decoders - // - - decoders = new RawDecoder[8]; - decoders[0] = rawDecoder; - decoders[1] = rreDecoder; - decoders[2] = correDecoder; - decoders[3] = hextileDecoder; - decoders[4] = zlibDecoder; - decoders[5] = tightDecoder; - decoders[6] = zrleDecoder; - decoders[7] = copyRectDecoder; - - // - // Set session recorder for decoders - // - - for (int i = 0; i < decoders.length; i++) { - decoders[i].setDataOutputStream(ros); - } - - setPixelFormat(); - resetSelection(); - - inputEnabled = false; - if (!viewer.options.viewOnly) - enableInput(true); - - // Enable mouse and keyboard event listeners. - addKeyListener(this); - addMouseListener(this); - addMouseMotionListener(this); - - // Create thread, that will send mouse movement events - // to VNC server. - Thread mouseThread = new Thread(this); - mouseThread.start(); - } - - public VncCanvas(VncViewer v) throws IOException { - this(v, 0, 0); - } - - // - // Callback methods to determine geometry of our Component. - // - - public Dimension getPreferredSize() { - return new Dimension(scaledWidth, scaledHeight); - } - - public Dimension getMinimumSize() { - return new Dimension(scaledWidth, scaledHeight); - } - - public Dimension getMaximumSize() { - return new Dimension(scaledWidth, scaledHeight); - } - - // - // All painting is performed here. - // - - public void update(Graphics g) { - paint(g); - } - - public void paint(Graphics g) { - synchronized(memImage) { - if (rfb.framebufferWidth == scaledWidth) { - g.drawImage(memImage, 0, 0, null); - } else { - paintScaledFrameBuffer(g); - } - } - if (showSoftCursor) { - int x0 = cursorX - hotX, y0 = cursorY - hotY; - Rectangle r = new Rectangle(x0, y0, cursorWidth, cursorHeight); - if (r.intersects(g.getClipBounds())) { - g.drawImage(softCursor, x0, y0, null); - } - } - 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) { - g.drawImage(memImage, 0, 0, scaledWidth, scaledHeight, null); - } - - // - // Start/stop receiving mouse events. Keyboard events are received - // even in view-only mode, because we want to map the 'r' key to the - // screen refreshing function. - // - - public synchronized void enableInput(boolean enable) { - if (enable && !inputEnabled) { - inputEnabled = true; - if (viewer.showControls) { - viewer.buttonPanel.enableRemoteAccessControls(true); - } - createSoftCursor(); // scaled cursor - } else if (!enable && inputEnabled) { - inputEnabled = false; - if (viewer.showControls) { - viewer.buttonPanel.enableRemoteAccessControls(false); - } - createSoftCursor(); // non-scaled cursor - } - } - - public void setPixelFormat() throws IOException { - if (viewer.options.eightBitColors) { - rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6); - bytesPixel = 1; - } else { - rfb.writeSetPixelFormat(32, 24, false, true, 255, 255, 255, 16, 8, 0); - bytesPixel = 4; - } - updateFramebufferSize(); - } - - void setScalingFactor(int sf) { - scalingFactor = sf; - updateFramebufferSize(); - invalidate(); - } - - void updateFramebufferSize() { - - // Useful shortcuts. - int fbWidth = rfb.framebufferWidth; - int fbHeight = rfb.framebufferHeight; - - // FIXME: This part of code must be in VncViewer i think - if (viewer.options.autoScale) { - if (viewer.inAnApplet) { - maxWidth = viewer.getWidth(); - maxHeight = viewer.getHeight(); - } else { - if (viewer.vncFrame != null) { - if (isFirstSizeAutoUpdate) { - isFirstSizeAutoUpdate = false; - Dimension screenSize = viewer.vncFrame.getToolkit().getScreenSize(); - maxWidth = (int)screenSize.getWidth() - 100; - maxHeight = (int)screenSize.getHeight() - 100; - viewer.vncFrame.setSize(maxWidth, maxHeight); - } else { - viewer.desktopScrollPane.doLayout(); - maxWidth = viewer.desktopScrollPane.getWidth(); - maxHeight = viewer.desktopScrollPane.getHeight(); - } - } else { - maxWidth = fbWidth; - maxHeight = fbHeight; - } - } - int f1 = maxWidth * 100 / fbWidth; - int f2 = maxHeight * 100 / fbHeight; - scalingFactor = Math.min(f1, f2); - if (scalingFactor > 100) - scalingFactor = 100; - System.out.println("Scaling desktop at " + scalingFactor + "%"); - } - - // Update scaled framebuffer geometry. - scaledWidth = (fbWidth * scalingFactor + 50) / 100; - scaledHeight = (fbHeight * scalingFactor + 50) / 100; - - // Create new off-screen image either if it does not exist, or if - // its geometry should be changed. It's not necessary to replace - // existing image if only pixel format should be changed. - if (memImage == null) { - memImage = viewer.vncContainer.createImage(fbWidth, fbHeight); - memGraphics = memImage.getGraphics(); - } else if (memImage.getWidth(null) != fbWidth || - memImage.getHeight(null) != fbHeight) { - synchronized(memImage) { - memImage = viewer.vncContainer.createImage(fbWidth, fbHeight); - memGraphics = memImage.getGraphics(); - } - } - - // - // Update decoders - // - - // - // FIXME: Why decoders can be null here? - // - - if (decoders != null) { - for (int i = 0; i < decoders.length; i++) { - // - // Set changes to every decoder that we can use - // - - decoders[i].setBPP(bytesPixel); - decoders[i].setFrameBufferSize(fbWidth, fbHeight); - decoders[i].setGraphics(memGraphics); - - // - // Update decoder - // - - decoders[i].update(); - } - } - - // FIXME: This part of code must be in VncViewer i think - // Update the size of desktop containers. - if (viewer.inSeparateFrame) { - if (viewer.desktopScrollPane != null) { - if (!viewer.options.autoScale) { - resizeDesktopFrame(); - } else { - setSize(scaledWidth, scaledHeight); - viewer.desktopScrollPane.setSize(maxWidth + 200, - maxHeight + 200); - } - } - } else { - setSize(scaledWidth, scaledHeight); - } - viewer.moveFocusToDesktop(); - } - - void resizeDesktopFrame() { - setSize(scaledWidth, scaledHeight); - - // FIXME: Find a better way to determine correct size of a - // ScrollPane. -- const - Insets insets = viewer.desktopScrollPane.getInsets(); - viewer.desktopScrollPane.setSize(scaledWidth + - 2 * Math.min(insets.left, insets.right), - scaledHeight + - 2 * Math.min(insets.top, insets.bottom)); - - viewer.vncFrame.pack(); - - // Try to limit the frame size to the screen size. - - Dimension screenSize = viewer.vncFrame.getToolkit().getScreenSize(); - Dimension frameSize = viewer.vncFrame.getSize(); - Dimension newSize = frameSize; - - // Reduce Screen Size by 30 pixels in each direction; - // This is a (poor) attempt to account for - // 1) Menu bar on Macintosh (should really also account for - // Dock on OSX). Usually 22px on top of screen. - // 2) Taxkbar on Windows (usually about 28 px on bottom) - // 3) Other obstructions. - - screenSize.height -= 30; - screenSize.width -= 30; - - boolean needToResizeFrame = false; - if (frameSize.height > screenSize.height) { - newSize.height = screenSize.height; - needToResizeFrame = true; - } - if (frameSize.width > screenSize.width) { - newSize.width = screenSize.width; - needToResizeFrame = true; - } - if (needToResizeFrame) { - viewer.vncFrame.setSize(newSize); - } - - viewer.desktopScrollPane.doLayout(); - } - - // - // processNormalProtocol() - executed by the rfbThread to deal with the - // RFB socket. - // - - public void processNormalProtocol() throws Exception { - - // Start/stop session recording if necessary. - viewer.checkRecordingStatus(); - - 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; - - // - // main dispatch loop - // - - while (true) { - - // Read message type from the server. - int msgType = rfb.readServerMessageType(); - - // Process the message depending on its type. - switch (msgType) { - case RfbProto.FramebufferUpdate: - - if (statNumUpdates == viewer.debugStatsExcludeUpdates && - !statsRestarted) { - resetStats(); - statsRestarted = true; - } else if (statNumUpdates == viewer.debugStatsMeasureUpdates && - statsRestarted) { - viewer.disconnect(); - } - - rfb.readFramebufferUpdate(); - statNumUpdates++; - - boolean cursorPosReceived = false; - - for (int i = 0; i < rfb.updateNRects; i++) { - - rfb.readFramebufferUpdateRectHdr(); - statNumTotalRects++; - int rx = rfb.updateRectX, ry = rfb.updateRectY; - int rw = rfb.updateRectW, rh = rfb.updateRectH; - - if (rfb.updateRectEncoding == rfb.EncodingLastRect) - break; - - if (rfb.updateRectEncoding == rfb.EncodingNewFBSize) { - rfb.setFramebufferSize(rw, rh); - updateFramebufferSize(); - break; - } - - if (rfb.updateRectEncoding == rfb.EncodingXCursor || - rfb.updateRectEncoding == rfb.EncodingRichCursor) { - handleCursorShapeUpdate(rfb.updateRectEncoding, rx, ry, rw, rh); - continue; - } - - if (rfb.updateRectEncoding == rfb.EncodingPointerPos) { - softCursorMove(rx, ry); - cursorPosReceived = true; - continue; - } - - long numBytesReadBefore = rfb.getNumBytesRead(); - - rfb.startTiming(); - - switch (rfb.updateRectEncoding) { - case RfbProto.EncodingRaw: - statNumRectsRaw++; - handleRawRect(rx, ry, rw, rh); - break; - case RfbProto.EncodingCopyRect: - statNumRectsCopy++; - handleCopyRect(rx, ry, rw, rh); - break; - case RfbProto.EncodingRRE: - handleRRERect(rx, ry, rw, rh); - break; - case RfbProto.EncodingCoRRE: - handleCoRRERect(rx, ry, rw, rh); - break; - case RfbProto.EncodingHextile: - statNumRectsHextile++; - handleHextileRect(rx, ry, rw, rh); - break; - case RfbProto.EncodingZRLE: - statNumRectsZRLE++; - handleZRLERect(rx, ry, rw, rh); - break; - case RfbProto.EncodingZlib: - handleZlibRect(rx, ry, rw, rh); - break; - case RfbProto.EncodingTight: - if (tightDecoder != null) { - statNumRectsTightJPEG = tightDecoder.getNumJPEGRects(); - //statNumRectsTight = tightDecoder.getNumTightRects(); - } - statNumRectsTight++; - handleTightRect(rx, ry, rw, rh); - break; - default: - throw new Exception("Unknown RFB rectangle encoding " + - rfb.updateRectEncoding); - } - - rfb.stopTiming(); - - statNumPixelRects++; - statNumBytesDecoded += rw * rh * bytesPixel; - statNumBytesEncoded += - (int)(rfb.getNumBytesRead() - numBytesReadBefore); - } - - boolean fullUpdateNeeded = false; - - // Start/stop session recording if necessary. Request full - // update if a new session file was opened. - if (viewer.checkRecordingStatus()) - fullUpdateNeeded = true; - - // Defer framebuffer update request if necessary. But wake up - // immediately on keyboard or mouse event. Also, don't sleep - // if there is some data to receive, or if the last update - // included a PointerPos message. - if (viewer.deferUpdateRequests > 0 && - rfb.available() == 0 && !cursorPosReceived) { - synchronized(rfb) { - try { - rfb.wait(viewer.deferUpdateRequests); - } catch (InterruptedException e) { - } - } - } - - viewer.autoSelectEncodings(); - - // Before requesting framebuffer update, check if the pixel - // 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 - } - } - - // 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()) { - rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, - rfb.framebufferHeight, true); - } - - break; - - case RfbProto.SetColourMapEntries: - throw new Exception("Can't handle SetColourMapEntries message"); - - case RfbProto.Bell: - Toolkit.getDefaultToolkit().beep(); - break; - - case RfbProto.ServerCutText: - String s = rfb.readServerCutText(); - 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); - } - } - } - - // - // Handle a raw rectangle. The second form with paint==false is used - // by the Hextile decoder for raw-encoded tiles. - // - - void handleRawRect(int x, int y, int w, int h) throws IOException, Exception { - handleRawRect(x, y, w, h, true); - } - - void handleRawRect(int x, int y, int w, int h, boolean paint) - throws IOException , Exception{ - rawDecoder.handleRect(x, y, w, h); - if (paint) - scheduleRepaint(x, y, w, h); - } - - // - // Handle a CopyRect rectangle. - // - - void handleCopyRect(int x, int y, int w, int h) throws IOException { - copyRectDecoder.handleRect(x, y, w, h); - scheduleRepaint(x, y, w, h); - } - - // - // Handle an RRE-encoded rectangle. - // - - void handleRRERect(int x, int y, int w, int h) throws IOException { - rreDecoder.handleRect(x, y, w, h); - scheduleRepaint(x, y, w, h); - } - - // - // Handle a CoRRE-encoded rectangle. - // - - void handleCoRRERect(int x, int y, int w, int h) throws IOException { - correDecoder.handleRect(x, y, w, h); - scheduleRepaint(x, y, w, h); - } - - // - // Handle a Hextile-encoded rectangle. - // - - void handleHextileRect(int x, int y, int w, int h) throws IOException, - Exception { - hextileDecoder.handleRect(x, y, w, h); - } - - // - // Handle a ZRLE-encoded rectangle. - // - // FIXME: Currently, session recording is not fully supported for ZRLE. - // - - void handleZRLERect(int x, int y, int w, int h) throws Exception { - zrleDecoder.handleRect(x, y, w, h); - scheduleRepaint(x, y, w, h); - } - - // - // Handle a Zlib-encoded rectangle. - // - - void handleZlibRect(int x, int y, int w, int h) throws Exception { - zlibDecoder.handleRect(x, y, w, h); - scheduleRepaint(x, y, w, h); - } - - // - // Handle a Tight-encoded rectangle. - // - - void handleTightRect(int x, int y, int w, int h) throws Exception { - tightDecoder.handleRect(x, y, w, h); - scheduleRepaint(x, y, w, h); - } - - // - // Tell JVM to repaint specified desktop area. - // - - public void scheduleRepaint(int x, int y, int w, int h) { - // Request repaint, deferred if necessary. - if (rfb.framebufferWidth == scaledWidth) { - repaint(viewer.deferScreenUpdates, x, y, w, h); - } else { - int sx = x * scalingFactor / 100; - int sy = y * scalingFactor / 100; - int sw = ((x + w) * scalingFactor + 49) / 100 - sx + 1; - int sh = ((y + h) * scalingFactor + 49) / 100 - sy + 1; - repaint(viewer.deferScreenUpdates, sx, sy, sw, sh); - } - } - - // - // Handle events. - // - - public void keyPressed(KeyEvent evt) { - processLocalKeyEvent(evt); - } - public void keyReleased(KeyEvent evt) { - processLocalKeyEvent(evt); - } - public void keyTyped(KeyEvent evt) { - evt.consume(); - } - - public void mousePressed(MouseEvent evt) { - processLocalMouseEvent(evt, false); - } - public void mouseReleased(MouseEvent evt) { - processLocalMouseEvent(evt, false); - } - public void mouseMoved(MouseEvent evt) { - processLocalMouseEvent(evt, true); - } - public void mouseDragged(MouseEvent evt) { - processLocalMouseEvent(evt, true); - } - - private synchronized void trySendPointerEvent() { - if ((needToSendMouseEvent) && (mouseEvent!=null)) { - sendMouseEvent(mouseEvent, false); - needToSendMouseEvent = false; - lastMouseEventSendTime = System.currentTimeMillis(); - } - } - - public void run() { - while (true) { - // Send mouse movement if we have it - trySendPointerEvent(); - // Sleep for some time - try { - Thread.sleep(1000 / mouseMaxFreq); - } catch (InterruptedException ex) { - } - } - } - - // - // Ignored events. - // - - public void mouseClicked(MouseEvent evt) {} - public void mouseEntered(MouseEvent evt) {} - public void mouseExited(MouseEvent evt) {} - - // - // Actual event processing. - // - - private void processLocalKeyEvent(KeyEvent evt) { - if (viewer.rfb != null && rfb.inNormalProtocol) { - if (!inputEnabled) { - if ((evt.getKeyChar() == 'r' || evt.getKeyChar() == 'R') && - evt.getID() == KeyEvent.KEY_PRESSED ) { - // Request screen update. - try { - rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, - rfb.framebufferHeight, false); - } catch (IOException e) { - e.printStackTrace(); - } - } - } else { - // Input enabled. - synchronized(rfb) { - try { - rfb.writeKeyEvent(evt); - } catch (Exception e) { - e.printStackTrace(); - } - rfb.notify(); - } - } - } - // Don't ever pass keyboard events to AWT for default processing. - // Otherwise, pressing Tab would switch focus to ButtonPanel etc. - evt.consume(); - } - - 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; - } - } - } else { - handleSelectionMouseEvent(evt); - } - } - } - - private void sendMouseEvent(MouseEvent evt, boolean moved) { - if (moved) { - softCursorMove(evt.getX(), evt.getY()); - } - if (rfb.framebufferWidth != scaledWidth) { - int sx = (evt.getX() * 100 + scalingFactor/2) / scalingFactor; - int sy = (evt.getY() * 100 + scalingFactor/2) / scalingFactor; - evt.translatePoint(sx - evt.getX(), sy - evt.getY()); - } - synchronized(rfb) { - try { - rfb.writePointerEvent(evt); - } catch (Exception e) { - e.printStackTrace(); - } - rfb.notify(); - lastMouseEventSendTime = System.currentTimeMillis(); - } - } - - // - // Reset update statistics. - // - - void resetStats() { - statStartTime = System.currentTimeMillis(); - statNumUpdates = 0; - statNumTotalRects = 0; - statNumPixelRects = 0; - statNumRectsTight = 0; - statNumRectsTightJPEG = 0; - statNumRectsZRLE = 0; - statNumRectsHextile = 0; - statNumRectsRaw = 0; - statNumRectsCopy = 0; - statNumBytesEncoded = 0; - statNumBytesDecoded = 0; - if (tightDecoder != null) { - tightDecoder.setNumJPEGRects(0); - tightDecoder.setNumTightRects(0); - } - } - - ////////////////////////////////////////////////////////////////// - // - // Handle cursor shape updates (XCursor and RichCursor encodings). - // - - boolean showSoftCursor = false; - - MemoryImageSource softCursorSource; - Image softCursor; - MouseEvent mouseEvent = null; - boolean needToSendMouseEvent = false; - int cursorX = 0, cursorY = 0; - int cursorWidth, cursorHeight; - int origCursorWidth, origCursorHeight; - int hotX, hotY; - int origHotX, origHotY; - - // - // Handle cursor shape update (XCursor and RichCursor encodings). - // - - synchronized void - handleCursorShapeUpdate(int encodingType, - int xhot, int yhot, int width, int height) - throws IOException { - - softCursorFree(); - - if (width * height == 0) - return; - - // Ignore cursor shape data if requested by user. - if (viewer.options.ignoreCursorUpdates) { - int bytesPerRow = (width + 7) / 8; - int bytesMaskData = bytesPerRow * height; - - if (encodingType == rfb.EncodingXCursor) { - rfb.skipBytes(6 + bytesMaskData * 2); - } else { - // rfb.EncodingRichCursor - rfb.skipBytes(width * height + bytesMaskData); - } - return; - } - - // Decode cursor pixel data. - softCursorSource = decodeCursorShape(encodingType, width, height); - - // Set original (non-scaled) cursor dimensions. - origCursorWidth = width; - origCursorHeight = height; - origHotX = xhot; - origHotY = yhot; - - // Create off-screen cursor image. - createSoftCursor(); - - // Show the cursor. - showSoftCursor = true; - repaint(viewer.deferCursorUpdates, - cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); - } - - // - // decodeCursorShape(). Decode cursor pixel data and return - // corresponding MemoryImageSource instance. - // - - synchronized MemoryImageSource - decodeCursorShape(int encodingType, int width, int height) - throws IOException { - - int bytesPerRow = (width + 7) / 8; - int bytesMaskData = bytesPerRow * height; - - int[] softCursorPixels = new int[width * height]; - - if (encodingType == rfb.EncodingXCursor) { - - // Read foreground and background colors of the cursor. - byte[] rgb = new byte[6]; - rfb.readFully(rgb); - int[] colors = { (0xFF000000 | (rgb[3] & 0xFF) << 16 | - (rgb[4] & 0xFF) << 8 | (rgb[5] & 0xFF)), - (0xFF000000 | (rgb[0] & 0xFF) << 16 | - (rgb[1] & 0xFF) << 8 | (rgb[2] & 0xFF)) }; - - // Read pixel and mask data. - byte[] pixBuf = new byte[bytesMaskData]; - rfb.readFully(pixBuf); - byte[] maskBuf = new byte[bytesMaskData]; - rfb.readFully(maskBuf); - - // Decode pixel data into softCursorPixels[]. - byte pixByte, maskByte; - int x, y, n, result; - int i = 0; - for (y = 0; y < height; y++) { - for (x = 0; x < width / 8; x++) { - pixByte = pixBuf[y * bytesPerRow + x]; - maskByte = maskBuf[y * bytesPerRow + x]; - for (n = 7; n >= 0; n--) { - if ((maskByte >> n & 1) != 0) { - result = colors[pixByte >> n & 1]; - } else { - result = 0; // Transparent pixel - } - softCursorPixels[i++] = result; - } - } - for (n = 7; n >= 8 - width % 8; n--) { - if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) { - result = colors[pixBuf[y * bytesPerRow + x] >> n & 1]; - } else { - result = 0; // Transparent pixel - } - softCursorPixels[i++] = result; - } - } - - } else { - // encodingType == rfb.EncodingRichCursor - - // Read pixel and mask data. - byte[] pixBuf = new byte[width * height * bytesPixel]; - rfb.readFully(pixBuf); - byte[] maskBuf = new byte[bytesMaskData]; - rfb.readFully(maskBuf); - - // Decode pixel data into softCursorPixels[]. - byte pixByte, maskByte; - int x, y, n, result; - int i = 0; - for (y = 0; y < height; y++) { - for (x = 0; x < width / 8; x++) { - maskByte = maskBuf[y * bytesPerRow + x]; - for (n = 7; n >= 0; n--) { - if ((maskByte >> n & 1) != 0) { - if (bytesPixel == 1) { - result = cm8.getRGB(pixBuf[i]); - } else { - result = 0xFF000000 | - (pixBuf[i * 4 + 2] & 0xFF) << 16 | - (pixBuf[i * 4 + 1] & 0xFF) << 8 | - (pixBuf[i * 4] & 0xFF); - } - } else { - result = 0; // Transparent pixel - } - softCursorPixels[i++] = result; - } - } - for (n = 7; n >= 8 - width % 8; n--) { - if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) { - if (bytesPixel == 1) { - result = cm8.getRGB(pixBuf[i]); - } else { - result = 0xFF000000 | - (pixBuf[i * 4 + 2] & 0xFF) << 16 | - (pixBuf[i * 4 + 1] & 0xFF) << 8 | - (pixBuf[i * 4] & 0xFF); - } - } else { - result = 0; // Transparent pixel - } - softCursorPixels[i++] = result; - } - } - - } - - return new MemoryImageSource(width, height, softCursorPixels, 0, width); - } - - // - // createSoftCursor(). Assign softCursor new Image (scaled if necessary). - // Uses softCursorSource as a source for new cursor image. - // - - synchronized void - createSoftCursor() { - - if (softCursorSource == null) - return; - - int scaleCursor = viewer.options.scaleCursor; - if (scaleCursor == 0 || !inputEnabled) - scaleCursor = 100; - - // Save original cursor coordinates. - int x = cursorX - hotX; - int y = cursorY - hotY; - int w = cursorWidth; - int h = cursorHeight; - - cursorWidth = (origCursorWidth * scaleCursor + 50) / 100; - cursorHeight = (origCursorHeight * scaleCursor + 50) / 100; - hotX = (origHotX * scaleCursor + 50) / 100; - hotY = (origHotY * scaleCursor + 50) / 100; - softCursor = Toolkit.getDefaultToolkit().createImage(softCursorSource); - - if (scaleCursor != 100) { - softCursor = softCursor.getScaledInstance(cursorWidth, cursorHeight, - Image.SCALE_SMOOTH); - } - - if (showSoftCursor) { - // Compute screen area to update. - x = Math.min(x, cursorX - hotX); - y = Math.min(y, cursorY - hotY); - w = Math.max(w, cursorWidth); - h = Math.max(h, cursorHeight); - - repaint(viewer.deferCursorUpdates, x, y, w, h); - } - } - - // - // softCursorMove(). Moves soft cursor into a particular location. - // - - synchronized void softCursorMove(int x, int y) { - int oldX = cursorX; - int oldY = cursorY; - cursorX = x; - cursorY = y; - if (showSoftCursor) { - repaint(viewer.deferCursorUpdates, - oldX - hotX, oldY - hotY, cursorWidth, cursorHeight); - repaint(viewer.deferCursorUpdates, - cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); - } - } - - // - // softCursorFree(). Remove soft cursor, dispose resources. - // - - synchronized void softCursorFree() { - if (showSoftCursor) { - showSoftCursor = false; - softCursor = null; - softCursorSource = null; - - repaint(viewer.deferCursorUpdates, - 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(); - } - } - } -} diff --git a/java/src/com/tightvnc/vncviewer/VncCanvas2.java b/java/src/com/tightvnc/vncviewer/VncCanvas2.java deleted file mode 100644 index 502d26fe..00000000 --- a/java/src/com/tightvnc/vncviewer/VncCanvas2.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// 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. -// - -package com.tightvnc.vncviewer; - -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) {} - } - -} - diff --git a/java/src/com/tightvnc/vncviewer/VncViewer.java b/java/src/com/tightvnc/vncviewer/VncViewer.java deleted file mode 100644 index bdaee687..00000000 --- a/java/src/com/tightvnc/vncviewer/VncViewer.java +++ /dev/null @@ -1,1049 +0,0 @@ -// -// Copyright (C) 2001-2004 HorizonLive.com, Inc. All Rights Reserved. -// Copyright (C) 2002 Constantin Kaplinsky. 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. -// - -// -// VncViewer.java - the VNC viewer applet. This class mainly just sets up the -// user interface, leaving it to the VncCanvas to do the actual rendering of -// a VNC desktop. -// - -package com.tightvnc.vncviewer; - -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.net.*; - -public class VncViewer extends java.applet.Applet - implements java.lang.Runnable, WindowListener, ComponentListener { - - boolean inAnApplet = true; - boolean inSeparateFrame = false; - - // - // main() is called when run as a java program from the command line. - // It simply runs the applet inside a newly-created frame. - // - - public static void main(String[] argv) { - VncViewer v = new VncViewer(); - v.mainArgs = argv; - v.inAnApplet = false; - v.inSeparateFrame = true; - - v.init(); - v.start(); - } - - String[] mainArgs; - - RfbProto rfb; - Thread rfbThread; - - Frame vncFrame; - Container vncContainer; - ScrollPane desktopScrollPane; - GridBagLayout gridbag; - ButtonPanel buttonPanel; - Label connStatusLabel; - VncCanvas vc; - OptionsFrame options; - ClipboardFrame clipboard; - RecordingFrame rec; - - // Control session recording. - Object recordingSync; - String sessionFileName; - boolean recordingActive; - boolean recordingStatusChanged; - String cursorUpdatesDef; - String eightBitColorsDef; - - // Variables read from parameter values. - String socketFactory; - String host; - int port; - String passwordParam; - boolean showControls; - boolean offerRelogin; - boolean showOfflineDesktop; - int deferScreenUpdates; - int deferCursorUpdates; - int deferUpdateRequests; - int debugStatsExcludeUpdates; - int debugStatsMeasureUpdates; - - // Reference to this applet for inter-applet communication. - public static java.applet.Applet refApplet; - - // - // init() - // - - public void init() { - - readParameters(); - - refApplet = this; - - if (inSeparateFrame) { - vncFrame = new Frame("TigerVNC"); - if (!inAnApplet) { - vncFrame.add("Center", this); - } - vncContainer = vncFrame; - } else { - vncContainer = this; - } - - recordingSync = new Object(); - - options = new OptionsFrame(this); - clipboard = new ClipboardFrame(this); - if (RecordingFrame.checkSecurity()) - rec = new RecordingFrame(this); - - sessionFileName = null; - recordingActive = false; - recordingStatusChanged = false; - cursorUpdatesDef = null; - eightBitColorsDef = null; - - if (inSeparateFrame) { - vncFrame.addWindowListener(this); - vncFrame.addComponentListener(this); - } - - rfbThread = new Thread(this); - rfbThread.start(); - } - - public void update(Graphics g) { - } - - // - // run() - executed by the rfbThread to deal with the RFB socket. - // - - public void run() { - - gridbag = new GridBagLayout(); - vncContainer.setLayout(gridbag); - - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.anchor = GridBagConstraints.NORTHWEST; - - if (showControls) { - buttonPanel = new ButtonPanel(this); - gridbag.setConstraints(buttonPanel, gbc); - vncContainer.add(buttonPanel); - } - - try { - 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; - try { - screenSize = vncContainer.getToolkit().getScreenSize(); - } catch (Exception e) { - screenSize = new Dimension(0, 0); - } - createCanvas(screenSize.width - 32, screenSize.height - 32); - } else { - createCanvas(0, 0); - } - - gbc.weightx = 1.0; - gbc.weighty = 1.0; - - if (inSeparateFrame) { - - // Create a panel which itself is resizeable and can hold - // non-resizeable VncCanvas component at the top left corner. - Panel canvasPanel = new Panel(); - canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); - canvasPanel.add(vc); - - // Create a ScrollPane which will hold a panel with VncCanvas - // inside. - desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); - gbc.fill = GridBagConstraints.BOTH; - gridbag.setConstraints(desktopScrollPane, gbc); - desktopScrollPane.add(canvasPanel); - // If auto scale is not enabled we don't need to set first frame - // size to fullscreen - if (!options.autoScale) { - vc.isFirstSizeAutoUpdate = false; - } - - // Finally, add our ScrollPane to the Frame window. - vncFrame.add(desktopScrollPane); - vncFrame.setTitle(rfb.desktopName); - vncFrame.pack(); - vc.resizeDesktopFrame(); - - } else { - // Just add the VncCanvas component to the Applet. - gridbag.setConstraints(vc, gbc); - add(vc); - validate(); - } - - if (showControls) { - buttonPanel.enableButtons(); - } - - moveFocusToDesktop(); - processNormalProtocol(); - - } catch (NoRouteToHostException e) { - fatalError("Network error: no route to server: " + host, e); - } catch (UnknownHostException e) { - fatalError("Network error: server name unknown: " + host, e); - } catch (ConnectException e) { - fatalError("Network error: could not connect to server: " + - host + ":" + port, e); - } catch (EOFException e) { - if (showOfflineDesktop) { - e.printStackTrace(); - System.out.println("Network error: remote side closed connection"); - if (vc != null) { - vc.enableInput(false); - } - if (inSeparateFrame) { - vncFrame.setTitle(rfb.desktopName + " [disconnected]"); - } - if (rfb != null && !rfb.closed()) - rfb.close(); - if (showControls && buttonPanel != null) { - buttonPanel.disableButtonsOnDisconnect(); - if (inSeparateFrame) { - vncFrame.pack(); - } else { - validate(); - } - } - } else { - fatalError("Network error: remote side closed connection", e); - } - } catch (IOException e) { - String str = e.getMessage(); - if (str != null && str.length() != 0) { - fatalError("Network Error: " + str, e); - } else { - fatalError(e.toString(), e); - } - } catch (Exception e) { - String str = e.getMessage(); - if (str != null && str.length() != 0) { - fatalError("Error: " + str, e); - } else { - fatalError(e.toString(), e); - } - } - - } - - // - // Create a VncCanvas instance. - // - - void createCanvas(int maxWidth, int maxHeight) throws IOException { - // Determine if Java 2D API is available and use a special - // version of VncCanvas if it is present. - vc = null; - try { - // This throws ClassNotFoundException if there is no Java 2D API. - Class cl = Class.forName("java.awt.Graphics2D"); - // If we could load Graphics2D class, then we can use VncCanvas2D. - cl = Class.forName("com.tightvnc.vncviewer.VncCanvas2"); - Class[] argClasses = { this.getClass(), Integer.TYPE, Integer.TYPE }; - java.lang.reflect.Constructor cstr = cl.getConstructor(argClasses); - Object[] argObjects = - { this, new Integer(maxWidth), new Integer(maxHeight) }; - vc = (VncCanvas)cstr.newInstance(argObjects); - } catch (Exception e) { - System.out.println("Warning: Java 2D API is not available"); - } - - // If we failed to create VncCanvas2D, use old VncCanvas. - if (vc == null) - vc = new VncCanvas(this, maxWidth, maxHeight); - } - - - // - // Process RFB socket messages. - // If the rfbThread is being stopped, ignore any exceptions, - // otherwise rethrow the exception so it can be handled. - // - - void processNormalProtocol() throws Exception { - try { - vc.processNormalProtocol(); - } catch (Exception e) { - if (rfbThread == null) { - System.out.println("Ignoring RFB socket exceptions" + - " because applet is stopping"); - } else { - throw e; - } - } - } - - - // - // Connect to the RFB server and authenticate the user. - // - - void connectAndAuthenticate() throws Exception - { - showConnectionStatus("Initializing..."); - if (inSeparateFrame) { - vncFrame.pack(); - vncFrame.show(); - } else { - validate(); - } - - showConnectionStatus("Connecting to " + host + ", port " + port + "..."); - - rfb = new RfbProto(host, port, this); - showConnectionStatus("Connected to server"); - - rfb.readVersionMsg(); - showConnectionStatus("RFB server supports protocol version " + - rfb.serverMajor + "." + rfb.serverMinor); - - rfb.writeVersionMsg(); - showConnectionStatus("Using RFB protocol version " + - 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; - } - - switch (authType) { - case RfbProto.AuthNone: - showConnectionStatus("No authentication needed"); - rfb.authenticateNone(); - break; - case RfbProto.AuthVNC: - showConnectionStatus("Performing standard VNC authentication"); - if (passwordParam != null) { - rfb.authenticateVNC(passwordParam); - } else { - String pw = askPassword(); - rfb.authenticateVNC(pw); - } - break; - default: - throw new Exception("Unknown authentication scheme " + authType); - } - } - - - // - // Show a message describing the connection status. - // To hide the connection status label, use (msg == null). - // - - void showConnectionStatus(String msg) - { - if (msg == null) { - if (vncContainer.isAncestorOf(connStatusLabel)) { - vncContainer.remove(connStatusLabel); - } - return; - } - - System.out.println(msg); - - if (connStatusLabel == null) { - connStatusLabel = new Label("Status: " + msg); - connStatusLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); - } else { - connStatusLabel.setText("Status: " + msg); - } - - if (!vncContainer.isAncestorOf(connStatusLabel)) { - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.anchor = GridBagConstraints.NORTHWEST; - gbc.weightx = 1.0; - gbc.weighty = 1.0; - gbc.insets = new Insets(20, 30, 20, 30); - gridbag.setConstraints(connStatusLabel, gbc); - vncContainer.add(connStatusLabel); - } - - if (inSeparateFrame) { - vncFrame.pack(); - } else { - validate(); - } - } - - - // - // Show an authentication panel. - // - - String askPassword() throws Exception - { - showConnectionStatus(null); - - AuthPanel authPanel = new AuthPanel(this); - - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.anchor = GridBagConstraints.NORTHWEST; - gbc.weightx = 1.0; - gbc.weighty = 1.0; - gbc.ipadx = 100; - gbc.ipady = 50; - gridbag.setConstraints(authPanel, gbc); - vncContainer.add(authPanel); - - if (inSeparateFrame) { - vncFrame.pack(); - } else { - validate(); - } - - authPanel.moveFocusToDefaultField(); - String pw = authPanel.getPassword(); - vncContainer.remove(authPanel); - - return pw; - } - - - // - // Do the rest of the protocol initialisation. - // - - void doProtocolInitialisation() throws IOException - { - rfb.writeClientInit(); - rfb.readServerInit(); - - System.out.println("Desktop name is " + rfb.desktopName); - System.out.println("Desktop size is " + rfb.framebufferWidth + " x " + - rfb.framebufferHeight); - - setEncodings(); - - showConnectionStatus(null); - } - - - // - // Send current encoding list to the RFB server. - // - - int[] encodingsSaved; - int nEncodingsSaved; - - void setEncodings() { setEncodings(false); } - void autoSelectEncodings() { setEncodings(true); } - - void setEncodings(boolean autoSelectOnly) { - if (options == null || rfb == null || !rfb.inNormalProtocol) - return; - - int preferredEncoding = options.preferredEncoding; - if (preferredEncoding == -1) { - long kbitsPerSecond = rfb.kbitsPerSecond(); - if (nEncodingsSaved < 1) { - // Choose Tight or ZRLE encoding for the very first update. - System.out.println("Using Tight/ZRLE encodings"); - preferredEncoding = RfbProto.EncodingTight; - } else if (kbitsPerSecond > 2000 && - encodingsSaved[0] != RfbProto.EncodingHextile) { - // Switch to Hextile if the connection speed is above 2Mbps. - System.out.println("Throughput " + kbitsPerSecond + - " kbit/s - changing to Hextile encoding"); - preferredEncoding = RfbProto.EncodingHextile; - } else if (kbitsPerSecond < 1000 && - encodingsSaved[0] != RfbProto.EncodingTight) { - // Switch to Tight/ZRLE if the connection speed is below 1Mbps. - System.out.println("Throughput " + kbitsPerSecond + - " kbit/s - changing to Tight/ZRLE encodings"); - preferredEncoding = RfbProto.EncodingTight; - } else { - // Don't change the encoder. - if (autoSelectOnly) - return; - preferredEncoding = encodingsSaved[0]; - } - } else { - // Auto encoder selection is not enabled. - if (autoSelectOnly) - return; - } - - int[] encodings = new int[20]; - int nEncodings = 0; - - encodings[nEncodings++] = preferredEncoding; - if (options.useCopyRect) { - encodings[nEncodings++] = RfbProto.EncodingCopyRect; - } - - if (preferredEncoding != RfbProto.EncodingTight) { - encodings[nEncodings++] = RfbProto.EncodingTight; - } - if (preferredEncoding != RfbProto.EncodingZRLE) { - encodings[nEncodings++] = RfbProto.EncodingZRLE; - } - if (preferredEncoding != RfbProto.EncodingHextile) { - encodings[nEncodings++] = RfbProto.EncodingHextile; - } - if (preferredEncoding != RfbProto.EncodingZlib) { - encodings[nEncodings++] = RfbProto.EncodingZlib; - } - if (preferredEncoding != RfbProto.EncodingCoRRE) { - encodings[nEncodings++] = RfbProto.EncodingCoRRE; - } - if (preferredEncoding != RfbProto.EncodingRRE) { - encodings[nEncodings++] = RfbProto.EncodingRRE; - } - - if (options.compressLevel >= 0 && options.compressLevel <= 9) { - encodings[nEncodings++] = - RfbProto.EncodingCompressLevel0 + options.compressLevel; - } - if (options.jpegQuality >= 0 && options.jpegQuality <= 9) { - encodings[nEncodings++] = - RfbProto.EncodingQualityLevel0 + options.jpegQuality; - } - - if (options.requestCursorUpdates) { - encodings[nEncodings++] = RfbProto.EncodingXCursor; - encodings[nEncodings++] = RfbProto.EncodingRichCursor; - if (!options.ignoreCursorUpdates) - encodings[nEncodings++] = RfbProto.EncodingPointerPos; - } - - encodings[nEncodings++] = RfbProto.EncodingLastRect; - encodings[nEncodings++] = RfbProto.EncodingNewFBSize; - - boolean encodingsWereChanged = false; - if (nEncodings != nEncodingsSaved) { - encodingsWereChanged = true; - } else { - for (int i = 0; i < nEncodings; i++) { - if (encodings[i] != encodingsSaved[i]) { - encodingsWereChanged = true; - break; - } - } - } - - if (encodingsWereChanged) { - try { - rfb.writeSetEncodings(encodings, nEncodings); - if (vc != null) { - vc.softCursorFree(); - } - } catch (Exception e) { - e.printStackTrace(); - } - encodingsSaved = encodings; - nEncodingsSaved = nEncodings; - } - } - - - // - // setCutText() - send the given cut text to the RFB server. - // - - void setCutText(String text) { - try { - if (rfb != null && rfb.inNormalProtocol) { - rfb.writeClientCutText(text); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - - // - // Order change in session recording status. To stop recording, pass - // null in place of the fname argument. - // - - void setRecordingStatus(String fname) { - synchronized(recordingSync) { - sessionFileName = fname; - recordingStatusChanged = true; - } - } - - // - // Start or stop session recording. Returns true if this method call - // causes recording of a new session. - // - - boolean checkRecordingStatus() throws IOException { - synchronized(recordingSync) { - if (recordingStatusChanged) { - recordingStatusChanged = false; - if (sessionFileName != null) { - startRecording(); - return true; - } else { - stopRecording(); - } - } - } - return false; - } - - // - // Start session recording. - // - - protected void startRecording() throws IOException { - synchronized(recordingSync) { - if (!recordingActive) { - // Save settings to restore them after recording the session. - cursorUpdatesDef = - options.choices[options.cursorUpdatesIndex].getSelectedItem(); - eightBitColorsDef = - options.choices[options.eightBitColorsIndex].getSelectedItem(); - // Set options to values suitable for recording. - options.choices[options.cursorUpdatesIndex].select("Disable"); - options.choices[options.cursorUpdatesIndex].setEnabled(false); - options.setEncodings(); - options.choices[options.eightBitColorsIndex].select("No"); - options.choices[options.eightBitColorsIndex].setEnabled(false); - options.setColorFormat(); - } else { - rfb.closeSession(); - } - - System.out.println("Recording the session in " + sessionFileName); - rfb.startSession(sessionFileName); - recordingActive = true; - } - } - - // - // Stop session recording. - // - - protected void stopRecording() throws IOException { - synchronized(recordingSync) { - if (recordingActive) { - // Restore options. - options.choices[options.cursorUpdatesIndex].select(cursorUpdatesDef); - options.choices[options.cursorUpdatesIndex].setEnabled(true); - options.setEncodings(); - options.choices[options.eightBitColorsIndex].select(eightBitColorsDef); - options.choices[options.eightBitColorsIndex].setEnabled(true); - options.setColorFormat(); - - rfb.closeSession(); - System.out.println("Session recording stopped."); - } - sessionFileName = null; - recordingActive = false; - } - } - - - // - // readParameters() - read parameters from the html source or from the - // command line. On the command line, the arguments are just a sequence of - // param_name/param_value pairs where the names and values correspond to - // those expected in the html applet tag source. - // - - void readParameters() { - host = readParameter("HOST", !inAnApplet); - if (host == null) { - host = getCodeBase().getHost(); - if (host.equals("")) { - fatalError("HOST parameter not specified"); - } - } - - port = readIntParameter("PORT", 5900); - - // Read "ENCPASSWORD" or "PASSWORD" parameter if specified. - readPasswordParameters(); - - String str; - if (inAnApplet) { - str = readParameter("Open New Window", false); - if (str != null && str.equalsIgnoreCase("Yes")) - inSeparateFrame = true; - } - - // "Show Controls" set to "No" disables button panel. - showControls = true; - str = readParameter("Show Controls", false); - if (str != null && str.equalsIgnoreCase("No")) - showControls = false; - - // "Offer Relogin" set to "No" disables "Login again" and "Close - // window" buttons under error messages in applet mode. - offerRelogin = true; - str = readParameter("Offer Relogin", false); - if (str != null && str.equalsIgnoreCase("No")) - offerRelogin = false; - - // Do we continue showing desktop on remote disconnect? - showOfflineDesktop = false; - str = readParameter("Show Offline Desktop", false); - if (str != null && str.equalsIgnoreCase("Yes")) - showOfflineDesktop = true; - - // Fine tuning options. - deferScreenUpdates = readIntParameter("Defer screen updates", 20); - deferCursorUpdates = readIntParameter("Defer cursor updates", 10); - deferUpdateRequests = readIntParameter("Defer update requests", 0); - - // Debugging options. - debugStatsExcludeUpdates = readIntParameter("DEBUG_XU", 0); - debugStatsMeasureUpdates = readIntParameter("DEBUG_CU", 0); - - // SocketFactory. - socketFactory = readParameter("SocketFactory", false); - } - - // - // Read password parameters. If an "ENCPASSWORD" parameter is set, - // then decrypt the password into the passwordParam string. Otherwise, - // try to read the "PASSWORD" parameter directly to passwordParam. - // - - private void readPasswordParameters() { - String encPasswordParam = readParameter("ENCPASSWORD", false); - if (encPasswordParam == null) { - passwordParam = readParameter("PASSWORD", false); - } else { - // ENCPASSWORD is hexascii-encoded. Decode. - byte[] pw = {0, 0, 0, 0, 0, 0, 0, 0}; - int len = encPasswordParam.length() / 2; - if (len > 8) - len = 8; - for (int i = 0; i < len; i++) { - String hex = encPasswordParam.substring(i*2, i*2+2); - Integer x = new Integer(Integer.parseInt(hex, 16)); - pw[i] = x.byteValue(); - } - // Decrypt the password. - byte[] key = {23, 82, 107, 6, 35, 78, 88, 7}; - DesCipher des = new DesCipher(key); - des.decrypt(pw, 0, pw, 0); - passwordParam = new String(pw); - } - } - - public String readParameter(String name, boolean required) { - if (inAnApplet) { - String s = getParameter(name); - if ((s == null) && required) { - fatalError(name + " parameter not specified"); - } - return s; - } - - for (int i = 0; i < mainArgs.length; i += 2) { - if (mainArgs[i].equalsIgnoreCase(name)) { - try { - return mainArgs[i+1]; - } catch (Exception e) { - if (required) { - fatalError(name + " parameter not specified"); - } - return null; - } - } - } - if (required) { - fatalError(name + " parameter not specified"); - } - return null; - } - - int readIntParameter(String name, int defaultValue) { - String str = readParameter(name, false); - int result = defaultValue; - if (str != null) { - try { - result = Integer.parseInt(str); - } catch (NumberFormatException e) { } - } - return result; - } - - // - // moveFocusToDesktop() - move keyboard focus either to VncCanvas. - // - - void moveFocusToDesktop() { - if (vncContainer != null) { - if (vc != null && vncContainer.isAncestorOf(vc)) - vc.requestFocus(); - } - } - - // - // disconnect() - close connection to server. - // - - synchronized public void disconnect() { - System.out.println("Disconnecting"); - - if (vc != null) { - double sec = (System.currentTimeMillis() - vc.statStartTime) / 1000.0; - double rate = Math.round(vc.statNumUpdates / sec * 100) / 100.0; - long nRealRects = vc.statNumPixelRects; - long nPseudoRects = vc.statNumTotalRects - vc.statNumPixelRects; - System.out.println("Updates received: " + vc.statNumUpdates + " (" + - nRealRects + " rectangles + " + nPseudoRects + - " pseudo), " + rate + " updates/sec"); - long numRectsOther = nRealRects - vc.statNumRectsTight - - vc.statNumRectsZRLE - vc.statNumRectsHextile - - vc.statNumRectsRaw - vc.statNumRectsCopy; - System.out.println("Rectangles:" + - " Tight=" + vc.statNumRectsTight + - "(JPEG=" + vc.statNumRectsTightJPEG + - ") ZRLE=" + vc.statNumRectsZRLE + - " Hextile=" + vc.statNumRectsHextile + - " Raw=" + vc.statNumRectsRaw + - " CopyRect=" + vc.statNumRectsCopy + - " other=" + numRectsOther); - - long raw = vc.statNumBytesDecoded; - long compressed = vc.statNumBytesEncoded; - if (compressed > 0) { - double ratio = Math.round((double)raw / compressed * 1000) / 1000.0; - System.out.println("Pixel data: " + vc.statNumBytesDecoded + - " bytes, " + vc.statNumBytesEncoded + - " compressed, ratio " + ratio); - } - } - - if (rfb != null && !rfb.closed()) - rfb.close(); - options.dispose(); - clipboard.dispose(); - if (rec != null) - rec.dispose(); - - if (inAnApplet) { - showMessage("Disconnected"); - } else { - System.exit(0); - } - } - - // - // fatalError() - print out a fatal error message. - // FIXME: Do we really need two versions of the fatalError() method? - // - - synchronized public void fatalError(String str) { - System.out.println(str); - - if (inAnApplet) { - // vncContainer null, applet not inited, - // can not present the error to the user. - Thread.currentThread().stop(); - } else { - System.exit(1); - } - } - - synchronized public void fatalError(String str, Exception e) { - - if (rfb != null && rfb.closed()) { - // Not necessary to show error message if the error was caused - // by I/O problems after the rfb.close() method call. - System.out.println("RFB thread finished"); - return; - } - - System.out.println(str); - e.printStackTrace(); - - if (rfb != null) - rfb.close(); - - if (inAnApplet) { - showMessage(str); - } else { - System.exit(1); - } - } - - // - // Show message text and optionally "Relogin" and "Close" buttons. - // - - void showMessage(String msg) { - vncContainer.removeAll(); - - Label errLabel = new Label(msg, Label.CENTER); - errLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); - - if (offerRelogin) { - - Panel gridPanel = new Panel(new GridLayout(0, 1)); - Panel outerPanel = new Panel(new FlowLayout(FlowLayout.LEFT)); - outerPanel.add(gridPanel); - vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 16)); - vncContainer.add(outerPanel); - Panel textPanel = new Panel(new FlowLayout(FlowLayout.CENTER)); - textPanel.add(errLabel); - gridPanel.add(textPanel); - gridPanel.add(new ReloginPanel(this)); - - } else { - - vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30)); - vncContainer.add(errLabel); - - } - - if (inSeparateFrame) { - vncFrame.pack(); - } else { - validate(); - } - } - - // - // Stop the applet. - // Main applet thread will terminate on first exception - // after seeing that rfbThread has been set to null. - // - - public void stop() { - System.out.println("Stopping applet"); - rfbThread = null; - } - - // - // This method is called before the applet is destroyed. - // - - public void destroy() { - System.out.println("Destroying applet"); - - vncContainer.removeAll(); - options.dispose(); - clipboard.dispose(); - if (rec != null) - rec.dispose(); - if (rfb != null && !rfb.closed()) - rfb.close(); - if (inSeparateFrame) - vncFrame.dispose(); - } - - // - // Start/stop receiving mouse events. - // - - public void enableInput(boolean enable) { - vc.enableInput(enable); - } - - // - // Resize framebuffer if autoScale is enabled. - // - - public void componentResized(ComponentEvent e) { - if (e.getComponent() == vncFrame) { - if (options.autoScale) { - if (vc != null) { - if (!vc.isFirstSizeAutoUpdate) { - vc.updateFramebufferSize(); - } - } - } - } - } - - // - // Ignore component events we're not interested in. - // - - public void componentShown(ComponentEvent e) { } - public void componentMoved(ComponentEvent e) { } - public void componentHidden(ComponentEvent e) { } - - // - // Close application properly on window close event. - // - - public void windowClosing(WindowEvent evt) { - System.out.println("Closing window"); - if (rfb != null) - disconnect(); - - vncContainer.hide(); - - if (!inAnApplet) { - System.exit(0); - } - } - - // - // 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) {} -} diff --git a/java/src/com/tightvnc/vncviewer/ZlibInStream.java b/java/src/com/tightvnc/vncviewer/ZlibInStream.java deleted file mode 100644 index 636fb545..00000000 --- a/java/src/com/tightvnc/vncviewer/ZlibInStream.java +++ /dev/null @@ -1,113 +0,0 @@ -/* 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 -// - -package com.tightvnc.vncviewer; - -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; -} diff --git a/java/src/com/tightvnc/vncviewer/index.html b/java/src/com/tightvnc/vncviewer/index.html deleted file mode 100644 index 96805dc5..00000000 --- a/java/src/com/tightvnc/vncviewer/index.html +++ /dev/null @@ -1,29 +0,0 @@ -<!-- - index.html - an example HTML page for TigerVNC Java viewer applet, to be - used with a standalone Web server running on the same machine where the - TigerVNC 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> -TigerVNC desktop -</TITLE> -<APPLET CODE="VncViewer.class" ARCHIVE="VncViewer.jar" - WIDTH="800" HEIGHT="632"> -<PARAM NAME="PORT" VALUE="5901"> -</APPLET> -<BR> -<A href="http://www.tigervnc.org/">TigerVNC site</A> -</HTML> diff --git a/java/src/com/tightvnc/vncviewer/index.vnc b/java/src/com/tightvnc/vncviewer/index.vnc deleted file mode 100644 index f24df7c5..00000000 --- a/java/src/com/tightvnc/vncviewer/index.vnc +++ /dev/null @@ -1,25 +0,0 @@ -<!-- - index.vnc - default HTML page for TigerVNC 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 TigerVNC 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.tigervnc.org/">TigerVNC site</A> -</HTML> |