/// <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); this.AddRegion(region, VncEncoding.Raw, contents); }
/// <summary> /// Copies a region of the framebuffer into a bitmap. /// </summary> /// <param name="source">The framebuffer to read.</param> /// <param name="sourceRectangle">The framebuffer region to copy.</param> /// <param name="target">The bitmap to copy into.</param> /// <param name="targetX">The leftmost X coordinate of the bitmap to draw to.</param> /// <param name="targetY">The topmost Y coordinate of the bitmap to draw to.</param> public unsafe static void CopyFromFramebuffer(VncFramebuffer source, VncRectangle sourceRectangle, Bitmap target, int targetX, int targetY) { Throw.If.Null(source, "source").Null(target, "target"); if (sourceRectangle.IsEmpty) { return; } var winformsRect = new Rectangle(targetX, targetY, sourceRectangle.Width, sourceRectangle.Height); var data = target.LockBits(winformsRect, ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); try { fixed(byte *framebufferData = source.GetBuffer()) { VncPixelFormat.Copy((IntPtr)framebufferData, source.Stride, source.PixelFormat, sourceRectangle, data.Scan0, data.Stride, new VncPixelFormat()); } } finally { target.UnlockBits(data); } }
/// <summary> /// 将需要更新位图的区域复制到framebuffer中 /// </summary> /// <param name="source">图片源.</param> /// <param name="sourceRectangle">要复制的位图区域.</param> /// <param name="target">目标帧缓冲区</param> /// <param name="targetX">帧缓冲区的左顶点X坐标</param> /// <param name="targetY">帧缓冲区的左顶点Y坐标</param> public unsafe static void CopyToFramebuffer(Bitmap source, VncRectangle sourceRectangle, VncFramebuffer target, int targetX, int targetY) { Throw.If.Null(source, "source").Null(target, "target"); if (sourceRectangle.IsEmpty) { return; } var winformsRect = new Rectangle(sourceRectangle.X, sourceRectangle.Y, sourceRectangle.Width, sourceRectangle.Height); var data = source.LockBits(winformsRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); try { fixed(byte *framebufferData = target.GetBuffer()) { VncPixelFormat.Copy(data.Scan0, data.Stride, new VncPixelFormat(32, 24, 8, 16, 8, 8, 8, 0), sourceRectangle, (IntPtr)framebufferData, target.Stride, target.PixelFormat, targetX, targetY); } } finally { source.UnlockBits(data); } }
public bool RespondToUpdateRequest(VncServerSession session) { var fb = Framebuffer; var fbr = session.FramebufferUpdateRequest; if (fb == null || fbr == null) { return(false); } var incremental = fbr.Incremental; var region = fbr.Region; session.FramebufferManualBeginUpdate(); var buffer = fb.GetBuffer(); int bpp = fb.PixelFormat.BytesPerPixel; lock (fb.SyncRoot) { int ymax = Math.Min(region.Y + region.Height, fb.Height); int xmax = Math.Min(region.X + region.Width, fb.Width); for (int y = region.Y; y < ymax; y += TileSize) { for (int x = region.X; x < xmax; x += TileSize) { int w = Math.Min(TileSize, xmax - x); int h = Math.Min(TileSize, ymax - y); var subregion = new VncRectangle(x, y, w, h); VncPixelFormat.Copy(buffer, fb.Stride, fb.PixelFormat, subregion, _pixelBuffer, w * bpp, Framebuffer.PixelFormat); int ix = x / TileSize, iy = y / TileSize; var tileHash = _hash.ComputeHash(_pixelBuffer, 0, w * h * bpp); if (_hashes[iy, ix] == null || !_hashes[iy, ix].SequenceEqual(tileHash)) { _hashes[iy, ix] = tileHash; if (incremental) { session.FramebufferManualInvalidate(subregion); } } } } } if (!incremental) { session.FramebufferManualInvalidate(region); } return(session.FramebufferManualEndUpdate()); }
/// <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); } }
/// <summary> /// Copies a region of a bitmap into the framebuffer. /// </summary> /// <param name="source">The bitmap to read.</param> /// <param name="sourceRectangle">The bitmap region to copy.</param> /// <param name="target">The framebuffer to copy into.</param> /// <param name="targetX">The leftmost X coordinate of the framebuffer to draw to.</param> /// <param name="targetY">The topmost Y coordinate of the framebuffer to draw to.</param> public static unsafe void CopyToFramebuffer( Bitmap source, VncRectangle sourceRectangle, VncFramebuffer target, int targetX, int targetY) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (sourceRectangle.IsEmpty) { return; } var winformsRect = new Rectangle(sourceRectangle.X, sourceRectangle.Y, sourceRectangle.Width, sourceRectangle.Height); var data = source.LockBits(winformsRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); try { fixed(byte *framebufferData = target.GetBuffer()) { VncPixelFormat.Copy( data.Scan0, data.Stride, new VncPixelFormat(), sourceRectangle, (IntPtr)framebufferData, target.Stride, target.PixelFormat, targetX, targetY); } } finally { source.UnlockBits(data); } }
/// <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); } }