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

📄 vnccanvas.java

📁 teamviewer source code vc++
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -