Exemple #1
0
        /// <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());
        }
Exemple #5
0
        /// <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);
            }
        }
Exemple #6
0
        /// <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);
            }
        }
Exemple #7
0
        /// <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);
            }
        }