/// <summary> /// Queues an update corresponding to one region of the framebuffer being copied to another. /// </summary> /// <param name="target"> /// The updated <see cref="VncRectangle"/>. /// </param> /// <param name="sourceX"> /// The X coordinate of the source. /// </param> /// <param name="sourceY"> /// The Y coordinate of the source. /// </param> /// <remarks> /// Do not call this method without holding <see cref="VncServerSession.FramebufferUpdateRequestLock"/>. /// </remarks> public void FramebufferManualCopyRegion(VncRectangle target, int sourceX, int sourceY) { if (!this.clientEncoding.Contains(VncEncoding.CopyRect)) { var source = new VncRectangle(sourceX, sourceY, target.Width, target.Height); var region = VncRectangle.Union(source, target); if (region.Area > source.Area + target.Area) { this.FramebufferManualInvalidate(new[] { source, target }); } else { this.FramebufferManualInvalidate(region); } return; } var contents = new byte[4]; VncUtility.EncodeUInt16BE(contents, 0, (ushort)sourceX); VncUtility.EncodeUInt16BE(contents, 2, (ushort)sourceY); this.AddRegion(target, VncEncoding.CopyRect, contents); }
/// <inheritdoc/> public override void Send(Stream stream, VncPixelFormat pixelFormat, VncRectangle region, byte[] contents) { this.buffer.SetLength(0); this.deflater.Write(contents, 0, contents.Length); this.deflater.Flush(); this.buffer.Position = 0; byte[] length = new byte[4]; VncUtility.EncodeUInt32BE(length, 0, (uint)this.buffer.Length); stream.Write(length, 0, 4); this.buffer.CopyTo(stream); }
/// <inheritdoc/> public void FramebufferManualInvalidate(VncRectangle region) { var fb = this.Framebuffer; var cpf = this.clientPixelFormat; region = VncRectangle.Intersect(region, new VncRectangle(0, 0, this.clientWidth, this.clientHeight)); if (region.IsEmpty) { return; } int x = region.X, y = region.Y, w = region.Width, h = region.Height, bpp = cpf.BytesPerPixel; var contents = new byte[w * h * bpp]; VncPixelFormat.Copy( fb.GetBuffer(), fb.Width, fb.Stride, fb.PixelFormat, region, contents, w, w * bpp, cpf); #if DEFLATESTREAM_FLUSH_WORKS if (_clientEncoding.Contains(VncEncoding.Zlib)) { _zlibMemoryStream.Position = 0; _zlibMemoryStream.SetLength(0); _zlibMemoryStream.Write(new byte[4], 0, 4); if (_zlibDeflater == null) { _zlibMemoryStream.Write(new[] { (byte)120, (byte)218 }, 0, 2); _zlibDeflater = new DeflateStream(_zlibMemoryStream, CompressionMode.Compress, false); } _zlibDeflater.Write(contents, 0, contents.Length); _zlibDeflater.Flush(); contents = _zlibMemoryStream.ToArray(); VncUtility.EncodeUInt32BE(contents, 0, (uint)(contents.Length - 4)); AddRegion(region, VncEncoding.Zlib, contents); } else #endif { this.AddRegion(region, VncEncoding.Raw, contents); } }
/// <inheritdoc/> public void FramebufferManualInvalidate(VncRectangle region) { var fb = this.Framebuffer; var cpf = this.clientPixelFormat; region = VncRectangle.Intersect(region, new VncRectangle(0, 0, this.clientWidth, this.clientHeight)); if (region.IsEmpty) { return; } int x = region.X, y = region.Y, w = region.Width, h = region.Height, bpp = cpf.BytesPerPixel; var contents = new byte[w * h * bpp]; VncPixelFormat.Copy( fb.GetBuffer(), fb.Width, fb.Stride, fb.PixelFormat, region, contents, w, w * bpp, cpf); if (clientEncoding.Contains(VncEncoding.Zlib)) { byte[] zlibContents = Compress(contents); var lenArray = new byte[4]; VncUtility.EncodeUInt32BE(lenArray, 0, (uint)(zlibContents.Length)); var finArray = Combine(lenArray, zlibContents); AddRegion(region, VncEncoding.Zlib, finArray); } else { this.AddRegion(region, VncEncoding.Raw, contents); } }