Пример #1
0
        /// <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="scan0">The bitmap buffer start address</param>
        /// <param name="stride">The bitmap width stride</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 static unsafe void CopyFromFramebuffer(
            VncFramebuffer source,
            VncRectangle sourceRectangle,
            IntPtr scan0,
            int stride,
            int targetX,
            int targetY)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (sourceRectangle.IsEmpty)
            {
                return;
            }

            fixed(byte *framebufferData = source.GetBuffer())
            {
                VncPixelFormat.Copy(
                    (IntPtr)framebufferData,
                    source.Stride,
                    source.PixelFormat,
                    sourceRectangle,
                    scan0,
                    stride,
                    new VncPixelFormat());
            }
        }
Пример #2
0
        private void NegotiateDesktop()
        {
            this.c.SendByte((byte)(this.options.ShareDesktop ? 1 : 0));

            var width = this.c.ReceiveUInt16BE();

            VncStream.SanityCheck(width > 0 && width < 0x8000);
            var height = this.c.ReceiveUInt16BE();

            VncStream.SanityCheck(height > 0 && height < 0x8000);

            VncPixelFormat pixelFormat;

            try
            {
                pixelFormat = VncPixelFormat.Decode(this.c.Receive(VncPixelFormat.Size), 0);
            }
            catch (ArgumentException e)
            {
                throw new VncException(
                          "Unsupported pixel format.",
                          VncFailureReason.UnsupportedPixelFormat,
                          e);
            }

            var name = this.c.ReceiveString();

            this.Framebuffer = new VncFramebuffer(name, width, height, pixelFormat);
        }
Пример #3
0
        /// <summary>
        /// <para>
        /// Copies pixels. A format conversion is performed if necessary.
        /// </para>
        /// <para>
        /// Be sure to lock <see cref="VncFramebuffer.SyncRoot"/> first to avoid tearing,
        /// if the connection is active.
        /// </para>
        /// </summary>
        /// <param name="source">A pointer to the upper-left corner of the source.</param>
        /// <param name="sourceStride">The offset in the source between one Y coordinate and the next.</param>
        /// <param name="sourceFormat">The source pixel format.</param>
        /// <param name="sourceRectangle">The rectangle in the source to decode.</param>
        /// <param name="target">A pointer to the upper-left corner of the target.</param>
        /// <param name="targetStride">The offset in the target between one Y coordinate and the next.</param>
        /// <param name="targetFormat">The target pixel format.</param>
        /// <param name="targetX">The X coordinate in the target that the leftmost pixel should be placed into.</param>
        /// <param name="targetY">The Y coordinate in the target that the topmost pixel should be placed into.</param>
        public static unsafe void Copy(
            IntPtr source,
            int sourceStride,
            VncPixelFormat sourceFormat,
            VncRectangle sourceRectangle,
            IntPtr target,
            int targetStride,
            VncPixelFormat targetFormat,
            int targetX = 0,
            int targetY = 0)
        {
            Throw.If.True(source == IntPtr.Zero, "source").True(target == IntPtr.Zero, "target");
            Throw.If.Null(sourceFormat, "sourceFormat").Null(targetFormat, "targetFormat");

            if (sourceRectangle.IsEmpty)
            {
                return;
            }

            int x = sourceRectangle.X, w = sourceRectangle.Width;
            int y = sourceRectangle.Y, h = sourceRectangle.Height;

            var sourceData = (byte *)(void *)source + (y * sourceStride) + (x * sourceFormat.BytesPerPixel);
            var targetData = (byte *)(void *)target + (targetY * targetStride) + (targetX * targetFormat.BytesPerPixel);

            if (sourceFormat.Equals(targetFormat))
            {
                for (int iy = 0; iy < h; iy++)
                {
                    if (sourceFormat.BytesPerPixel == 4)
                    {
                        uint *sourceDataX0 = (uint *)sourceData, targetDataX0 = (uint *)targetData;
                        for (int ix = 0; ix < w; ix++)
                        {
                            *targetDataX0++ = *sourceDataX0++;
                        }
                    }
                    else
                    {
                        int   bytes = w * sourceFormat.BytesPerPixel;
                        byte *sourceDataX0 = (byte *)sourceData, targetDataX0 = (byte *)targetData;
                        for (int ib = 0; ib < bytes; ib++)
                        {
                            *targetDataX0++ = *sourceDataX0++;
                        }
                    }

                    sourceData += sourceStride;
                    targetData += targetStride;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VncFramebuffer"/> class.
        /// </summary>
        /// <param name="name">The framebuffer name. Many VNC clients set their titlebar to this name.</param>
        /// <param name="width">The framebuffer width.</param>
        /// <param name="height">The framebuffer height.</param>
        /// <param name="pixelFormat">The framebuffer pixel format.</param>
        public VncFramebuffer(string name, int width, int height, VncPixelFormat pixelFormat)
        {
            Throw.If.Null(name, "name");
            Throw.If.Negative(width, "width").Negative(height, "height");
            Throw.If.Null(pixelFormat, "pixelFormat");

            this.Name        = name;
            this.Width       = width;
            this.Height      = height;
            this.PixelFormat = pixelFormat;
            this.Stride      = this.PixelFormat.BytesPerPixel * this.Width;
            this.SyncRoot    = new object();

            this.buffer = new byte[this.Width * this.Height * this.PixelFormat.BytesPerPixel];
        }
Пример #5
0
        /// <summary>
        /// Copies pixels between two byte arrays. A format conversion is performed if necessary.
        ///
        /// Be sure to lock <see cref="VncFramebuffer.SyncRoot"/> first to avoid tearing,
        /// if the connection is active.
        /// </summary>
        /// <param name="source">A pointer to the upper-left corner of the source.</param>
        /// <param name="sourceWidth">The width of the source image.</param>
        /// <param name="sourceStride">The offset in the source between one Y coordinate and the next.</param>
        /// <param name="sourceFormat">The source pixel format.</param>
        /// <param name="sourceRectangle">The rectangle in the source to decode.</param>
        /// <param name="target">A pointer to the upper-left corner of the target.</param>
        /// <param name="targetWidth">The width of the target image.</param>
        /// <param name="targetStride">The offset in the target between one Y coordinate and the next.</param>
        /// <param name="targetFormat">The target pixel format.</param>
        /// <param name="targetX">The X coordinate in the target that the leftmost pixel should be placed into.</param>
        /// <param name="targetY">The Y coordinate in the target that the topmost pixel should be placed into.</param>
        public static unsafe void Copy(
            byte[] source,
            int sourceWidth,
            int sourceStride,
            VncPixelFormat sourceFormat,
            VncRectangle sourceRectangle,
            byte[] target,
            int targetWidth,
            int targetStride,
            VncPixelFormat targetFormat,
            int targetX = 0,
            int targetY = 0)
        {
            Throw.If.Null(source, "source").Null(target, "target");

            if (sourceRectangle.IsEmpty)
            {
                return;
            }

            int x = sourceRectangle.X, w = sourceRectangle.Width;
            int y = sourceRectangle.Y, h = sourceRectangle.Height;

            if (sourceFormat.Equals(targetFormat))
            {
                if (sourceRectangle.Width == sourceWidth &&
                    sourceWidth == targetWidth &&
                    sourceStride == targetStride)
                {
                    int sourceStart = sourceStride * y;
                    int length      = targetStride * h;

                    Buffer.BlockCopy(source, sourceStart, target, 0, length);
                }
                else
                {
                    for (int iy = 0; iy < h; iy++)
                    {
                        int sourceStart = (sourceStride * (iy + y)) + (x * sourceFormat.BitsPerPixel / 8);
                        int targetStart = targetStride * iy;

                        int length = w * sourceFormat.BitsPerPixel / 8;

                        Buffer.BlockCopy(source, sourceStart, target, targetStart, length);
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Loads the framebuffer from the specified location and returns a function that can be used to copy the data to a bitmap.
        /// </summary>
        /// <param name="x">The x offset. (0 if null)</param>
        /// <param name="y">The y offset. (0 if null)</param>
        /// <param name="width">The width. (Framebuffer.Width if null)</param>
        /// <param name="height">The height (Framebuffer.Height if null)</param>
        /// <returns>An action with 2 parameters (BitmapData.Scan0 and BitmapData.Stride) that copies the framebuffer data to the specfied address</returns>
        public Action <IntPtr, int> GetFramebuffer(int?x = null, int?y = null, int?width = null, int?height = null)
        {
            var xValue      = x ?? 0;
            var yValue      = y ?? 0;
            var widthValue  = width ?? this.Framebuffer.Width;
            var heightValue = height ?? this.Framebuffer.Height;

            this.SendFramebufferUpdateRequest(false, xValue, yValue, widthValue, heightValue);

            ResponseType handledResponse;

            do
            {
                handledResponse = this.HandleResponse();
                if (handledResponse == ResponseType.DesktopSize)
                {
                    this.SendFramebufferUpdateRequest(false, xValue, yValue, widthValue, heightValue);
                }
            }while (handledResponse != ResponseType.FramebufferUpdate);

            return((scan0, stride) => VncPixelFormat.CopyFromFramebuffer(
                       this.Framebuffer, new VncRectangle(xValue, yValue, widthValue, heightValue), scan0, stride, 0, 0));
        }