This structure specifies a rectangle relative to the virtual-desktop origin. Section 2.2.4.4 Note that the width and height of the MPEG-4 AVC/H.264 codec bitstream MUST be aligned to a multiple of 16
            public void SolidFill(RDPGFX_COLOR32 fillPixel, RDPGFX_RECT16[] fillRects)
            {
                if (fillRects != null && fillRects.Length > 0)
                {
                    Color c = Color.Black;
                    if (this.pixelFormat == PixelFormat.PIXEL_FORMAT_ARGB_8888)
                    {
                        c = Color.FromArgb(fillPixel.XA, fillPixel.R, fillPixel.G, fillPixel.B);
                    }
                    else
                    {
                        c = Color.FromArgb(fillPixel.R, fillPixel.G, fillPixel.B);
                    }
                    Brush brush = new SolidBrush(c);
                    Rectangle[] rects = new Rectangle[fillRects.Length];
                    for (int i = 0; i < fillRects.Length; i++)
                    {
                        rects[i] = new Rectangle(fillRects[i].left, fillRects[i].top, fillRects[i].right - fillRects[i].left, fillRects[i].bottom - fillRects[i].top);
                    }
                    imageGraphic.FillRectangles(brush, rects);

                    if (mapPoints.Count > 0)
                    {
                        List<Rectangle> rectList = new List<Rectangle>();
                        foreach (Point p in mapPoints)
                        {
                            foreach(Rectangle rect in rects)
                            {
                                rectList.Add(new Rectangle(rect.Left+p.X, rect.Top+p.Y, rect.Width, rect.Height));
                            }
                        }
                        Graphics baseImageGraphics = Graphics.FromImage(screen.BaseImage);

                        baseImageGraphics.FillRectangles(brush, rectList.ToArray());

                        baseImageGraphics.Dispose();
                    }

                }
            }
        /// <summary>
        /// Send bitmap data in clearCodec encoding method.
        /// </summary>
        /// <param name="sId">This is used to indicate the target surface id.</param>
        /// <param name="pixFormat">This is used to indicate the pixel format to fill target surface.</param>
        /// <param name="ccFlag">This is used to indicate the clearcodec stream flags.</param>
        /// <param name="graphIdx">This is used to indicate the index of graph to be put in client graph cache.</param>
        /// <param name="bmRect">The rectangle of whole Image, which will be sent in clearcodec, relative to the surface </param>
        /// <param name="residualImage"> The residual layer image to be sent </param>
        /// <param name="bands"> The dictionary of band layer image and position </param>
        /// <param name="subcodecs"> The dictionary of subcodec layer image, subcodecID and position </param>
        /// <returns> Frame Id </returns>
        public uint SendImageWithClearCodec(ushort sId, PixelFormat pixFormat, byte ccFlag, ushort graphIdx, RDPGFX_RECT16 bmRect, Image residualBmp, 
            Dictionary<RDPGFX_POINT16, Bitmap> bands, Dictionary<RDPGFX_POINT16, BMP_INFO> subcodecs)
        {
            uint fid = MakeStartFramePdu();

            ClearCodec_BitmapStream ccStream = new ClearCodec_BitmapStream(ccFlag, graphIdx);
            if ((ushort)currentTestType >= 500 && (ushort)currentTestType <= 599)
            {
                // Clearcodec negative test
                ccStream.SetTestType(currentTestType);
            }

            ccStream.LoadResidualBitmap((Bitmap)residualBmp);
            if(bands != null)
            {
                foreach (KeyValuePair<RDPGFX_POINT16, Bitmap> band in bands)
                {
                    ccStream.LoadBandBitmap(band.Value, band.Key);
                }
            }
            if (subcodecs != null)
            {
                foreach (KeyValuePair<RDPGFX_POINT16, BMP_INFO> scBmp in subcodecs)
                {
                    ccStream.LoadSubcodecBitmap(scBmp.Value.bmp, scBmp.Key, scBmp.Value.scID);
                }
            }
            ccStream.seqNumber = egfxServer.Get_ClearCodecBitmapStream_SeqNum();
            MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_CLEARCODEC, pixFormat, bmRect, ccStream.Encode());
            MakeEndFramePdu(fid);

            PackAndSendServerPdu();

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.RenderClearCodecImage(sId, pixFormat, ccFlag, graphIdx, bmRect, residualBmp, bands, subcodecs);
            }

            return fid;
        }
        /// <summary>
        /// Send bitmap data in H264 AVC444 codec
        /// </summary>
        /// <param name="sId">This is used to indicate the target surface id</param>
        /// <param name="pixFormat">This is used to indicate the pixel format to fill target surface.</param>
        /// <param name="bmRect">The rectangle of whole Image</param>
        /// <param name="avc444BitmapStream">A RFX_AVC444_BITMAP_STREAM structure for encoded information</param>
        /// <param name="baseImage">Base Image used to verify output</param>
        /// <returns></returns>
        public uint SendImageWithH264AVC444Codec(ushort sId, PixelFormat pixFormat, RDPGFX_RECT16 bmRect, RFX_AVC444_BITMAP_STREAM avc444BitmapStream,
            Image baseImage)
        {
            uint fid = MakeStartFramePdu();
            MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_AVC444, pixFormat, bmRect, avc444BitmapStream.Encode());
            MakeEndFramePdu(fid);
            PackAndSendServerPdu();

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                if (baseImage == null)
                {
                    Site.Assume.Inconclusive("Cannot verify the output since base image is not find, check the existance and format of BaseImage element in test data file.");
                }
                this.bcgrAdapter.SimulatedScreen.RenderUncompressedImage(sId, baseImage, bmRect.left, bmRect.top);
            }

            return fid;
        }
        /// <summary>
        /// Method to copy bitmap of a rectangle in surface to other position
        /// </summary>
        /// <param name="surf">The source surface where the rectangle to be copied.</param>
        /// <param name="srcRect">The rectangle to be copied.</param>
        /// <param name="destPos">The position array that rectangle is copied to.</param>
        /// <returns> Frame Id </returns>
        public uint IntraSurfaceCopy(Surface surf, RDPGFX_RECT16 srcRect, RDPGFX_POINT16[] destPos)
        {
            uint fid = MakeStartFramePdu();
            MakeSurfaceToSurfacePdu(surf.Id, surf.Id, srcRect, destPos);
            MakeEndFramePdu(fid);

            PackAndSendServerPdu();

            return fid;
        }
        /// <summary>
        /// Method to implement SurfaceToCache functionality
        /// </summary>
        /// <param name="surf">The surface to be filled.</param>
        /// <param name="cacheRect">The rectangle to be cached on the surface.</param>
        /// <param name="cacheKey">The cacheKey of rectangle bitmap data on client.</param>
        /// <param name="cacheSlot">Specify a cacheslot</param>
        /// <param name="fillColor">The color that rectangle to be filled.</param>
        public uint CacheSurface(Surface surf, RDPGFX_RECT16 cacheRect, ulong cacheKey, ushort? cacheSlot, RDPGFX_COLOR32? fillColor = null)
        {
            uint fid = MakeStartFramePdu();

            if (fillColor != null)
            {
                // Send solid fill request to client to fill cacheRect of surface with color.
                RDPGFX_RECT16[] rects = { cacheRect };
                MakeSolidFillPdu(surf.Id, fillColor.Value, rects);
            }

            if (cacheSlot == null)
            {
                cacheSlot = 1;
            }

            if (currentTestType == RdpegfxNegativeTypes.CacheManagement_Default_ExceedMaxCacheSlot)
            {
                // 25600 is the max cache slots number for default cache size.
                for (ushort index = 1; index <= 25601; ++index)
                {
                    cacheSlot = index;
                    MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
                    if (index % 100 == 0)
                        PackAndSendServerPdu();
                }
            }
            else if (currentTestType == RdpegfxNegativeTypes.CacheManagement_SmallCache_ExceedMaxCacheSlot)
            {
                // 12800 is the max cache slots number for small cache size.
                for (ushort index = 1; index <= 12801; ++index)
                {
                    cacheSlot = index;
                    MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
                    if (index % 100 == 0)
                        PackAndSendServerPdu();
                }
            }
            else if (currentTestType == RdpegfxNegativeTypes.CacheManagement_ThinCient_ExceedMaxCacheslot)
            {
                // 4096 is the max cache slots number for thin client cache size.
                for (ushort index = 1; index <= 4097; ++index)
                {
                    cacheSlot = index;
                    MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
                    if (index % 100 == 0)
                        PackAndSendServerPdu();
                }
            }
            else if (currentTestType == RdpegfxNegativeTypes.CacheManagement_Default_ExceedMaxCacheSize)
            {
                // Every cache slot has the size of 1MB here,
                // 100MB is the max cache size for default flag, cache 101 MB here which exceeds max cache size.
                for (ushort index = 1; index <= 101; ++index)
                {
                    cacheSlot = index;
                    MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
                }
            }
            else if (currentTestType == RdpegfxNegativeTypes.CacheManagement_SmallCache_ExceedMaxCacheSize)
            {
                // Every cache slot has the size of 1MB here,
                // 50MB is the max cache size for SmallCache flag, cache 51 MB here which exceeds max cache size.
                for (ushort index = 1; index <= 51; ++index)
                {
                    cacheSlot = index;
                    MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
                }
            }
            else if (currentTestType == RdpegfxNegativeTypes.CacheManagement_ThinClient_ExceedMaxCacheSize)
            {
                // Every cache slot has the size of 1MB here,
                // 16MB is the max cache size for SmallCache flag, cache 17 MB here which exceeds max cache size.
                for (ushort index = 1; index <= 17; ++index)
                {
                    cacheSlot = index;
                    MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
                }
            }
            else
            {
                MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);
            }

            if (currentTestType == RdpegfxNegativeTypes.CacheManagement_Delete_InexistentCacheSlot)
            {
                // Delete an inexistent cache slot.
                MakeEvictCacheEntryPdu(0xfefe);    // 0xfefe is an inexistent cache slot.
            }

            MakeEndFramePdu(fid);
            PackAndSendServerPdu();
            return fid;
        }
 /// <summary>
 /// Method to make a wire to surface Pdu1 
 /// </summary>
 /// <param name="sId">This is used to indicate the target surface id.</param>
 /// <param name="cId">This is used to indicate the codecId.</param>
 /// <param name="pixFormat">This is used to indicate the pixel format to fill target surface.</param>
 /// <param name="bmRect">This is used to indicate border of bitmap on target surface.</param>
 /// <param name="bmLen">This is used to indicate the length of bitmap data.</param>
 /// <param name="bmData">This is used to indicate the bitmap data encoded by cId codec.</param>
 void MakeWireToSurfacePdu1(ushort sId, CodecType cId, PixelFormat pixFormat, RDPGFX_RECT16 bmRect, byte[] bmData)
 {
     RDPGFX_WIRE_TO_SURFACE_PDU_1 wireToSurf1 = egfxServer.CreateWireToSurfacePdu1(sId, cId, pixFormat, bmRect, bmData);
     AddPdusToBuffer(wireToSurf1);
 }
        /// <summary>
        /// Method to implement SurfaceToCache and CacheToSurface functionality.
        /// </summary>
        /// <param name="surf">The surface to be filled.</param>
        /// <param name="cacheRect">The rectangle to be cached on the surface.</param>
        /// <param name="cacheKey">The cacheKey of rectangle bitmap data on client.</param>
        /// <param name="destPoints">This is used to specify destination points of source rectangle bitmap to be copied </param>
        /// <param name="cacheSlot">Specify a cacheslot</param>
        /// <param name="fillColor">The color that rectangle to be filled.</param>
        /// <returns> Frame Id </returns>
        public uint FillSurfaceByCachedBitmap(Surface surf, RDPGFX_RECT16 cacheRect, ulong cacheKey, RDPGFX_POINT16[] destPoints, ushort? cacheSlot, RDPGFX_COLOR32? fillColor = null)
        {
            uint fid = MakeStartFramePdu();

            if (fillColor != null)
            {
                // Send solid fill request to client to fill cacheRect of surface with color
                RDPGFX_RECT16[] rects = { cacheRect };
                MakeSolidFillPdu(surf.Id, fillColor.Value, rects);
            }

            // Copy a rectangle bitmap data to cache and move it from cache to other positions of surface.
            if (cacheSlot == null)
            {
                cacheSlot = 1;  //set slot# to 1
            }
            MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);

            if (currentTestType == RdpegfxNegativeTypes.CacheManagement_CacheToSurface_InexistentCacheSlot)
            {
                cacheSlot = (ushort)(cacheSlot.Value + 1);
            }
            ushort sid = surf.Id;
            if (currentTestType == RdpegfxNegativeTypes.CacheManagement_CacheToSurface_InexistentSurface)
            {
                sid++;
            }
            MakeCacheToSurfacePdu(cacheSlot.Value, sid, destPoints);

            MakeEndFramePdu(fid);

            PackAndSendServerPdu();
            return fid;
        }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_CreateSurface_MaxWidth()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            this.TestSite.Log.Add(LogEntryKind.Comment, "Reset virtual desktop size, width is {0}, height is {1}.", RdpegfxTestUtility.MaxBmpWidth, RdpegfxTestUtility.desktopHeight);
            // Reset graphics of virtual desktop
            fid = this.rdpegfxAdapter.ResetGraphics(RdpegfxTestUtility.MaxBmpWidth, RdpegfxTestUtility.desktopHeight);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with green color, surface width is {0}, height is {1}.", RdpegfxTestUtility.MaxBmpWidth, RdpegfxTestUtility.desktopHeight);
            // Create & output a surface
            RDPGFX_RECT16 surfRect = new RDPGFX_RECT16(0, 0, RdpegfxTestUtility.MaxBmpWidth, (ushort)RdpegfxTestUtility.desktopHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface with max ID: {0} is created", surf.Id);

            // Send solid fill request to client to fill surface with green color
            RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(0, 0, RdpegfxTestUtility.MaxBmpWidth, (ushort)RdpegfxTestUtility.desktopHeight);
            RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, fillRects);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);

            // Expect the client to send a frame acknowledge pdu
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            // Don't verify the output since the output window is too large 32766*32766
            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_FillOverlappedSurface()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface.");
            // Create & output a surface
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create another surface which overlap partial area of the first surface.");
            // Create & output a surface
            RDPGFX_RECT16 surfRect2 = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos4, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf2 = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect2, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf2, "Surface {0} is created", surf2.Id);

            // Send solid fill request to client to fill surface with green color
            this.TestSite.Log.Add(LogEntryKind.Comment, "Fill the first surface with solid green color.");
            RDPGFX_RECT16 fillSurfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.imgPos, (ushort)(RdpegfxTestUtility.surfWidth), RdpegfxTestUtility.surfHeight);
            RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, fillRects);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);

            // Expect the client to send a frame acknowledge pdu
            // If the server receives the message, it indicates that the client has been successfully decoded the logical frame of graphics commands
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            RDPGFX_RECT16 verifyRect = new RDPGFX_RECT16(surfRect.left, surfRect.top, surfRect2.right, surfRect2.bottom);
            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Constructor, create a wire to surface message to transfer a bitmap.
        /// </summary>
        /// <param name="sId">This is used to indicate the target surface id.</param>
        /// <param name="cId">This is used to indicate the codecId.</param>
        /// <param name="pixFormat">This is used to indicate the pixel format to fill target surface.</param>
        /// <param name="bmRect">This is used to indicate border of bitmap on target surface.</param>
        /// <param name="bmLen">This is used to indicate the length of bitmap data.</param>
        /// <param name="bmData">This is used to indicate the bitmap data encoded by cId codec.</param>
        public RDPGFX_WIRE_TO_SURFACE_PDU_1(ushort sId, CodecType cId, PixelFormat pixFormat, RDPGFX_RECT16 bmRect, byte[] bmData)
        {
            this.Header.cmdId = PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_1;
            this.Header.flags = 0x0;
            this.Header.pduLength = (uint)Marshal.SizeOf(Header);

            this.surfaceId = sId;
            this.codecId = cId;
            this.pixelFormat = pixFormat;
            this.destRect = bmRect;
            this.Header.pduLength += 13;

            this.bitmapData = bmData;
            if (bmData != null)
            {
                this.bitmapDataLength = (uint)bmData.Length;
                this.Header.pduLength += this.bitmapDataLength;   // add length of bitmapData
            }
            this.Header.pduLength += 4;  // 4 bytes for bitmapDataLength field.
        }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_CreateSurface_FullWindow()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            ushort desktopWidth = this.rdpbcgrAdapter.SessionContext.DesktopWidth;
            ushort desktopHeight = this.rdpbcgrAdapter.SessionContext.DesktopHeight;
            if (desktopWidth == 0 || desktopHeight == 0)
            {
                this.Site.Assume.Fail("Cannot get Desktop width or height from TS_UD_CS_CORE structure in connection establish phase.");
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with green color.");
            // Create & output a surface
            RDPGFX_RECT16 surfRect = new RDPGFX_RECT16(0, 0, desktopWidth, desktopHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface with max ID: {0} is created", surf.Id);

            // Send solid fill request to client to fill surface with green color
            RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(0, 0, desktopWidth, desktopHeight);
            RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, fillRects);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);

            // Expect the client to send a frame acknowledge pdu
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Constructor, create a surface to surface message, with only 1 destination copy position.
        /// </summary>
        /// <param name="srcSID">This is used to indicate source surface id.</param>
        /// <param name="destSID">This is used to indicate destination surface id.</param>
        /// <param name="srcRect">This is used to indicate source rectangle bitmap area to be copied.</param>
        public RDPGFX_SURFACE_TO_SURFACE(ushort srcSID, ushort destSID, RDPGFX_RECT16 srcRect)
        {
            this.Header.cmdId = PacketTypeValues.RDPGFX_CMDID_SURFACETOSURFACE;
            this.Header.flags = 0x0;
            this.Header.pduLength = (uint)Marshal.SizeOf(Header) + 14;

            this.surfaceIdSrc = srcSID;
            this.surfaceIdDest = destSID;
            this.rectSrc = srcRect;
            this.destPtsCount = 0;
            this.destPtsList =  new List<RDPGFX_POINT16>();
            this.destPtsList.Clear();
        }
        /// <summary>
        /// Constructor, create a surface to cache message.
        /// </summary>
        /// <param name="sid">This is used to indicate surface id.</param>
        /// <param name="key">This is used to indicate a key to associate with the bitmap cache entry.</param>
        /// <param name="slot">This is used to indicate the index of the bitmap cache entry in which 
        /// the source bitmap data is stored.</param>
        /// <param name="rect">This is used to indicate rectangle that bounds the source bitmap.</param>
        public RDPGFX_SURFACE_TO_CACHE(ushort sid, ulong key, ushort slot, RDPGFX_RECT16 rect)
        {
            this.Header.cmdId = PacketTypeValues.RDPGFX_CMDID_SURFACETOCACHE;
            this.Header.flags = 0x0;
            this.Header.pduLength = 28;  // header 8 bytes, body: 20 bytes

            this.surfaceId = sid;
            this.cacheKey = key;
            this.cacheSlot = slot;
            this.rectSrc = rect;
        }
 /// <summary>
 /// Add more rectangle to be filled in destination surface.
 /// </summary>
 /// <param name="rect">This is to specify a rectangle area of surface.</param>
 public void addFillRect(RDPGFX_RECT16 rect)
 {
     this.fillRectList.Add(rect);
     this.fillRectCount++;
     this.Header.pduLength += (uint)Marshal.SizeOf(rect);
 }
        /// <summary>
        /// Method to make a surface to cache Pdu
        /// </summary>
        /// <param name="sid">This is used to indicate surface id.</param>
        /// <param name="key">This is used to indicate a key to associate with the bitmap cache entry.</param>
        /// <param name="slot">This is used to indicate the index of the bitmap cache entry in which 
        /// the source bitmap data is stored.</param>
        /// <param name="rect">This is used to indicate rectangle that bounds the source bitmap.</param>
        void MakeSurfaceToCachePdu(ushort sid, ulong key, ushort slot, RDPGFX_RECT16 rect)
        {
            RDPGFX_SURFACE_TO_CACHE surfaceToCache = egfxServer.CreateSurfaceToCachePdu(sid, key, slot, rect);
            AddPdusToBuffer(surfaceToCache);

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.SurfaceToCache(sid, key, slot, rect);
            }
        }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_MapSurface_SurfaceBorderOverlapWindow()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            ushort desktopWidth = this.rdpbcgrAdapter.SessionContext.DesktopWidth;
            ushort desktopHeight = this.rdpbcgrAdapter.SessionContext.DesktopHeight;
            if (desktopWidth <= RdpegfxTestUtility.surfWidth || desktopHeight <= RdpegfxTestUtility.surfHeight)
            {
                this.Site.Assume.Fail("The Desktop width or height are not applicable for this test case, desktop width must larger than {0}, and desktop height must larger than {1}.", RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with green color.");
            // Create & output a surface
            RDPGFX_RECT16 surfRect = new RDPGFX_RECT16(
                (ushort)(desktopWidth - RdpegfxTestUtility.surfWidth),
                (ushort)(desktopHeight - RdpegfxTestUtility.surfHeight),
                desktopWidth,
                desktopHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface with max ID: {0} is created", surf.Id);

            // Send solid fill request to client to fill surface with green color
            RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(0, 0, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, fillRects);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);

            // Expect the client to send a frame acknowledge pdu
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Method to make a surface to surface Pdu.
        /// </summary>
        /// <param name="srcSID">This is used to indicate source surface id.</param>
        /// <param name="destSID">This is used to indicate destination surface id.</param>
        /// <param name="srcRect">This is used to indicate source rectangle bitmap area to be copied.</param>
        /// <param name="destPoints">This is used to specify destination points of source rectangle bitmap to be copied </param>
        void MakeSurfaceToSurfacePdu(ushort srcSID, ushort destSID, RDPGFX_RECT16 srcRect, RDPGFX_POINT16[] destPoints)
        {
            RDPGFX_SURFACE_TO_SURFACE surfToSurf = egfxServer.CreateSurfaceToSurfacePdu(srcSID, destSID, srcRect, destPoints);
            // Change pdu based testtype
            if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_InexistentSrc)
            {
                surfToSurf.surfaceIdSrc = 0xffff; // 0xffff is an inexistent surface id.
            }
            else if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_InexistentDest)
            {
                surfToSurf.surfaceIdDest = 0xffff; // 0xffff is an inexistent surface id.
            }
            else if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_DestPtsCount_Mismatch)
            {
                surfToSurf.destPtsCount += 1; // Make the value of destPts and the length of destPts mismatch.
            }

            AddPdusToBuffer(surfToSurf);

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.SurfaceToSurface(srcSID, destSID, srcRect, destPoints);
            }
        }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_SolidFill_ManyFillRects()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with green color.");
            // Create & output a surface
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            // Generate many fillRects on the surface
            List<RDPGFX_RECT16> rectList = new List<RDPGFX_RECT16>();
            for (ushort y = 0; y < RdpegfxTestUtility.surfHeight; y+= 2)
            {
                for (ushort x = 0; x < RdpegfxTestUtility.surfWidth; x += 2)
                {
                    RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(x, y, (ushort)(x + 1),(ushort)(y + 1));
                    rectList.Add(fillSurfRect);
                }
            }

            // Send solid fill request to client to fill surface with green color
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, rectList.ToArray());
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}, {1} fillrects in total.", fid, rectList.Count);

            // Expect the client to send a frame acknowledge pdu
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Method to instruct client to create a surface, and output it to client screen.
        /// </summary>
        /// <param name="rect"> surface rectangle </param>
        /// <param name="pixFormat"> pixel Format to fill surface </param>
        /// <param name="surfaceId">Specify a Surface ID</param>
        /// <returns> The created surface </returns>
        public Surface CreateAndOutputSurface(RDPGFX_RECT16 rect, PixelFormat pixFormat, ushort? surfaceId = null)
        {
            ushort w = (ushort)(rect.right - rect.left);
            ushort h = (ushort)(rect.bottom - rect.top);

            // Create a surface and output it to screen
            Surface surface = surfManager.CreateSurface(w, h, surfaceId);
            if (null == surface)
            {
                Site.Log.Add(LogEntryKind.Warning, "Attempt to create too much(>255) surfaces!");
                return null;
            }

            MakeCreateSurfacePdu(surface.Id, w, h, pixFormat);
            MakeMapSurfaceToOutputPdu(surface.Id, rect.left, rect.top);

            PackAndSendServerPdu();

            return surface;
        }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_SolidFill_MultiFillRectsOverlapped()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with green color.");
            // Create & output a surface
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            // Generate fillrects in the corner
            List<RDPGFX_RECT16> rectList = new List<RDPGFX_RECT16>();
            // First Rect
            RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(
                0,
                0,
                RdpegfxTestUtility.smallWidth,
                RdpegfxTestUtility.smallHeight);
            rectList.Add(fillSurfRect);
            // Second Rect, overlap partial area of the first rect
            fillSurfRect = new RDPGFX_RECT16(
                (ushort)(RdpegfxTestUtility.smallWidth/2),
                (ushort)(RdpegfxTestUtility.smallHeight/2),
                (ushort)(RdpegfxTestUtility.smallWidth / 2 + RdpegfxTestUtility.smallWidth),
                (ushort)(RdpegfxTestUtility.smallHeight / 2 + RdpegfxTestUtility.smallHeight));
            rectList.Add(fillSurfRect);

            // Send solid fill request to client to fill surface with green color
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, rectList.ToArray());
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);

            // Expect the client to send a frame acknowledge pdu
            // If the server receives the message, it indicates that the client has been successfully decoded the logical frame of graphics commands
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Method to copy bitmap of a rectangle in a surface to other position in another surface
        /// </summary>
        /// <param name="surf">The source surface where the rectangle to be copied.</param>
        /// <param name="srcRect">The rectangle to be copied.</param>
        /// <param name="fillColor">The color of rectangle to be filled.</param>
        /// <param name="surfDest">The destination surface where the rectangle is copied to.</param>
        /// <param name="destPos">The position array that rectangle is copied to.</param>
        /// <returns> Frame Id </returns>
        public uint InterSurfaceCopy(Surface surfSrc, RDPGFX_RECT16 srcRect, RDPGFX_COLOR32 fillColor, Surface surfDest, RDPGFX_POINT16[] destPos)
        {
            uint fid = MakeStartFramePdu();
            RDPGFX_RECT16[] rects = { srcRect };
            MakeSolidFillPdu(surfSrc.Id, fillColor, rects);
            MakeSurfaceToSurfacePdu(surfSrc.Id, surfDest.Id, srcRect, destPos);
            if (currentTestType != RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_DestPtsCount_Mismatch)
            {
                MakeEndFramePdu(fid);
            }

            PackAndSendServerPdu();

            return fid;
        }
 /// <summary>
 /// Method to send client a display configuration change notification by sending surface management commands to restart graphics pipeline 
 /// </summary>
 /// <param name="width">Width of screen</param>
 /// <param name="height">Height of Screen</param>
 public void restartGraphicsPipeline(ushort width, ushort height)
 {
     // create RDPGFX_RESET_GRAPHICS_PDU with only one monitor
     this.rdpegfxAdapter.ResetGraphics(width, height);
     // Create & output a surface
     RDPGFX_RECT16 surfRect = new RDPGFX_RECT16(0, 0, width, height);
     Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
     // Send solid fill request to client to fill surface with green color
     RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(0, 0, width, height);
     RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
     uint fid = this.rdpegfxAdapter.SolidFillSurface(surf, new RDPGFX_COLOR32(Color.Green.R, Color.Green.G, Color.Green.B, Color.Green.A), fillRects);
     // Expect the client to send a frame acknowledge pdu
     // If the server receives the message, it indicates that the client has been successfully decoded the logical frame of graphics commands
     this.rdpegfxAdapter.ExpectFrameAck(fid);
     // Delete the surface
     this.rdpegfxAdapter.DeleteSurface(surf.Id);
 }
        /// <summary>
        /// Encode a bitmap data by RemoteFX codec.
        /// </summary>
        /// <param name="image"> The bitmap image to be sent </param>
        /// <param name="opMode"> Indicate Operational Mode.</param>
        /// <param name="entropy"> Indicate Entropy Algorithm.</param>
        /// <param name="imgPos"> The top-left position of bitmap image relative to surface</param>
        /// <param name="sId"> The surface Id that bitmap image is sent to </param>
        /// <returns> A dictionary with frameId and byte stream frame pair </returns>
        public Dictionary<uint, byte[]> RemoteFXCodecEncode(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy,
            RDPGFX_POINT16 imgPos, ushort sId, PixelFormat pixFormat)
        {
            if (image == null) return null;

            Dictionary<uint, byte[]> frDict = new Dictionary<uint, byte[]>();   // Save encoded frames for one tile

            TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize);

            for (uint index = 0; index < tileImageArr.Length; index++)
            {
                byte[] tileBitmap = this.PackRfxTileImage(index, opMode, entropy, tileImageArr[index].image);
                ushort tileLeft = (ushort)(imgPos.x + tileImageArr[index].x);
                ushort tileTop = (ushort)(imgPos.y + tileImageArr[index].y);
                RDPGFX_RECT16 tileRect = new RDPGFX_RECT16(tileLeft, tileTop,
                                                            (ushort)(tileLeft + tileImageArr[index].image.Width),
                                                            (ushort)(tileTop + tileImageArr[index].image.Height));

                uint fid = MakeStartFramePdu();
                MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_CAVIDEO, pixFormat, tileRect, tileBitmap);
                MakeEndFramePdu(fid);

                if (this.bcgrAdapter.SimulatedScreen != null)
                {
                    this.bcgrAdapter.SimulatedScreen.RenderRemoteFXTile(sId, tileRect);
                }

                frDict.Add(fid, EncodePdusToSent());
            }

            return frDict;
        }
        /// <summary>
        /// Send a uncompressed bitmap data, the data segment(s) can be compressed or uncompressed according to parameter.
        /// </summary>
        /// <param name="image"> The bitmap image to be sent </param>
        /// <param name="destLeft"> The x-coordination of bitmap image top-left position  </param>
        /// <param name="destTop"> The y-coordination of bitmap image top-left position </param>
        /// <param name="sId"> The surface Id that bitmap image is sent to </param>
        /// <param name="pixFormat"> The pixel format of bitmap image </param>
        /// <param name="compFlag"> The flag indicates whether the bitmap is compressed </param>
        /// <param name="partSize"> The size of pure data in a single RDP8_BULK_ENCODED_DATA structure </param>
        /// <returns> Frame Id </returns>
        public uint SendUncompressedImage(System.Drawing.Image image, ushort destLeft, ushort destTop,
            ushort sId, PixelFormat pixFormat, byte compFlag, uint partSize)
        {
            if (image == null)
            {
                Site.Log.Add(LogEntryKind.Debug, "[In iRdprfxAdapter.SendImageToClient Method] The image to be send is null.");
                return 0;
            }

            uint fid = MakeStartFramePdu();

            RDPGFX_RECT16 imageRect = new RDPGFX_RECT16(destLeft, destTop,
                                                            (ushort)(destLeft + image.Width),
                                                            (ushort)(destTop + image.Height));
            byte[] imageData = ImageToByteArray(image);

            MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_UNCOMPRESSED, pixFormat, imageRect, imageData);

            MakeEndFramePdu(fid);

            this.segPdu.compressFlag = compFlag;
            this.segPdu.SetSegmentPartSize(partSize);
            PackAndSendServerPdu();

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.RenderUncompressedImage(sId, image, destLeft, destTop);
            }

            return fid;
        }
        /// <summary>
        /// Send clearcodec encoded glyph in batch (make sure glyphnum + startGlyphRect.right is not bigger than surf.width)
        /// </summary>
        /// <param name="surf">This is used to indicate the target surface id.</param>
        /// <param name="startGlyphIdx">This is used to indicate the start index of graph batch to be put in client graph cache.</param>
        /// <param name="startGlyphPos">The start position of glyph batch, which will be sent in clearcodec, relative to the surface. </param>
        /// <param name="glyphNum"> The glyph number in batch. </param>
        /// <param name="glyph"> The residual layer image to be sent. </param>
        /// <returns> Frame Id </returns>
        public uint SendClearCodecGlyphInBatch(Surface surf, ushort startGlyphIdx, RDPGFX_POINT16 startGlyphPos, ushort glyphNum, Image glyph)
        {
            uint fid = MakeStartFramePdu();

            ushort glyphIdx = startGlyphIdx;
            RDPGFX_RECT16 glyphRect = new RDPGFX_RECT16(startGlyphPos.x, startGlyphPos.y,
                                            (ushort)(startGlyphPos.x + glyph.Width),
                                            (ushort)(startGlyphPos.y + glyph.Height));

            // Pack multiple w2s_1 PDU into a frame.
            for (ushort i = 0; i < glyphNum; i++)
            {
                ClearCodec_BitmapStream ccStream = new ClearCodec_BitmapStream(ClearCodec_BitmapStream.CLEARCODEC_FLAG_GLYPH_INDEX, glyphIdx);
                ccStream.LoadResidualBitmap((Bitmap)glyph);
                ccStream.seqNumber = egfxServer.Get_ClearCodecBitmapStream_SeqNum();
                MakeWireToSurfacePdu1(surf.Id, CodecType.RDPGFX_CODECID_CLEARCODEC, PixelFormat.PIXEL_FORMAT_XRGB_8888,
                                        glyphRect, ccStream.Encode());
                glyphIdx++;
                glyphRect.left++;
                glyphRect.right++;
            }

            MakeEndFramePdu(fid);

            PackAndSendServerPdu();

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.RenderClearCodecBatch(surf.Id, startGlyphIdx, startGlyphPos, glyphNum, glyph);
            }

            return fid;
        }
        /// <summary>
        /// Method to solidfill a surface with color
        /// </summary>
        /// <param name="surf">The surface to be filled.</param>
        /// <param name="color">The color to fill the surface.</param>
        /// <param name="rects">The rectangles to be filled in the surface.</param>
        /// <param name="frameId">Specify the frame Id.</param>
        /// <returns> Frame Id </returns>
        public uint SolidFillSurface(Surface surf, RDPGFX_COLOR32 color, RDPGFX_RECT16[] rects, uint? frameId = null)
        {
            uint fid = MakeStartFramePdu(frameId);
            MakeSolidFillPdu(surf.Id, color, rects);
            MakeEndFramePdu(fid);

            PackAndSendServerPdu();
            return fid;
        }
        /// <summary>
        /// Send bitmap data in H264 AVC444 codec
        /// </summary>
        /// <param name="sId">This is used to indicate the target surface id</param>
        /// <param name="pixFormat">This is used to indicate the pixel format to fill target surface.</param>
        /// <param name="bmRect">The rectangle of whole Image</param>
        /// <param name="lcValue">Code specifies how data is encoded in the avc420EncodedBitstream1 and avc420EncodedBitstream2 fields</param>
        /// <param name="stream1NumRects">Number of rects of avc420EncodedBitstream1</param>
        /// <param name="steam1RegionRects">Rect list of avc420EncodedBitstream1</param>
        /// <param name="stream1QuantQualityVals">Quality list of avc420EncodedBitstream1</param>
        /// <param name="avc420EncodedBitstream1">encoded H264 AVC420 data stream of avc420EncodedBitstream1</param>
        /// <param name="stream2NumRects">Number of rects of avc420EncodedBitstream2</param>
        /// <param name="steam2RegionRects">Rect list of avc420EncodedBitstream2</param>
        /// <param name="stream2QuantQualityVals">Quality list of avc420EncodedBitstream2</param>
        /// <param name="avc420EncodedBitstream2">encoded H264 AVC420 data stream of avc420EncodedBitstream2</param>
        /// <param name="baseImage">Base Image used to verify output</param>
        /// <returns></returns>
        public uint SendImageWithH264AVC444Codec(ushort sId, PixelFormat pixFormat, RDPGFX_RECT16 bmRect, AVC444LCValue lcValue,
            uint stream1NumRects, RDPGFX_RECT16[] steam1RegionRects, RDPGFX_AVC420_QUANT_QUALITY[] stream1QuantQualityVals, byte[] avc420EncodedBitstream1,
            uint stream2NumRects, RDPGFX_RECT16[] steam2RegionRects, RDPGFX_AVC420_QUANT_QUALITY[] stream2QuantQualityVals, byte[] avc420EncodedBitstream2,
            Image baseImage)
        {
            uint fid = MakeStartFramePdu();
            RFX_AVC420_METABLOCK avc420MetaData = new RFX_AVC420_METABLOCK();
            avc420MetaData.numRegionRects = stream1NumRects;
            avc420MetaData.regionRects = steam1RegionRects;
            avc420MetaData.quantQualityVals = stream1QuantQualityVals;
            RFX_AVC420_BITMAP_STREAM avc420Stream1 = new RFX_AVC420_BITMAP_STREAM(avc420MetaData, avc420EncodedBitstream1);

            RFX_AVC420_BITMAP_STREAM avc420Stream2 = null;
            if (stream2NumRects != 0 && avc420EncodedBitstream2 != null)
            {
                avc420MetaData = new RFX_AVC420_METABLOCK();
                avc420MetaData.numRegionRects = stream2NumRects;
                avc420MetaData.regionRects = steam2RegionRects;
                avc420MetaData.quantQualityVals = stream2QuantQualityVals;
                avc420Stream2 = new RFX_AVC420_BITMAP_STREAM(avc420MetaData, avc420EncodedBitstream2);
            }

            RFX_AVC444_BITMAP_STREAM avc444Stream = new RFX_AVC444_BITMAP_STREAM(lcValue, avc420Stream1, avc420Stream2);
            MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_AVC444, pixFormat, bmRect, avc444Stream.Encode());
            MakeEndFramePdu(fid);

            PackAndSendServerPdu();

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                if (baseImage == null)
                {
                    Site.Assume.Inconclusive("Cannot verify the output since base image is not find, check the existance and format of BaseImage element in test data file.");
                }
                this.bcgrAdapter.SimulatedScreen.RenderUncompressedImage(sId, baseImage, bmRect.left, bmRect.top);
            }

            return fid;
        }
        /// <summary>
        /// Method to make a solid fill Pdu
        /// </summary>
        /// <param name="sid">This is used to indicate surface id to be filled.</param>
        /// <param name="pixel">This is used to indicate color to fill.</param>
        /// <param name="rects">This is to specify rectangle areas in surface </param>
        void MakeSolidFillPdu(ushort sid, RDPGFX_COLOR32 color, RDPGFX_RECT16[] rects)
        {
            RDPGFX_SOLIDFILL solidFill = egfxServer.CreateSolidFillPdu(sid, color, rects);
            // Change pdu based testtype.
            if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_SolidFill_ToInexistentSurface)
                solidFill.surfaceId = 0xffff;   // Set the surface id to an inexsit surface's id 0xffff

            AddPdusToBuffer(solidFill);

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.SolidFill(sid, color, rects);
            }
        }
        /// <summary>
        /// Method to send nested frames
        /// </summary>
        /// <param name="surf">The surface that the frames belong to</param>
        /// <param name="colors">The color to fill the surface</param>
        /// <param name="rects">The rectangles to be filled in the surface</param>
        public void SendNestedFrames(Surface surf, RDPGFX_COLOR32[] colors, RDPGFX_RECT16[] rects)
        {
            uint fid1 = MakeStartFramePdu();
            uint fid2 = MakeStartFramePdu();
            MakeSolidFillPdu(surf.Id, colors[0], new RDPGFX_RECT16[] { rects[0] });
            MakeSolidFillPdu(surf.Id, colors[1], new RDPGFX_RECT16[] { rects[1] });
            MakeEndFramePdu(fid2);
            MakeEndFramePdu(fid1);

            PackAndSendServerPdu();
            //ExpectFrameAck(fid2);
            //ExpectFrameAck(fid1);
        }
            /// <summary>
            /// Draw part of an image on the surface.
            /// Also will update the corresponding mapped screen position.
            /// </summary>
            /// <param name="srcImage"></param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            public void DrawImage(Image srcImage, ushort x, ushort y, RDPGFX_RECT16 srcRect)
            {
                Rectangle rect = new Rectangle(srcRect.left, srcRect.top, srcRect.right - srcRect.left, srcRect.bottom - srcRect.top);
                imageGraphic.DrawImage(srcImage, x, y, rect, GraphicsUnit.Pixel);

                if (mapPoints.Count > 0)
                {
                    Graphics baseImageGraphics = Graphics.FromImage(screen.BaseImage);
                    foreach (Point p in mapPoints)
                    {
                        baseImageGraphics.DrawImage(srcImage, p.X + x, p.Y + y, rect, GraphicsUnit.Pixel);
                    }
                    baseImageGraphics.Dispose();
                }
            }