?? vnccanvas.java
字號:
handleUpdatedPixels(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 {
rfb.readCopyRect();
memGraphics.copyArea(
rfb.copyRectSrcX,
rfb.copyRectSrcY,
w,
h,
x - rfb.copyRectSrcX,
y - rfb.copyRectSrcY);
scheduleRepaint(x, y, w, h);
}
//
// Handle an RRE-encoded rectangle.
//
void handleRRERect(int x, int y, int w, int h) throws IOException {
int nSubrects = rfb.is.readInt();
byte[] bg_buf = new byte[bytesPixel];
rfb.is.readFully(bg_buf);
Color pixel;
if (bytesPixel == 1)
{
pixel = colors[bg_buf[0] & 0xFF];
}
else
{
pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF);
}
memGraphics.setColor(pixel);
memGraphics.fillRect(x, y, w, h);
byte[] buf = new byte[nSubrects * (bytesPixel + 8)];
rfb.is.readFully(buf);
DataInputStream ds = new DataInputStream(new ByteArrayInputStream(buf));
if (rfb.rec != null) {
rfb.rec.writeIntBE(nSubrects);
rfb.rec.write(bg_buf);
rfb.rec.write(buf);
}
int sx, sy, sw, sh;
for (int j = 0; j < nSubrects; j++) {
if (bytesPixel == 1) {
pixel = colors[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();
memGraphics.setColor(pixel);
memGraphics.fillRect(sx, sy, sw, sh);
}
scheduleRepaint(x, y, w, h);
}
//
// Handle a CoRRE-encoded rectangle.
//
void handleCoRRERect(int x, int y, int w, int h) throws IOException {
int nSubrects = rfb.is.readInt();
byte[] bg_buf = new byte[bytesPixel];
rfb.is.readFully(bg_buf);
Color pixel;
if (bytesPixel == 1) {
pixel = colors[bg_buf[0] & 0xFF];
} else {
pixel =
new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF);
}
memGraphics.setColor(pixel);
memGraphics.fillRect(x, y, w, h);
byte[] buf = new byte[nSubrects * (bytesPixel + 4)];
rfb.is.readFully(buf);
if (rfb.rec != null) {
rfb.rec.writeIntBE(nSubrects);
rfb.rec.write(bg_buf);
rfb.rec.write(buf);
}
int sx, sy, sw, sh;
int i = 0;
for (int j = 0; j < nSubrects; j++) {
if (bytesPixel == 1) {
pixel = colors[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;
memGraphics.setColor(pixel);
memGraphics.fillRect(sx, sy, sw, sh);
}
scheduleRepaint(x, y, w, h);
}
//
// Handle a Hextile-encoded rectangle.
//
// These colors should be kept between handleHextileSubrect() calls.
private Color hextile_bg, hextile_fg;
void handleHextileRect(int x, int y, int w, int h) throws IOException {
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);
}
// Finished with a row of tiles, now let's show it.
scheduleRepaint(x, y, w, h);
}
}
//
// Handle one tile in the Hextile-encoded data.
//
void handleHextileSubrect(int tx, int ty, int tw, int th)
throws IOException {
int subencoding = rfb.is.readUnsignedByte();
if (rfb.rec != null) {
rfb.rec.writeByte(subencoding);
}
// Is it a raw-encoded sub-rectangle?
if ((subencoding & rfb.HextileRaw) != 0) {
handleRawRect(tx, ty, tw, th, false);
return;
}
// Read and draw the background if specified.
byte[] cbuf = new byte[bytesPixel];
if ((subencoding & rfb.HextileBackgroundSpecified) != 0) {
rfb.is.readFully(cbuf);
if (bytesPixel == 1) {
hextile_bg = colors[cbuf[0] & 0xFF];
} else {
hextile_bg =
new Color(cbuf[2] & 0xFF, cbuf[1] & 0xFF, cbuf[0] & 0xFF);
}
if (rfb.rec != null) {
rfb.rec.write(cbuf);
}
}
memGraphics.setColor(hextile_bg);
memGraphics.fillRect(tx, ty, tw, th);
// Read the foreground color if specified.
if ((subencoding & rfb.HextileForegroundSpecified) != 0) {
rfb.is.readFully(cbuf);
if (bytesPixel == 1) {
hextile_fg = colors[cbuf[0] & 0xFF];
} else {
hextile_fg =
new Color(cbuf[2] & 0xFF, cbuf[1] & 0xFF, cbuf[0] & 0xFF);
}
if (rfb.rec != null) {
rfb.rec.write(cbuf);
}
}
// Done with this tile if there is no sub-rectangles.
if ((subencoding & rfb.HextileAnySubrects) == 0)
return;
int nSubrects = rfb.is.readUnsignedByte();
int bufsize = nSubrects * 2;
if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
bufsize += nSubrects * bytesPixel;
}
byte[] buf = new byte[bufsize];
rfb.is.readFully(buf);
if (rfb.rec != null) {
rfb.rec.writeByte(nSubrects);
rfb.rec.write(buf);
}
int b1, b2, sx, sy, sw, sh;
int i = 0;
if ((subencoding & rfb.HextileSubrectsColoured) == 0) {
// Sub-rectangles are all of the same color.
memGraphics.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;
memGraphics.fillRect(sx, sy, sw, sh);
}
} else if (bytesPixel == 1) {
// BGR233 (8-bit color) version for colored sub-rectangles.
for (int j = 0; j < nSubrects; j++) {
hextile_fg = colors[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;
memGraphics.setColor(hextile_fg);
memGraphics.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;
memGraphics.setColor(hextile_fg);
memGraphics.fillRect(sx, sy, sw, sh);
}
}
}
//
// Handle a Zlib-encoded rectangle.
//
void handleZlibRect(int x, int y, int w, int h) throws Exception {
int nBytes = rfb.is.readInt();
if (zlibBuf == null || zlibBufLen < nBytes) {
zlibBufLen = nBytes * 2;
zlibBuf = new byte[zlibBufLen];
}
rfb.is.readFully(zlibBuf, 0, nBytes);
if (rfb.rec != null && rfb.recordFromBeginning) {
rfb.rec.writeIntBE(nBytes);
rfb.rec.write(zlibBuf, 0, nBytes);
}
if (zlibInflater == null) {
zlibInflater = new Inflater();
}
zlibInflater.setInput(zlibBuf, 0, nBytes);
if (bytesPixel == 1) {
for (int dy = y; dy < y + h; dy++) {
zlibInflater.inflate(pixels8, dy * rfb.framebufferWidth + x, w);
if (rfb.rec != null && !rfb.recordFromBeginning)
rfb.rec.write(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 + 2] & 0xFF)
<< 16 | (buf[i * 4 + 1] & 0xFF)
<< 8 | (buf[i * 4] & 0xFF);
}
if (rfb.rec != null && !rfb.recordFromBeginning)
rfb.rec.write(buf);
}
}
handleUpdatedPixels(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 {
int comp_ctl = rfb.is.readUnsignedByte();
if (rfb.rec != null) {
if (rfb.recordFromBeginning
|| comp_ctl == (rfb.TightFill << 4)
|| comp_ctl == (rfb.TightJpeg << 4)) {
// Send data exactly as received.
rfb.rec.writeByte(comp_ctl);
} else {
// Tell the decoder to flush each of the four zlib streams.
rfb.rec.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 > rfb.TightMaxSubencoding) {
throw new Exception("Incorrect tight subencoding: " + comp_ctl);
}
// Handle solid-color rectangles.
if (comp_ctl == rfb.TightFill) {
if (bytesPixel == 1) {
int idx = rfb.is.readUnsignedByte();
memGraphics.setColor(colors[idx]);
if (rfb.rec != null) {
rfb.rec.writeByte(idx);
}
} else {
byte[] buf = new byte[3];
rfb.is.readFully(buf);
if (rfb.rec != null) {
rfb.rec.write(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;
}
if (comp_ctl == rfb.TightJpeg) {
// Read JPEG data.
byte[] jpegData = new byte[rfb.readCompactLen()];
rfb.is.readFully(jpegData);
if (rfb.rec != null) {
if (!rfb.recordFromBeginning) {
rfb.recordCompactLen(jpegData.length);
}
rfb.rec.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;
}
// 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 & rfb.TightExplicitFilter) != 0) {
int filter_id = rfb.is.readUnsignedByte();
if (rfb.rec != null) {
rfb.rec.writeByte(filter_id);
}
if (filter_id == rfb.TightFilterPalette) {
numColors = rfb.is.readUnsignedByte() + 1;
if (rfb.rec != null) {
rfb.rec.writeByte(numColors - 1);
}
if (bytesPixel == 1) {
if (numColors != 2) {
throw new Exception(
"Incorrect tight palette size: " + numColors);
}
rfb.is.readFully(palette8);
if (rfb.rec != null) {
rfb.rec.write(palette8);
}
} else {
byte[] buf = new byte[numColors * 3];
rfb.is.readFully(buf);
if (rfb.rec != null) {
rfb.rec.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 == rfb.TightFilterGradient) {
useGradient = true;
} else if (filter_id != rfb.TightFilterCopy) {
throw new Exception("Incorrect tight filter id: " + filter_id);
}
}
if (numColors == 0 && bytesPixel == 4)
rowSize *= 3;
// Read, optionally uncompress and decode data.
int dataSize = h * rowSize;
if (dataSize < rfb.TightMinToCompress) {
// Data size is small - not compressed with zlib.
if (numColors != 0) {
// Indexed colors.
byte[] indexedData = new byte[dataSize];
rfb.is.readFully(indexedData);
if (rfb.rec != null) {
rfb.rec.write(indexedData);
}
if (numColors == 2) {
// Two colors.
if (bytesPixel == 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 * rfb.framebufferWidth + dx] =
palette24[indexedData[i++] & 0xFF];
}
}
}
} else if (useGradient) {
// "Gradient"-processed data
byte[] buf = new byte[w * h * 3];
rfb.is.readFully(buf);
if (rfb.rec != null) {
rfb.rec.write(buf);
}
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);
if (rfb.rec != null) {
rfb.rec.write(
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);
if (rfb.rec != null) {
rfb.rec.write(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);
}
}
}
}
} else {
// Data was compressed with zlib.
int zlibDataLen = rfb.readCompactLen();
byte[] zlibData = new byte[zlibDataLen];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -