⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vnccanvas.java

📁 一个远程登陆器的原代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
		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 + -