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(); } }