Preliminary version of RFB Session Player converted from TightVNC Java
viewer sources.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2500 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/src/com/tightvnc/rfbplayer/VncCanvas.java b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
index 6d12aa2..750c847 100644
--- a/java/src/com/tightvnc/rfbplayer/VncCanvas.java
+++ b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
@@ -32,21 +32,17 @@
// VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
//
-class VncCanvas extends Canvas
- implements KeyListener, MouseListener, MouseMotionListener {
+class VncCanvas extends Canvas {
- VncViewer viewer;
+ RfbPlayer player;
RfbProto rfb;
- ColorModel cm8, cm24;
- Color[] colors;
- int bytesPixel;
+ ColorModel cm24;
Image memImage;
Graphics memGraphics;
Image rawPixelsImage;
MemoryImageSource pixelsSource;
- byte[] pixels8;
int[] pixels24;
// Zlib encoder's data.
@@ -64,31 +60,17 @@
// which decodes and loads JPEG images.
Rectangle jpegRect;
- // True if we process keyboard and mouse events.
- boolean listenersInstalled;
-
//
// The constructor.
//
- VncCanvas(VncViewer v) throws IOException {
- viewer = v;
- rfb = viewer.rfb;
+ VncCanvas(RfbPlayer player) throws IOException {
+ this.player = player;
+ rfb = player.rfb;
- tightInflaters = new Inflater[4];
-
- cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
- colors = new Color[256];
- for (int i = 0; i < 256; i++)
- colors[i] = new Color(cm8.getRGB(i));
-
- setPixelFormat();
-
- listenersInstalled = false;
- if (!viewer.options.viewOnly)
- enableInput(true);
+ updateFramebufferSize();
}
//
@@ -119,13 +101,6 @@
synchronized(memImage) {
g.drawImage(memImage, 0, 0, null);
}
- if (showSoftCursor) {
- int x0 = cursorX - hotX, y0 = cursorY - hotY;
- Rectangle r = new Rectangle(x0, y0, cursorWidth, cursorHeight);
- if (r.intersects(g.getClipBounds())) {
- g.drawImage(softCursor, x0, y0, null);
- }
- }
}
//
@@ -153,37 +128,6 @@
}
}
- //
- // Start/stop receiving keyboard and mouse events.
- //
-
- public synchronized void enableInput(boolean enable) {
- if (enable && !listenersInstalled) {
- listenersInstalled = true;
- addKeyListener(this);
- addMouseListener(this);
- addMouseMotionListener(this);
- viewer.buttonPanel.enableRemoteAccessControls(true);
- } else if (!enable && listenersInstalled) {
- listenersInstalled = false;
- removeKeyListener(this);
- removeMouseListener(this);
- removeMouseMotionListener(this);
- viewer.buttonPanel.enableRemoteAccessControls(false);
- }
- }
-
- public void setPixelFormat() throws IOException {
- if (viewer.options.eightBitColors) {
- rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6);
- bytesPixel = 1;
- } else {
- rfb.writeSetPixelFormat(32, 24, true, true, 255, 255, 255, 16, 8, 0);
- bytesPixel = 4;
- }
- updateFramebufferSize();
- }
-
void updateFramebufferSize() {
// Useful shortcuts.
@@ -194,37 +138,27 @@
// its geometry should be changed. It's not necessary to replace
// existing image if only pixel format should be changed.
if (memImage == null) {
- memImage = viewer.createImage(fbWidth, fbHeight);
+ memImage = player.createImage(fbWidth, fbHeight);
memGraphics = memImage.getGraphics();
} else if (memImage.getWidth(null) != fbWidth ||
memImage.getHeight(null) != fbHeight) {
synchronized(memImage) {
- memImage = viewer.createImage(fbWidth, fbHeight);
+ memImage = player.createImage(fbWidth, fbHeight);
memGraphics = memImage.getGraphics();
}
}
// Images with raw pixels should be re-allocated on every change
// of geometry or pixel format.
- if (bytesPixel == 1) {
- pixels24 = null;
- pixels8 = new byte[fbWidth * fbHeight];
-
- pixelsSource =
- new MemoryImageSource(fbWidth, fbHeight, cm8, pixels8, 0, fbWidth);
- } else {
- pixels8 = null;
- pixels24 = new int[fbWidth * fbHeight];
-
- pixelsSource =
- new MemoryImageSource(fbWidth, fbHeight, cm24, pixels24, 0, fbWidth);
- }
+ pixels24 = new int[fbWidth * fbHeight];
+ pixelsSource =
+ new MemoryImageSource(fbWidth, fbHeight, cm24, pixels24, 0, fbWidth);
pixelsSource.setAnimated(true);
rawPixelsImage = createImage(pixelsSource);
// Update the size of desktop containers.
- if (viewer.inSeparateFrame) {
- if (viewer.desktopScrollPane != null)
+ if (player.inSeparateFrame) {
+ if (player.desktopScrollPane != null)
resizeDesktopFrame();
} else {
setSize(fbWidth, fbHeight);
@@ -236,17 +170,17 @@
// FIXME: Find a better way to determine correct size of a
// ScrollPane. -- const
- Insets insets = viewer.desktopScrollPane.getInsets();
- viewer.desktopScrollPane.setSize(rfb.framebufferWidth +
+ Insets insets = player.desktopScrollPane.getInsets();
+ player.desktopScrollPane.setSize(rfb.framebufferWidth +
2 * Math.min(insets.left, insets.right),
rfb.framebufferHeight +
2 * Math.min(insets.top, insets.bottom));
- viewer.vncFrame.pack();
+ player.vncFrame.pack();
// Try to limit the frame size to the screen size.
- Dimension screenSize = viewer.vncFrame.getToolkit().getScreenSize();
- Dimension frameSize = viewer.vncFrame.getSize();
+ Dimension screenSize = player.vncFrame.getToolkit().getScreenSize();
+ Dimension frameSize = player.vncFrame.getSize();
Dimension newSize = frameSize;
boolean needToResizeFrame = false;
if (frameSize.height > screenSize.height) {
@@ -258,10 +192,10 @@
needToResizeFrame = true;
}
if (needToResizeFrame) {
- viewer.vncFrame.setSize(newSize);
+ player.vncFrame.setSize(newSize);
}
- viewer.desktopScrollPane.doLayout();
+ player.desktopScrollPane.doLayout();
}
//
@@ -271,14 +205,28 @@
public void processNormalProtocol() throws IOException {
- rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
- rfb.framebufferHeight, false);
+ zlibInflater = new Inflater();
+ tightInflaters = new Inflater[4];
- //
- // main dispatch loop
- //
+ // Main dispatch loop.
while (true) {
+
+ while (player.getMode() != player.MODE_PLAYBACK) {
+ synchronized(this) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ if (player.getMode() == player.MODE_STOPPED) {
+ throw new EOFException("Playback stopped");
+ }
+ if (player.getMode() == player.MODE_PLAYBACK) {
+ player.fbsStream.resumeReading();
+ }
+ }
+
int msgType = rfb.readServerMessageType();
switch (msgType) {
@@ -299,10 +247,8 @@
if (rfb.updateRectEncoding == rfb.EncodingXCursor ||
rfb.updateRectEncoding == rfb.EncodingRichCursor) {
- handleCursorShapeUpdate(rfb.updateRectEncoding,
- rfb.updateRectX, rfb.updateRectY,
- rfb.updateRectW, rfb.updateRectH);
- continue;
+ throw new IOException("Sorry, no support for" +
+ " cursor shape updates yet");
}
switch (rfb.updateRectEncoding) {
@@ -336,35 +282,19 @@
int x, y, w, h;
Color pixel;
- if (bytesPixel == 1) {
- memGraphics.setColor(colors[rfb.is.readUnsignedByte()]);
- memGraphics.fillRect(rx, ry, rw, rh);
+ pixel = new Color(0xFF000000 | rfb.is.readInt());
+ memGraphics.setColor(pixel);
+ memGraphics.fillRect(rx, ry, rw, rh);
- for (int j = 0; j < nSubrects; j++) {
- pixel = colors[rfb.is.readUnsignedByte()];
- x = rx + rfb.is.readUnsignedShort();
- y = ry + rfb.is.readUnsignedShort();
- w = rfb.is.readUnsignedShort();
- h = rfb.is.readUnsignedShort();
-
- memGraphics.setColor(pixel);
- memGraphics.fillRect(x, y, w, h);
- }
- } else { // 24-bit color
+ for (int j = 0; j < nSubrects; j++) {
pixel = new Color(0xFF000000 | rfb.is.readInt());
+ x = rx + rfb.is.readUnsignedShort();
+ y = ry + rfb.is.readUnsignedShort();
+ w = rfb.is.readUnsignedShort();
+ h = rfb.is.readUnsignedShort();
+
memGraphics.setColor(pixel);
- memGraphics.fillRect(rx, ry, rw, rh);
-
- for (int j = 0; j < nSubrects; j++) {
- pixel = new Color(0xFF000000 | rfb.is.readInt());
- x = rx + rfb.is.readUnsignedShort();
- y = ry + rfb.is.readUnsignedShort();
- w = rfb.is.readUnsignedShort();
- h = rfb.is.readUnsignedShort();
-
- memGraphics.setColor(pixel);
- memGraphics.fillRect(x, y, w, h);
- }
+ memGraphics.fillRect(x, y, w, h);
}
scheduleRepaint(rx, ry, rw, rh);
@@ -379,35 +309,19 @@
int x, y, w, h;
Color pixel;
- if (bytesPixel == 1) {
- memGraphics.setColor(colors[rfb.is.readUnsignedByte()]);
- memGraphics.fillRect(rx, ry, rw, rh);
+ pixel = new Color(0xFF000000 | rfb.is.readInt());
+ memGraphics.setColor(pixel);
+ memGraphics.fillRect(rx, ry, rw, rh);
- for (int j = 0; j < nSubrects; j++) {
- pixel = colors[rfb.is.readUnsignedByte()];
- x = rx + rfb.is.readUnsignedByte();
- y = ry + rfb.is.readUnsignedByte();
- w = rfb.is.readUnsignedByte();
- h = rfb.is.readUnsignedByte();
-
- memGraphics.setColor(pixel);
- memGraphics.fillRect(x, y, w, h);
- }
- } else { // 24-bit color
+ for (int j = 0; j < nSubrects; j++) {
pixel = new Color(0xFF000000 | rfb.is.readInt());
+ x = rx + rfb.is.readUnsignedByte();
+ y = ry + rfb.is.readUnsignedByte();
+ w = rfb.is.readUnsignedByte();
+ h = rfb.is.readUnsignedByte();
+
memGraphics.setColor(pixel);
- memGraphics.fillRect(rx, ry, rw, rh);
-
- for (int j = 0; j < nSubrects; j++) {
- pixel = new Color(0xFF000000 | rfb.is.readInt());
- x = rx + rfb.is.readUnsignedByte();
- y = ry + rfb.is.readUnsignedByte();
- w = rfb.is.readUnsignedByte();
- h = rfb.is.readUnsignedByte();
-
- memGraphics.setColor(pixel);
- memGraphics.fillRect(x, y, w, h);
- }
+ memGraphics.fillRect(x, y, w, h);
}
scheduleRepaint(rx, ry, rw, rh);
@@ -436,22 +350,16 @@
// Is it a raw-encoded sub-rectangle?
if ((subencoding & rfb.HextileRaw) != 0) {
- if (bytesPixel == 1) {
- for (int j = ty; j < ty + th; j++) {
- rfb.is.readFully(pixels8, j*rfb.framebufferWidth+tx, tw);
- }
- } else {
- byte[] buf = new byte[tw * 4];
- int count, offset;
- for (int j = ty; j < ty + th; j++) {
- rfb.is.readFully(buf);
- offset = j * rfb.framebufferWidth + tx;
- for (count = 0; count < tw; count++) {
- pixels24[offset + count] =
- (buf[count * 4 + 1] & 0xFF) << 16 |
- (buf[count * 4 + 2] & 0xFF) << 8 |
- (buf[count * 4 + 3] & 0xFF);
- }
+ byte[] buf = new byte[tw * 4];
+ int count, offset;
+ for (int j = ty; j < ty + th; j++) {
+ rfb.is.readFully(buf);
+ offset = j * rfb.framebufferWidth + tx;
+ for (count = 0; count < tw; count++) {
+ pixels24[offset + count] =
+ (buf[count * 4 + 1] & 0xFF) << 16 |
+ (buf[count * 4 + 2] & 0xFF) << 8 |
+ (buf[count * 4 + 3] & 0xFF);
}
}
handleUpdatedPixels(tx, ty, tw, th);
@@ -460,22 +368,14 @@
// Read and draw the background if specified.
if ((subencoding & rfb.HextileBackgroundSpecified) != 0) {
- if (bytesPixel == 1) {
- bg = colors[rfb.is.readUnsignedByte()];
- } else {
- bg = new Color(0xFF000000 | rfb.is.readInt());
- }
+ bg = new Color(0xFF000000 | rfb.is.readInt());
}
memGraphics.setColor(bg);
memGraphics.fillRect(tx, ty, tw, th);
// Read the foreground color if specified.
if ((subencoding & rfb.HextileForegroundSpecified) != 0) {
- if (bytesPixel == 1) {
- fg = colors[rfb.is.readUnsignedByte()];
- } else {
- fg = new Color(0xFF000000 | rfb.is.readInt());
- }
+ fg = new Color(0xFF000000 | rfb.is.readInt());
}
// Done with this tile if there is no sub-rectangles.
@@ -485,62 +385,29 @@
int nSubrects = rfb.is.readUnsignedByte();
int b1, b2, sx, sy, sw, sh;
- if (bytesPixel == 1) {
-
- // BGR233 (8-bit color) version.
- if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
- for (int j = 0; j < nSubrects; j++) {
- fg = colors[rfb.is.readUnsignedByte()];
- b1 = rfb.is.readUnsignedByte();
- b2 = rfb.is.readUnsignedByte();
- sx = tx + (b1 >> 4);
- sy = ty + (b1 & 0xf);
- sw = (b2 >> 4) + 1;
- sh = (b2 & 0xf) + 1;
- memGraphics.setColor(fg);
- memGraphics.fillRect(sx, sy, sw, sh);
- }
- } else {
+ if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
+ for (int j = 0; j < nSubrects; j++) {
+ fg = new Color(0xFF000000 | rfb.is.readInt());
+ b1 = rfb.is.readUnsignedByte();
+ b2 = rfb.is.readUnsignedByte();
+ sx = tx + (b1 >> 4);
+ sy = ty + (b1 & 0xf);
+ sw = (b2 >> 4) + 1;
+ sh = (b2 & 0xf) + 1;
memGraphics.setColor(fg);
- for (int j = 0; j < nSubrects; j++) {
- b1 = rfb.is.readUnsignedByte();
- b2 = rfb.is.readUnsignedByte();
- sx = tx + (b1 >> 4);
- sy = ty + (b1 & 0xf);
- sw = (b2 >> 4) + 1;
- sh = (b2 & 0xf) + 1;
- memGraphics.fillRect(sx, sy, sw, sh);
- }
+ memGraphics.fillRect(sx, sy, sw, sh);
}
-
} else {
-
- // Full-color (24-bit) version.
- if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
- for (int j = 0; j < nSubrects; j++) {
- fg = new Color(0xFF000000 | rfb.is.readInt());
- b1 = rfb.is.readUnsignedByte();
- b2 = rfb.is.readUnsignedByte();
- sx = tx + (b1 >> 4);
- sy = ty + (b1 & 0xf);
- sw = (b2 >> 4) + 1;
- sh = (b2 & 0xf) + 1;
- memGraphics.setColor(fg);
- memGraphics.fillRect(sx, sy, sw, sh);
- }
- } else {
- memGraphics.setColor(fg);
- for (int j = 0; j < nSubrects; j++) {
- b1 = rfb.is.readUnsignedByte();
- b2 = rfb.is.readUnsignedByte();
- sx = tx + (b1 >> 4);
- sy = ty + (b1 & 0xf);
- sw = (b2 >> 4) + 1;
- sh = (b2 & 0xf) + 1;
- memGraphics.fillRect(sx, sy, sw, sh);
- }
+ memGraphics.setColor(fg);
+ for (int j = 0; j < nSubrects; j++) {
+ b1 = rfb.is.readUnsignedByte();
+ b2 = rfb.is.readUnsignedByte();
+ sx = tx + (b1 >> 4);
+ sy = ty + (b1 & 0xf);
+ sw = (b2 >> 4) + 1;
+ sh = (b2 & 0xf) + 1;
+ memGraphics.fillRect(sx, sy, sw, sh);
}
-
}
}
@@ -560,10 +427,6 @@
}
rfb.is.readFully(zlibBuf, 0, nBytes);
-
- if (zlibInflater == null) {
- zlibInflater = new Inflater();
- }
zlibInflater.setInput(zlibBuf, 0, nBytes);
handleZlibRect(rfb.updateRectX, rfb.updateRectY,
@@ -586,30 +449,6 @@
}
}
-
- // Defer framebuffer update request if necessary. But wake up
- // immediately on keyboard or mouse event.
- if (viewer.deferUpdateRequests > 0) {
- synchronized(rfb) {
- try {
- rfb.wait(viewer.deferUpdateRequests);
- } catch (InterruptedException e) {
- }
- }
- }
-
- // Before requesting framebuffer update, check if the pixel
- // format should be changed. If it should, request full update
- // instead of incremental one.
- if (viewer.options.eightBitColors != (bytesPixel == 1)) {
- setPixelFormat();
- rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
- rfb.framebufferHeight, false);
- } else {
- rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
- rfb.framebufferHeight, true);
- }
-
break;
case RfbProto.SetColourMapEntries:
@@ -621,12 +460,15 @@
case RfbProto.ServerCutText:
String s = rfb.readServerCutText();
- viewer.clipboard.setCutText(s);
break;
default:
throw new IOException("Unknown RFB message type " + msgType);
}
+
+ if (player.getMode() == player.MODE_STOPPED) {
+ throw new EOFException("Playback stopped");
+ }
}
}
@@ -637,22 +479,16 @@
void handleRawRect(int x, int y, int w, int h) throws IOException {
- if (bytesPixel == 1) {
- for (int dy = y; dy < y + h; dy++) {
- rfb.is.readFully(pixels8, dy * rfb.framebufferWidth + x, w);
- }
- } else {
- byte[] buf = new byte[w * 4];
- int i, offset;
- for (int dy = y; dy < y + h; dy++) {
- rfb.is.readFully(buf);
- offset = dy * rfb.framebufferWidth + x;
- for (i = 0; i < w; i++) {
- pixels24[offset + i] =
- (buf[i * 4 + 1] & 0xFF) << 16 |
- (buf[i * 4 + 2] & 0xFF) << 8 |
- (buf[i * 4 + 3] & 0xFF);
- }
+ byte[] buf = new byte[w * 4];
+ int i, offset;
+ for (int dy = y; dy < y + h; dy++) {
+ rfb.is.readFully(buf);
+ offset = dy * rfb.framebufferWidth + x;
+ for (i = 0; i < w; i++) {
+ pixels24[offset + i] =
+ (buf[i * 4 + 1] & 0xFF) << 16 |
+ (buf[i * 4 + 2] & 0xFF) << 8 |
+ (buf[i * 4 + 3] & 0xFF);
}
}
@@ -669,22 +505,16 @@
throws IOException {
try {
- if (bytesPixel == 1) {
- for (int dy = y; dy < y + h; dy++) {
- zlibInflater.inflate(pixels8, dy * rfb.framebufferWidth + x, w);
- }
- } else {
- byte[] buf = new byte[w * 4];
- int i, offset;
- for (int dy = y; dy < y + h; dy++) {
- zlibInflater.inflate(buf);
- offset = dy * rfb.framebufferWidth + x;
- for (i = 0; i < w; i++) {
- pixels24[offset + i] =
- (buf[i * 4 + 1] & 0xFF) << 16 |
- (buf[i * 4 + 2] & 0xFF) << 8 |
- (buf[i * 4 + 3] & 0xFF);
- }
+ byte[] buf = new byte[w * 4];
+ int i, offset;
+ for (int dy = y; dy < y + h; dy++) {
+ zlibInflater.inflate(buf);
+ offset = dy * rfb.framebufferWidth + x;
+ for (i = 0; i < w; i++) {
+ pixels24[offset + i] =
+ (buf[i * 4 + 1] & 0xFF) << 16 |
+ (buf[i * 4 + 2] & 0xFF) << 8 |
+ (buf[i * 4 + 3] & 0xFF);
}
}
}
@@ -720,15 +550,11 @@
// Handle solid-color rectangles.
if (comp_ctl == rfb.TightFill) {
- if (bytesPixel == 1) {
- memGraphics.setColor(colors[rfb.is.readUnsignedByte()]);
- } else {
- byte[] buf = new byte[3];
- rfb.is.readFully(buf);
- Color bg = new Color(0xFF000000 | (buf[0] & 0xFF) << 16 |
- (buf[1] & 0xFF) << 8 | (buf[2] & 0xFF));
- memGraphics.setColor(bg);
- }
+ byte[] buf = new byte[3];
+ rfb.is.readFully(buf);
+ Color bg = new Color(0xFF000000 | (buf[0] & 0xFF) << 16 |
+ (buf[1] & 0xFF) << 8 | (buf[2] & 0xFF));
+ memGraphics.setColor(bg);
memGraphics.fillRect(x, y, w, h);
scheduleRepaint(x, y, w, h);
return;
@@ -773,21 +599,12 @@
int filter_id = rfb.is.readUnsignedByte();
if (filter_id == rfb.TightFilterPalette) {
numColors = rfb.is.readUnsignedByte() + 1;
- if (bytesPixel == 1) {
- if (numColors != 2) {
- throw new IOException("Incorrect tight palette size: " +
- numColors);
- }
- palette8[0] = rfb.is.readByte();
- palette8[1] = rfb.is.readByte();
- } else {
- byte[] buf = new byte[numColors * 3];
- rfb.is.readFully(buf);
- for (int i = 0; i < numColors; i++) {
- palette24[i] = ((buf[i * 3] & 0xFF) << 16 |
- (buf[i * 3 + 1] & 0xFF) << 8 |
- (buf[i * 3 + 2] & 0xFF));
- }
+ byte[] buf = new byte[numColors * 3];
+ rfb.is.readFully(buf);
+ for (int i = 0; i < numColors; i++) {
+ palette24[i] = ((buf[i * 3] & 0xFF) << 16 |
+ (buf[i * 3 + 1] & 0xFF) << 8 |
+ (buf[i * 3 + 2] & 0xFF));
}
if (numColors == 2)
rowSize = (w + 7) / 8;
@@ -797,7 +614,7 @@
throw new IOException("Incorrect tight filter id: " + filter_id);
}
}
- if (numColors == 0 && bytesPixel == 4)
+ if (numColors == 0)
rowSize *= 3;
// Read, optionally uncompress and decode data.
@@ -810,13 +627,9 @@
rfb.is.readFully(indexedData);
if (numColors == 2) {
// Two colors.
- if (bytesPixel == 1) {
- decodeMonoData(x, y, w, h, indexedData, palette8);
- } else {
- decodeMonoData(x, y, w, h, indexedData, palette24);
- }
+ decodeMonoData(x, y, w, h, indexedData, palette24);
} else {
- // 3..255 colors (assuming bytesPixel == 4).
+ // 3..255 colors.
int i = 0;
for (int dy = y; dy < y + h; dy++) {
for (int dx = x; dx < x + w; dx++) {
@@ -832,22 +645,16 @@
decodeGradientData(x, y, w, h, buf);
} else {
// Raw truecolor data.
- if (bytesPixel == 1) {
- for (int dy = y; dy < y + h; dy++) {
- rfb.is.readFully(pixels8, dy * rfb.framebufferWidth + x, w);
- }
- } else {
- byte[] buf = new byte[w * 3];
- int i, offset;
- for (int dy = y; dy < y + h; dy++) {
- rfb.is.readFully(buf);
- offset = dy * rfb.framebufferWidth + x;
- for (i = 0; i < w; i++) {
- pixels24[offset + i] =
- (buf[i * 3] & 0xFF) << 16 |
- (buf[i * 3 + 1] & 0xFF) << 8 |
- (buf[i * 3 + 2] & 0xFF);
- }
+ byte[] buf = new byte[w * 3];
+ int i, offset;
+ for (int dy = y; dy < y + h; dy++) {
+ rfb.is.readFully(buf);
+ offset = dy * rfb.framebufferWidth + x;
+ for (i = 0; i < w; i++) {
+ pixels24[offset + i] =
+ (buf[i * 3] & 0xFF) << 16 |
+ (buf[i * 3 + 1] & 0xFF) << 8 |
+ (buf[i * 3 + 2] & 0xFF);
}
}
}
@@ -869,13 +676,9 @@
myInflater.inflate(indexedData);
if (numColors == 2) {
// Two colors.
- if (bytesPixel == 1) {
- decodeMonoData(x, y, w, h, indexedData, palette8);
- } else {
- decodeMonoData(x, y, w, h, indexedData, palette24);
- }
+ decodeMonoData(x, y, w, h, indexedData, palette24);
} else {
- // More than two colors (assuming bytesPixel == 4).
+ // More than two colors.
int i = 0;
for (int dy = y; dy < y + h; dy++) {
for (int dx = x; dx < x + w; dx++) {
@@ -885,28 +688,22 @@
}
}
} else if (useGradient) {
- // Compressed "Gradient"-filtered data (assuming bytesPixel == 4).
+ // Compressed "Gradient"-filtered data.
byte[] buf = new byte[w * h * 3];
myInflater.inflate(buf);
decodeGradientData(x, y, w, h, buf);
} else {
// Compressed truecolor data.
- if (bytesPixel == 1) {
- for (int dy = y; dy < y + h; dy++) {
- myInflater.inflate(pixels8, dy * rfb.framebufferWidth + x, w);
- }
- } else {
- byte[] buf = new byte[w * 3];
- int i, offset;
- for (int dy = y; dy < y + h; dy++) {
- myInflater.inflate(buf);
- offset = dy * rfb.framebufferWidth + x;
- for (i = 0; i < w; i++) {
- pixels24[offset + i] =
- (buf[i * 3] & 0xFF) << 16 |
- (buf[i * 3 + 1] & 0xFF) << 8 |
- (buf[i * 3 + 2] & 0xFF);
- }
+ byte[] buf = new byte[w * 3];
+ int i, offset;
+ for (int dy = y; dy < y + h; dy++) {
+ myInflater.inflate(buf);
+ offset = dy * rfb.framebufferWidth + x;
+ for (i = 0; i < w; i++) {
+ pixels24[offset + i] =
+ (buf[i * 3] & 0xFF) << 16 |
+ (buf[i * 3 + 1] & 0xFF) << 8 |
+ (buf[i * 3 + 2] & 0xFF);
}
}
}
@@ -921,30 +718,9 @@
}
//
- // Decode 1bpp-encoded bi-color rectangle (8-bit and 24-bit versions).
+ // Decode 1bpp-encoded bi-color rectangle.
//
- void decodeMonoData(int x, int y, int w, int h, byte[] src, byte[] palette)
- throws IOException {
-
- int dx, dy, n;
- int i = y * rfb.framebufferWidth + x;
- int rowBytes = (w + 7) / 8;
- byte b;
-
- for (dy = 0; dy < h; dy++) {
- for (dx = 0; dx < w / 8; dx++) {
- b = src[dy*rowBytes+dx];
- for (n = 7; n >= 0; n--)
- pixels8[i++] = palette[b >> n & 1];
- }
- for (n = 7; n >= 8 - w % 8; n--) {
- pixels8[i++] = palette[src[dy*rowBytes+dx] >> n & 1];
- }
- i += (rfb.framebufferWidth - w);
- }
- }
-
void decodeMonoData(int x, int y, int w, int h, byte[] src, int[] palette)
throws IOException {
@@ -1021,6 +797,7 @@
void handleUpdatedPixels(int x, int y, int w, int h) {
// Draw updated pixels of the off-screen image.
+
pixelsSource.newPixels(x, y, w, h);
memGraphics.setClip(x, y, w, h);
memGraphics.drawImage(rawPixelsImage, 0, 0, null);
@@ -1033,271 +810,7 @@
void scheduleRepaint(int x, int y, int w, int h) {
// Request repaint, deferred if necessary.
- repaint(viewer.deferScreenUpdates, x, y, w, h);
+ repaint(player.deferScreenUpdates, x, y, w, h);
}
-
- //
- // Handle events.
- //
-
- public void keyPressed(KeyEvent evt) {
- processLocalKeyEvent(evt);
- }
- public void keyReleased(KeyEvent evt) {
- processLocalKeyEvent(evt);
- }
- public void keyTyped(KeyEvent evt) {
- evt.consume();
- }
-
- public void mousePressed(MouseEvent evt) {
- processLocalMouseEvent(evt, false);
- }
- public void mouseReleased(MouseEvent evt) {
- processLocalMouseEvent(evt, false);
- }
- public void mouseMoved(MouseEvent evt) {
- processLocalMouseEvent(evt, true);
- }
- public void mouseDragged(MouseEvent evt) {
- processLocalMouseEvent(evt, true);
- }
-
- public void processLocalKeyEvent(KeyEvent evt) {
- if (rfb != null && rfb.inNormalProtocol) {
- synchronized(rfb) {
- try {
- rfb.writeKeyEvent(evt);
- } catch (Exception e) {
- e.printStackTrace();
- }
- rfb.notify();
- }
- }
- // Don't ever pass keyboard events to AWT for default processing.
- // Otherwise, pressing Tab would switch focus to ButtonPanel etc.
- evt.consume();
- }
-
- public void processLocalMouseEvent(MouseEvent evt, boolean moved) {
- if (rfb != null && rfb.inNormalProtocol) {
- if (moved) {
- softCursorMove(evt.getX(), evt.getY());
- }
- synchronized(rfb) {
- try {
- rfb.writePointerEvent(evt);
- } catch (Exception e) {
- e.printStackTrace();
- }
- rfb.notify();
- }
- }
- }
-
-
- //
- // Ignored events.
- //
-
- public void mouseClicked(MouseEvent evt) {}
- public void mouseEntered(MouseEvent evt) {}
- public void mouseExited(MouseEvent evt) {}
-
-
- //////////////////////////////////////////////////////////////////
- //
- // Handle cursor shape updates (XCursor and RichCursor encodings).
- //
-
- boolean showSoftCursor = false;
-
- int[] softCursorPixels;
- MemoryImageSource softCursorSource;
- Image softCursor;
-
- int cursorX = 0, cursorY = 0;
- int cursorWidth, cursorHeight;
- int hotX, hotY;
-
- //
- // Handle cursor shape update (XCursor and RichCursor encodings).
- //
-
- synchronized void
- handleCursorShapeUpdate(int encodingType,
- int xhot, int yhot, int width, int height)
- throws IOException {
-
- int bytesPerRow = (width + 7) / 8;
- int bytesMaskData = bytesPerRow * height;
-
- softCursorFree();
-
- if (width * height == 0)
- return;
-
- // Ignore cursor shape data if requested by user.
-
- if (viewer.options.ignoreCursorUpdates) {
- if (encodingType == rfb.EncodingXCursor) {
- rfb.is.skipBytes(6 + bytesMaskData * 2);
- } else {
- // rfb.EncodingRichCursor
- rfb.is.skipBytes(width * height + bytesMaskData);
- }
- return;
- }
-
- // Decode cursor pixel data.
-
- softCursorPixels = new int[width * height];
-
- if (encodingType == rfb.EncodingXCursor) {
-
- // Read foreground and background colors of the cursor.
- byte[] rgb = new byte[6];
- rfb.is.readFully(rgb);
- int[] colors = { (0xFF000000 | (rgb[3] & 0xFF) << 16 |
- (rgb[4] & 0xFF) << 8 | (rgb[5] & 0xFF)),
- (0xFF000000 | (rgb[0] & 0xFF) << 16 |
- (rgb[1] & 0xFF) << 8 | (rgb[2] & 0xFF)) };
-
- // Read pixel and mask data.
- byte[] pixBuf = new byte[bytesMaskData];
- rfb.is.readFully(pixBuf);
- byte[] maskBuf = new byte[bytesMaskData];
- rfb.is.readFully(maskBuf);
-
- // Decode pixel data into softCursorPixels[].
- byte pixByte, maskByte;
- int x, y, n, result;
- int i = 0;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width / 8; x++) {
- pixByte = pixBuf[y * bytesPerRow + x];
- maskByte = maskBuf[y * bytesPerRow + x];
- for (n = 7; n >= 0; n--) {
- if ((maskByte >> n & 1) != 0) {
- result = colors[pixByte >> n & 1];
- } else {
- result = 0; // Transparent pixel
- }
- softCursorPixels[i++] = result;
- }
- }
- for (n = 7; n >= 8 - width % 8; n--) {
- if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) {
- result = colors[pixBuf[y * bytesPerRow + x] >> n & 1];
- } else {
- result = 0; // Transparent pixel
- }
- softCursorPixels[i++] = result;
- }
- }
-
- } else {
- // encodingType == rfb.EncodingRichCursor
-
- // Read pixel and mask data.
- byte[] pixBuf = new byte[width * height * bytesPixel];
- rfb.is.readFully(pixBuf);
- byte[] maskBuf = new byte[bytesMaskData];
- rfb.is.readFully(maskBuf);
-
- // Decode pixel data into softCursorPixels[].
- byte pixByte, maskByte;
- int x, y, n, result;
- int i = 0;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width / 8; x++) {
- maskByte = maskBuf[y * bytesPerRow + x];
- for (n = 7; n >= 0; n--) {
- if ((maskByte >> n & 1) != 0) {
- if (bytesPixel == 1) {
- result = cm8.getRGB(pixBuf[i]);
- } else {
- result = 0xFF000000 |
- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
- (pixBuf[i * 4 + 3] & 0xFF);
- }
- } else {
- result = 0; // Transparent pixel
- }
- softCursorPixels[i++] = result;
- }
- }
- for (n = 7; n >= 8 - width % 8; n--) {
- if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) {
- if (bytesPixel == 1) {
- result = cm8.getRGB(pixBuf[i]);
- } else {
- result = 0xFF000000 |
- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
- (pixBuf[i * 4 + 3] & 0xFF);
- }
- } else {
- result = 0; // Transparent pixel
- }
- softCursorPixels[i++] = result;
- }
- }
-
- }
-
- // Draw the cursor on an off-screen image.
-
- softCursorSource =
- new MemoryImageSource(width, height, softCursorPixels, 0, width);
- softCursor = createImage(softCursorSource);
-
- // Set remaining data associated with cursor.
-
- cursorWidth = width;
- cursorHeight = height;
- hotX = xhot;
- hotY = yhot;
-
- showSoftCursor = true;
-
- // Show the cursor.
-
- repaint(viewer.deferCursorUpdates,
- cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight);
- }
-
- //
- // softCursorMove(). Moves soft cursor into a particular location.
- //
-
- synchronized void softCursorMove(int x, int y) {
- if (showSoftCursor) {
- repaint(viewer.deferCursorUpdates,
- cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight);
- repaint(viewer.deferCursorUpdates,
- x - hotX, y - hotY, cursorWidth, cursorHeight);
- }
-
- cursorX = x;
- cursorY = y;
- }
-
- //
- // softCursorFree(). Remove soft cursor, dispose resources.
- //
-
- synchronized void softCursorFree() {
- if (showSoftCursor) {
- showSoftCursor = false;
- softCursor = null;
- softCursorSource = null;
- softCursorPixels = null;
-
- repaint(viewer.deferCursorUpdates,
- cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight);
- }
- }
}