diff --git a/reactos/drivers/dd/vga/display/main/enable.c b/reactos/drivers/dd/vga/display/main/enable.c index 4fe8cb71d1e..e701836caa5 100644 --- a/reactos/drivers/dd/vga/display/main/enable.c +++ b/reactos/drivers/dd/vga/display/main/enable.c @@ -1,9 +1,9 @@ /* * entry.c * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * $Author: jfilby $ - * $Date: 2000/04/03 19:55:32 $ + * $Date: 2000/04/10 20:17:32 $ * */ @@ -44,6 +44,9 @@ BOOL VGADDIBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint, BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4); +BOOL VGADDICopyBits(SURFOBJ *Dest, SURFOBJ *Source, + CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, + PRECTL DestRect, PPOINTL SourcePoint); DRVFN FuncList[] = { @@ -58,11 +61,11 @@ DRVFN FuncList[] = {INDEX_DrvLineTo, (PFN) VGADDILineTo}, {INDEX_DrvPaint, (PFN) VGADDIPaint}, {INDEX_DrvBitBlt, (PFN) VGADDIBitBlt}, +// {INDEX_DrvCopyBits, (PFN) VGADDICopyBits}, #if 0 /* Optional Display driver functions */ {INDEX_, (PFN) }, - {INDEX_DrvCopyBits, (PFN) VGADDICopyBits}, {INDEX_DescribePixelFormat, (PFN) VGADDIDescribePixelFormat}, {INDEX_DrvDitherColor, (PFN) VGADDIDitherColor}, {INDEX_DrvFillPath, (PFN) VGADDIFillPath}, @@ -340,8 +343,6 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev) DHSURF dhsurf; HSURF hsurf; - DbgPrint("DrvEnableSurface..\n"); - // Initialize the VGA if (!InitVGA(ppdev, TRUE)) { @@ -379,8 +380,6 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev) goto error_clean; } BANKING CODE UNIMPLEMENTED */ - DbgPrint("Calling EngCreateDeviceSurface..\n"); - if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizeSurf, BMF_4BPP)) == (HSURF)0) { @@ -388,11 +387,10 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev) EngDebugPrint("VGADDI:", "EngCreateDeviceSurface call failed\n", 0); goto error_clean; } -DbgPrint("init saved bits.. "); - InitSavedBits(ppdev); -DbgPrint("successful\n"); - if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO)) + InitSavedBits(ppdev); + + if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO | HOOK_COPYBITS)) { EngDebugPrint("VGADDI:", "Successfully associated surface\n", 0); ppdev->SurfHandle = hsurf; diff --git a/reactos/drivers/dd/vga/display/makefile b/reactos/drivers/dd/vga/display/makefile index a3cd0cf0b2d..bb7db246e36 100644 --- a/reactos/drivers/dd/vga/display/makefile +++ b/reactos/drivers/dd/vga/display/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.4 2000/04/03 19:55:32 jfilby Exp $ +# $Id: makefile,v 1.5 2000/04/10 20:17:32 jfilby Exp $ # # Makefile for ReactOS vgaddi.dll # @@ -19,7 +19,7 @@ endif all: $(DLLTARGET) MAIN_OBJECTS = main/enable.o -OTHER_OBJECTS = objects/screen.o objects/lineto.o objects/paint.o objects/bitblt.o vgavideo/vgavideo.o +OTHER_OBJECTS = objects/screen.o objects/lineto.o objects/paint.o objects/bitblt.o objects/copybits.o vgavideo/vgavideo.o RESOURCE_OBJECTS = $(TARGET).coff OBJECTS = $(MAIN_OBJECTS) $(OTHER_OBJECTS) $(RESOURCE_OBJECTS) diff --git a/reactos/drivers/dd/vga/display/objects/bitblt.c b/reactos/drivers/dd/vga/display/objects/bitblt.c index 2de44fa7607..3df191b8c92 100644 --- a/reactos/drivers/dd/vga/display/objects/bitblt.c +++ b/reactos/drivers/dd/vga/display/objects/bitblt.c @@ -15,7 +15,7 @@ BOOL GDItoVGA( SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint) { - ULONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, BPP; + LONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, BPP; BYTE *GDIpos, *initial; BPP = bytesPerPixel(Source->iBitmapFormat); @@ -30,17 +30,16 @@ BOOL GDItoVGA( for(j=SourcePoint->y; jy+dy; j++) { - initial = GDIpos; + initial = GDIpos; - for(i=SourcePoint->x; ix+dx; i++) - { - RtlCopyMemory(&RGBulong, GDIpos, BPP); - idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong); - - vgaPutPixel(i+alterx, j+altery, idxColor); - GDIpos+=BPP; - } - GDIpos = initial + Source->lDelta; + for(i=SourcePoint->x; ix+dx; i++) + { + RtlCopyMemory(&RGBulong, GDIpos, BPP); + idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong); + vgaPutPixel(i+alterx, j+altery, idxColor); + GDIpos+=BPP; + } + GDIpos = initial + Source->lDelta; } } @@ -48,30 +47,46 @@ BOOL VGAtoGDI( SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint) { - ULONG i, j, dx, dy, idxColor, RGBulong, BPP; - BYTE *GDIpos, *initial; + LONG i, j, dx, dy, RGBulong, BPP; + BYTE *GDIpos, *initial, idxColor; + + // FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte) BPP = bytesPerPixel(Dest->iBitmapFormat); GDIpos = Dest->pvBits + - DestRect->top * Dest->lDelta + DestRect->left; + (DestRect->top * Dest->lDelta) + (DestRect->left * BPP); dx = DestRect->right - DestRect->left; dy = DestRect->bottom - DestRect->top; - for(j=SourcePoint->y; jy+dy; j++) + if(ColorTranslation == NULL) { - initial = GDIpos; - - for(i=SourcePoint->x; ix+dx; i++) - { - idxColor = vgaGetPixel(i, j); - - RGBulong = XLATEOBJ_iXlate(ColorTranslation, idxColor); - RtlCopyMemory(GDIpos, &RGBulong, BPP); - - GDIpos+=BPP; - } - GDIpos = initial + Dest->lDelta; + // No color translation necessary, we assume BPP = 1 + for(j=SourcePoint->y; jy+dy; j++) + { + initial = GDIpos; + for(i=SourcePoint->x; ix+dx; i++) + { + idxColor = vgaGetPixel(i, j); + RtlCopyMemory(GDIpos, &idxColor, 1); + GDIpos++; + } + GDIpos = initial + Dest->lDelta; + } + } else { + // Color translation + for(j=SourcePoint->y; jy+dy; j++) + { + initial = GDIpos; + for(i=SourcePoint->x; ix+dx; i++) + { + idxColor = vgaGetPixel(i, j); + RGBulong = XLATEOBJ_iXlate(ColorTranslation, idxColor); + RtlCopyMemory(GDIpos, &RGBulong, BPP); + GDIpos+=BPP; + } + GDIpos = initial + Dest->lDelta; + } } } @@ -200,7 +215,7 @@ BOOL VGADDIBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, { // FIXME: Intersect clip rectangle - BltOperation(Dest, Source, ColorTranslation, Mask, + BltOperation(Dest, Source, Mask, ColorTranslation, DestRect, SourcePoint); } else { diff --git a/reactos/drivers/dd/vga/display/objects/copybits.c b/reactos/drivers/dd/vga/display/objects/copybits.c new file mode 100644 index 00000000000..7577dc912a0 --- /dev/null +++ b/reactos/drivers/dd/vga/display/objects/copybits.c @@ -0,0 +1,859 @@ +#include +#include + +#include "..\vgaddi.h" +#include "..\vgavideo\vgavideo.h" + +// FIXME: There's a lot of redundancy in here -- break into functions +// FIXME: All functions involving the screen use terribly slow vgaPutPixel -- use something better + +VOID Screen2Screen(PDEVSURF PDSurf, RECTL *DestRect, POINTL *SourcePoint, + ULONG iCopyDir) +{ + ULONG i, j, spx, spy; + spy = SourcePoint->y; + + // FIXME: Right now assumes top->down and left->right + + for (j=DestRect->top; jbottom; j++) + { + spx = SourcePoint->x; + for(i=DestRect->left; iright; i++) + { + vgaPutPixel(spx, spy, vgaGetPixel(i, j)); + spx++; + } + spy++; + } +} + +VOID CopyRect4BPP(PDEVSURF DestSurf, PDEVSURF SourceSurf, RECTL *DestRect, + POINTL *SourcePoint) +{ + ULONG i, j, Width, spy; + spy = SourcePoint->y; + Width = DestRect->right - DestRect->left; + + for (j=DestRect->top; jbottom; j++) + { + RtlCopyMemory(DestSurf->StartBmp+DestSurf->NextScan*j+DestRect->left, + SourceSurf->StartBmp+SourceSurf->NextScan*j+SourcePoint->x, + Width); + spy++; + } +} + +VOID DFB2DIB(PDEVSURF DestSurf, PDEVSURF SourceSurf, RECTL *DestRect, + POINTL *SourcePoint) +{ + CopyRect4BPP(DestSurf, SourceSurf, DestRect, SourcePoint); +} + +VOID DFB2DFB(PDEVSURF DestSurf, PDEVSURF SourceSurf, RECTL *DestRect, + POINTL *SourcePoint) +{ + CopyRect4BPP(DestSurf, SourceSurf, DestRect, SourcePoint); +} + +#define DFB_TARGET 0 +#define VGA_TARGET 1 + +VOID DIB2VGA(PDEVSURF DestSurf, PDEVSURF SourceSurf, + RECTL *DestRect, POINTL *SourcePoint, UCHAR *ConversionTables, + BOOL DFBorVGAtarget) +{ + ULONG i, j, spx, spy; + BYTE c; + spy = SourcePoint->y; + + for (j=DestRect->top; jbottom; j++) + { + spx = SourcePoint->x; + for(i=DestRect->left; iright; i++) + { + if(DFBorVGAtarget == DFB_TARGET) + { + c = vgaGetPixel(spx, spy); + RtlCopyMemory(DestSurf->StartBmp+j*DestSurf->NextScan+i, c, 1); + } else + { + RtlCopyMemory(c, SourceSurf->StartBmp+j*SourceSurf->NextScan+i, 1); + vgaPutPixel(spx, spy, c); + } + spx++; + } + spy++; + } +} + +VOID DFB2VGA(DEVSURF *DestSurf, DEVSURF *SourceSurf, RECTL *DestRect, + POINTL *SourcePoint) +{ + DIB2VGA(DestSurf, SourceSurf, DestRect, SourcePoint, NULL, VGA_TARGET); +} + + +VOID VGA2DIB(DEVSURF *DestSurf, ULONG xSource, ULONG ySource, + PVOID DestScan0, ULONG left, ULONG top, ULONG width, + ULONG height, ULONG lDelta, ULONG Format, ULONG *Conversion) +{ + ULONG i, j, spx, spy, right = left + width, bottom = top + height; + BYTE c; + spy = ySource; + + for (j=top; jStartBmp+j*DestSurf->NextScan+i, c, 1); + spx++; + } + spy++; + } +} + +BOOL VGADDICopyBits(SURFOBJ *Dest, SURFOBJ *Source, + CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, + PRECTL DestRect, PPOINTL SourcePoint) +{ + PDEVSURF pdsurf; // Pointer to a device surface + + LONG lDelta; // Delta to next scan of destination + PVOID pjDstScan0; // Pointer to scan 0 of destination DIB + ULONG *pulXlate; // Pointer to color xlate vector + BOOL EnumMore; // Clip continuation flag + ULONG ircl; // Clip enumeration rectangle index + RECT_ENUM cben; // Clip enumerator + RECTL TempRect; + PRECTL PRect; + POINTL TempPoint; + DEVSURF TempDSurf; + PDEVSURF SurfDest; // Pointer for target + PDEVSURF SurfSource; // Pointer for source if present + INT iCopyDir; + RECT_ENUM RectEnum; // Clip enumerator + BYTE jClipping; + UCHAR *pucDIB4ToVGAConvTables; + ULONG ulWidth; + ULONG ulNumSlices; + ULONG ulRight; + ULONG x; + + // If translation is XO_TRIVIAL then no translation is required + if(ColorTranslation && (ColorTranslation->flXlate & XO_TRIVIAL)) + { + ColorTranslation = NULL; + } + + // If the destination is a device managed bitmap give it to VGADDIBitBlt + if(ColorTranslation && + ((Dest->iType == STYPE_DEVICE) || (Dest->iType == STYPE_DEVBITMAP))) + { + return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL, + Clip, ColorTranslation, + DestRect, SourcePoint, + (POINTL *)NULL, (BRUSHOBJ *)NULL, (POINTL *)NULL, + 0x0000CCCC)); + } + + if ((Dest->iType == STYPE_DEVICE) && (Source->iType == STYPE_DEVICE)) { + SurfDest = (PDEVSURF) Dest->dhsurf; + SurfSource = (PDEVSURF) Source->dhsurf; + + if (Clip == (CLIPOBJ *) NULL) + { + jClipping = DC_TRIVIAL; + } + else + { + jClipping = Clip->iDComplexity; + } + + + if (SourcePoint->y >= DestRect->top) { + if (SourcePoint->x >= DestRect->left) { + iCopyDir = CD_RIGHTDOWN; + } else { + iCopyDir = CD_LEFTDOWN; + } + } else { + if (SourcePoint->x >= DestRect->left) { + iCopyDir = CD_RIGHTUP; + } else { + iCopyDir = CD_LEFTUP; + } + } + + switch(jClipping) { + + case DC_TRIVIAL: + Screen2Screen(SurfDest, DestRect, SourcePoint, iCopyDir); + break; + + case DC_RECT: + if (!VGADDIIntersectRect(&TempRect, DestRect, + &Clip->rclBounds)) + { + return TRUE; + } + + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + + Screen2Screen(SurfDest, &TempRect, &TempPoint, iCopyDir); + break; + + case DC_COMPLEX: + + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, + iCopyDir, ENUM_RECT_LIMIT); + + do { + EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), + (PVOID)&RectEnum); + + PRect = RectEnum.arcl; + for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) { + + VGADDIIntersectRect(PRect, PRect, DestRect); + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + PRect->left - + DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - + DestRect->top; + Screen2Screen(SurfDest, PRect, &TempPoint, iCopyDir); + } + } while(EnumMore); + break; + } + return TRUE; + } + + // Device managed to standard bitmap + if ((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_BITMAP)) + { + switch(Dest->iBitmapFormat) + { + case BMF_4BPP: + if (ColorTranslation == NULL) + { + // Make just enough of a fake DEVSURF for the dest so that + // the DFB to DIB code can work + + TempDSurf.NextScan = Dest->lDelta; + TempDSurf.StartBmp = Dest->pvScan0; + + if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL)) + { + ulWidth = DestRect->right - DestRect->left; + if (ulWidth <= MAX_SCAN_WIDTH) + { + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + DestRect, SourcePoint); + } else { + TempRect.left = DestRect->left; + TempRect.right = DestRect->right; + TempRect.top = DestRect->top; + TempRect.bottom = DestRect->bottom; + + // cut rect into slices MAX_SCAN_WIDTH wide + ulRight = TempRect.right; // save right edge + TempRect.right = TempRect.left+MAX_SCAN_WIDTH; + ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH; + for (x=0; xx + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + TempRect.left = TempRect.right; + TempRect.right += MAX_SCAN_WIDTH; + } + TempRect.right = ulRight; + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + } + } + else if (Clip->iDComplexity == DC_RECT) + { + if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds)) + { + ulWidth = TempRect.right - TempRect.left; + + if (ulWidth <= MAX_SCAN_WIDTH) + { + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + } else { + // cut rect into slices MAX_SCAN_WIDTH wide + ulRight = TempRect.right; // save right edge + TempRect.right = TempRect.left+MAX_SCAN_WIDTH; + ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH; + for (x=0; xx + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + TempRect.left = TempRect.right; + TempRect.right += MAX_SCAN_WIDTH; + } + TempRect.right = ulRight; + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + } + } + return(TRUE); + } else { + // DC_COMPLEX: + + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, + CD_ANY, ENUM_RECT_LIMIT); + + do { + EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), + (PVOID) &RectEnum); + PRect = RectEnum.arcl; + for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) + { + VGADDIIntersectRect(PRect,PRect,DestRect); + ulWidth = PRect->right - PRect->left; + + if (ulWidth <= MAX_SCAN_WIDTH) + { + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + } else { + // cut rect into slices MAX_SCAN_WIDTH wide + ulRight = PRect->right; // save right edge + PRect->right = PRect->left+MAX_SCAN_WIDTH; + ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH; + for (x=0; xx + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + PRect, &TempPoint); + PRect->left = PRect->right; + PRect->right += MAX_SCAN_WIDTH; + } + PRect->right = ulRight; + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf, + PRect, &TempPoint); + } + } + } while(EnumMore); + + } + return(TRUE); + } + break; + } + } + + // Device managed to device managed + if ((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVBITMAP)) { + + if (Source==Dest) + { + TempRect.top = SourcePoint->y; + TempRect.left = SourcePoint->x; + TempRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top); + TempRect.right = SourcePoint->x + (DestRect->right - DestRect->left); + + if (DestRect->top >= SourcePoint->y) + { + if (VGADDIIntersectRect(&TempRect,&TempRect,DestRect)) + { + return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL, + Clip, ColorTranslation, + DestRect, SourcePoint, + (POINTL *)NULL, (BRUSHOBJ *)NULL, + (POINTL *)NULL, 0x0000CCCC)); + } + } + } + + if (ColorTranslation == NULL) + { + if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL)) + { + DFB2DFB((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf, + DestRect, SourcePoint); + } else if (Clip->iDComplexity == DC_RECT) + { + if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds)) + { + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + + DFB2DFB((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + } + return(TRUE); + } else { + // DC_COMPLEX: + + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, + CD_ANY, ENUM_RECT_LIMIT); + + do { + EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), (PVOID)&RectEnum); + PRect = RectEnum.arcl; + for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) + { + VGADDIIntersectRect(PRect,PRect,DestRect); + + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + + DFB2DFB((PDEVSURF)Dest->dhsurf, (PDEVSURF)Source->dhsurf, + PRect, &TempPoint); + } + } while(EnumMore); + } + return(TRUE); + } + } + + // Device managed to screen + if((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVICE)) + { + if(ColorTranslation == NULL) + { + if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL)) + { + DFB2VGA((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf, DestRect, + SourcePoint); + } else if (Clip->iDComplexity == DC_RECT) + { + if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds)) + { + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + + DFB2VGA((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf, + &TempRect, &TempPoint); + } + return(TRUE); + } else { + // DC_COMPLEX: + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT); + + do { + EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), (PVOID)&RectEnum); + PRect = RectEnum.arcl; + for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) + { + VGADDIIntersectRect(PRect,PRect,DestRect); + + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + + DFB2VGA((PDEVSURF)Dest->dhsurf, (PDEVSURF)Source->dhsurf, + PRect, &TempPoint); + } + } while(EnumMore); + } + return(TRUE); + } + } + + // Standard bitmap to device managed + if ((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVBITMAP)) + { + switch(Source->iBitmapFormat) + { + case BMF_4BPP: + if (ColorTranslation == NULL) + { + pucDIB4ToVGAConvTables = + ((PDEVSURF) Dest->dhsurf)->ppdev-> + pucDIB4ToVGAConvTables; + + // Make just enough of a fake DEVSURF for the source so that + // the DIB to DFB code can work + + TempDSurf.NextScan = Source->lDelta; + TempDSurf.StartBmp = Source->pvScan0; + + // Clip as needed + + if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL)) + { + ulWidth = DestRect->right - DestRect->left; + + if (ulWidth <= MAX_SCAN_WIDTH) + { + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, DestRect, + SourcePoint, pucDIB4ToVGAConvTables, DFB_TARGET); + } else { + TempRect.left = DestRect->left; + TempRect.right = DestRect->right; + TempRect.top = DestRect->top; + TempRect.bottom = DestRect->bottom; + + // cut rect into slices MAX_SCAN_WIDTH wide + ulRight = TempRect.right; // save right edge + TempRect.right = TempRect.left+MAX_SCAN_WIDTH; + ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH; + for (x=0; xx + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + &TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + TempRect.left = TempRect.right; + TempRect.right += MAX_SCAN_WIDTH; + } + TempRect.right = ulRight; + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + &TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + } + } + else if (Clip->iDComplexity == DC_RECT) + { + if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds)) + { + ulWidth = TempRect.right - TempRect.left; + + if (ulWidth <= MAX_SCAN_WIDTH) + { + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + &TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + } else { + // cut rect into slices MAX_SCAN_WIDTH wide + ulRight = TempRect.right; // save right edge + TempRect.right = TempRect.left+MAX_SCAN_WIDTH; + ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH; + for (x=0; xx + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + &TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + TempRect.left = TempRect.right; + TempRect.right += MAX_SCAN_WIDTH; + } + TempRect.right = ulRight; + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + &TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + } + } + return(TRUE); + } else { + // DC_COMPLEX: + + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, + CD_ANY, ENUM_RECT_LIMIT); + + do { + EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), + (PVOID) &RectEnum); + PRect = RectEnum.arcl; + for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) + { + VGADDIIntersectRect(PRect,PRect,DestRect); + ulWidth = PRect->right - PRect->left; + + if (ulWidth <= MAX_SCAN_WIDTH) + { + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + PRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + } else { + // cut rect into slices MAX_SCAN_WIDTH wide + ulRight = PRect->right; // save right edge + PRect->right = PRect->left+MAX_SCAN_WIDTH; + ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH; + for (x=0; xx + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + PRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + PRect->left = PRect->right; + PRect->right += MAX_SCAN_WIDTH; + } + PRect->right = ulRight; + // Adjust the source point for clipping too + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + PRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET); + } + } + } while(EnumMore); + + } + return(TRUE); + } + break; + + case BMF_1BPP: + case BMF_8BPP: + return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL, + Clip, ColorTranslation, + DestRect, SourcePoint, + (POINTL *)NULL, (BRUSHOBJ *)NULL, (POINTL *)NULL, + 0x0000CCCC)); + } + } + + // Standard bitmap to screen + if ((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE)) + { + switch(Source->iBitmapFormat) + { + case BMF_4BPP: + if (ColorTranslation == NULL) + { + pucDIB4ToVGAConvTables = + ((PDEVSURF) Dest->dhsurf)->ppdev-> + pucDIB4ToVGAConvTables; + + // Make just enough of a fake DEVSURF for the source so that + // the DIB to VGA code can work + + TempDSurf.NextScan = Source->lDelta; + TempDSurf.StartBmp = Source->pvScan0; + + // Clip as needed + + if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL)) + { + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, DestRect, + SourcePoint, pucDIB4ToVGAConvTables, VGA_TARGET); + + } else if (Clip->iDComplexity == DC_RECT) + { + if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds)) + { + TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left; + TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top; + + DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, + &TempRect, &TempPoint, pucDIB4ToVGAConvTables, VGA_TARGET); + } + return(TRUE); + + } else { + // DC_COMPLEX: + + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, + CD_ANY, ENUM_RECT_LIMIT); + + do { + EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), (PVOID)&RectEnum); + PRect = RectEnum.arcl; + for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) + { + VGADDIIntersectRect(PRect,PRect,DestRect); + + TempPoint.x = SourcePoint->x + PRect->left - DestRect->left; + TempPoint.y = SourcePoint->y + PRect->top - DestRect->top; + + DIB2VGA((PDEVSURF) Dest->dhsurf, + &TempDSurf, PRect, &TempPoint, + pucDIB4ToVGAConvTables, VGA_TARGET); + } + } while(EnumMore); + } + return(TRUE); + } + break; + + case BMF_1BPP: + case BMF_8BPP: + return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL, + Clip, ColorTranslation, + DestRect, SourcePoint, + (POINTL *)NULL, (BRUSHOBJ *)NULL, (POINTL *)NULL, + 0x0000CCCC)); + + case BMF_8RLE: + case BMF_4RLE: +// return(RleBlt(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint)); + + } + } + // Screen to standard bitmap + if ((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP)) + { + if (Dest->iBitmapFormat == BMF_4BPP) + { +// pdsurf = (PDEVSURF) Source->dhsurf; + + // Get the data for the destination DIB + lDelta = Dest->lDelta; + pjDstScan0 = (PBYTE) Dest->pvScan0; + + // Setup for any color translation which may be needed !!! Is any needed at all? + if (ColorTranslation == NULL) + { + pulXlate = NULL; + } + else + { + if (ColorTranslation->flXlate & XO_TABLE) + { + pulXlate = ColorTranslation->pulXlate; + } else { + pulXlate = (PULONG) NULL; + } + } + + if (Clip != (CLIPOBJ *) NULL) + { + switch(Clip->iDComplexity) + { + case DC_TRIVIAL: + EnumMore = FALSE; + cben.c = 1; + cben.arcl[0] = *DestRect; + break; + + case DC_RECT: + EnumMore = FALSE; + cben.c = 1; + cben.arcl[0] = Clip->rclBounds; + break; + + case DC_COMPLEX: + EnumMore = TRUE; + cben.c = 0; + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT); + break; + } + } + else + { + EnumMore = FALSE; + cben.c = 1; + cben.arcl[0] = *DestRect; // Use the target for clipping + } + + // Call the VGA conversion routine, adjusted for each rectangle + + do + { + LONG xSrc; + LONG ySrc; + RECTL *PRect; + + if (EnumMore) + EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(cben), (PVOID) &cben); + + for (ircl = 0; ircl < cben.c; ircl++) + { + PRect = &cben.arcl[ircl]; + + xSrc = SourcePoint->x + PRect->left - DestRect->left; + ySrc = SourcePoint->y + PRect->top - DestRect->top; + + VGAtoGDI(Dest, Source, NULL, ColorTranslation, DestRect, SourcePoint); + +/* VGA2DIB(pdsurf, xSrc, ySrc, pjDstScan0, + PRect->left, PRect->top, PRect->right - PRect->left, + PRect->bottom - PRect->top, + lDelta, Dest->iBitmapFormat, pulXlate); */ + } + } while (EnumMore); + return(TRUE); + } + } + // If unsupported + return(SimCopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint)); +} + +BOOL SimCopyBits(SURFOBJ *Dest, SURFOBJ *Source, + CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, + PRECTL DestRect, PPOINTL SourcePoint) +{ + HBITMAP hbmTmp; + SURFOBJ *psoTmp; + RECTL rclTmp; + SIZEL sizlTmp; + BOOL bReturn = FALSE; + POINTL ptl00 = {0,0}; + + rclTmp.top = rclTmp.left = 0; + rclTmp.right = sizlTmp.cx = DestRect->right - DestRect->left; + rclTmp.bottom = sizlTmp.cy = DestRect->bottom - DestRect->top; + + // Create bitmap in our compatible format + hbmTmp = EngCreateBitmap(sizlTmp, sizlTmp.cx * 1, BMF_4BPP, 0, NULL); // FIXME: Replace *1 with *BPP? + + if (hbmTmp) + { + if ((psoTmp = EngLockSurface((HSURF)hbmTmp)) != NULL) + { + if (((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE)) || + ((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVBITMAP))) + { + // DIB to VGA or DIB to DFB + if (EngCopyBits(psoTmp, Source, NULL, ColorTranslation, &rclTmp, SourcePoint)) + { + bReturn = VGADDICopyBits(Dest, psoTmp, Clip, NULL, DestRect, &ptl00); + } + } + else if (((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP)) || + ((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_BITMAP))) + { + // VGA to DIB or DFB to DIB + if (VGADDICopyBits(psoTmp, Source, NULL, NULL, &rclTmp, SourcePoint)) + { + bReturn = EngCopyBits(Dest, psoTmp, Clip, ColorTranslation, DestRect, &ptl00); + } + } + else if (((Source->iType == STYPE_DEVICE) || (Source->iType == STYPE_DEVBITMAP)) && + ((Dest->iType == STYPE_DEVICE) || (Dest->iType == STYPE_DEVBITMAP))) + { + // VGA or DFB to VGA or DFB + if (VGADDICopyBits(psoTmp, Source, NULL, NULL, &rclTmp, SourcePoint)) + { + bReturn = VGADDICopyBits(Dest, psoTmp, Clip, ColorTranslation, DestRect, &ptl00); + } + } + + EngUnlockSurface(psoTmp); + } + + EngDeleteSurface((HSURF)hbmTmp); + } + + return(bReturn); +} diff --git a/reactos/drivers/dd/vga/display/vgaddi.h b/reactos/drivers/dd/vga/display/vgaddi.h index 564568294e3..12e6977e1e5 100644 --- a/reactos/drivers/dd/vga/display/vgaddi.h +++ b/reactos/drivers/dd/vga/display/vgaddi.h @@ -206,3 +206,7 @@ BOOL InitVGA(PPDEV ppdev, BOOL bFirst); // screen.c: initialize VGA mode #define DRIVER_OFFSCREEN_REFRESHED 0x04L // if not set, don't use offscreen memory #define PLANAR_PELS_PER_CPU_ADDRESS 8 #define PACKED_PELS_PER_CPU_ADDRESS 2 + +BOOL VGAtoGDI( + SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation, + RECTL *DestRect, POINTL *SourcePoint); diff --git a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c index 90fddc2f165..f6db7acf35b 100644 --- a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c +++ b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c @@ -1,10 +1,21 @@ #include #include - +#include #include "vgavideo.h" #include +INT abs(INT nm) +{ + if(nm<0) + { + return nm * -1; + } else + { + return nm; + } +} + div_t div(int num, int denom) { div_t r; @@ -31,6 +42,40 @@ int mod(int num, int denom) return dvt.rem; } +BYTE bytesPerPixel(ULONG Format) +{ + // This function is taken from /subsys/win32k/eng/surface.c + // FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the + // pixel size if < 1 byte we expand it to 1 byte for simplicities sake + + if(Format==BMF_1BPP) + { + return 1; + } else + if((Format==BMF_4BPP) || (Format==BMF_4RLE)) + { + return 1; + } else + if((Format==BMF_8BPP) || (Format==BMF_8RLE)) + { + return 1; + } else + if(Format==BMF_16BPP) + { + return 2; + } else + if(Format==BMF_24BPP) + { + return 3; + } else + if(Format==BMF_32BPP) + { + return 4; + } + + return 0; +} + VOID vgaPreCalc() { ULONG j; @@ -84,10 +129,10 @@ VOID vgaPreCalc() } } -void vgaPutPixel(int x, int y, unsigned char c) +VOID vgaPutPixel(INT x, INT y, UCHAR c) { - unsigned offset; - unsigned char a; + ULONG offset; + UCHAR a; offset = xconv[x]+y80[y]; @@ -98,9 +143,9 @@ void vgaPutPixel(int x, int y, unsigned char c) WRITE_REGISTER_UCHAR(vidmem + offset, c); } -void vgaPutByte(int x, int y, unsigned char c) +VOID vgaPutByte(INT x, INT y, UCHAR c) { - unsigned offset; + ULONG offset; offset = xconv[x]+y80[y]; @@ -111,30 +156,29 @@ void vgaPutByte(int x, int y, unsigned char c) WRITE_REGISTER_UCHAR(vidmem + offset, c); } -void vgaGetByte(unsigned offset, - unsigned char *b, unsigned char *g, - unsigned char *r, unsigned char *i) +VOID vgaGetByte(ULONG offset, + UCHAR *b, UCHAR *g, + UCHAR *r, UCHAR *i) { -// fixme: use READ_REGISTER_UCHAR - WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0304); - *i = vidmem[offset]; + *i = READ_REGISTER_UCHAR(vidmem + offset); WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0204); - *r = vidmem[offset]; + *r = READ_REGISTER_UCHAR(vidmem + offset); WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0104); - *g = vidmem[offset]; + *g = READ_REGISTER_UCHAR(vidmem + offset); WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0004); - *b = vidmem[offset]; + *b = READ_REGISTER_UCHAR(vidmem + offset); } -int vgaGetPixel(int x, int y) +INT vgaGetPixel(INT x, INT y) { - unsigned char mask, b, g, r, i; - unsigned offset; + UCHAR mask, b, g, r, i; + ULONG offset; offset = xconv[x]+y80[y]; - mask=maskbit[x]; vgaGetByte(offset, &b, &g, &r, &i); + + mask=maskbit[x]; b=b&mask; g=g&mask; r=r&mask; @@ -149,12 +193,12 @@ int vgaGetPixel(int x, int y) return(b+2*g+4*r+8*i); } -BOOL vgaHLine(int x, int y, int len, unsigned char c) +BOOL vgaHLine(INT x, INT y, INT len, UCHAR c) { - unsigned char a; - unsigned int pre1, i; - unsigned int orgpre1, orgx, midpre1; - unsigned long leftpixs, midpixs, rightpixs, temp; + UCHAR a; + ULONG pre1, i; + ULONG orgpre1, orgx, midpre1; + ULONG long leftpixs, midpixs, rightpixs, temp; orgx=x; @@ -244,10 +288,10 @@ BOOL vgaHLine(int x, int y, int len, unsigned char c) return TRUE; } -BOOL vgaVLine(int x, int y, int len, unsigned char c) +BOOL vgaVLine(INT x, INT y, INT len, UCHAR c) { - unsigned offset, i; - unsigned char a; + ULONG offset, i; + UCHAR a; offset = xconv[x]+y80[y]; @@ -265,3 +309,25 @@ BOOL vgaVLine(int x, int y, int len, unsigned char c) return TRUE; } + +static const RECTL rclEmpty = { 0, 0, 0, 0 }; + +BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2) +{ + prcDst->left = max(prcSrc1->left, prcSrc2->left); + prcDst->right = min(prcSrc1->right, prcSrc2->right); + + if (prcDst->left < prcDst->right) { + prcDst->top = max(prcSrc1->top, prcSrc2->top); + prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom); + + if (prcDst->top < prcDst->bottom) + { + return TRUE; + } + } + + *prcDst = rclEmpty; + + return FALSE; +} diff --git a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h index 73054d88d1f..99e2a8edeee 100644 --- a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h +++ b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h @@ -28,3 +28,13 @@ typedef struct _VideoMode { } VideoMode; VOID vgaPreCalc(); +VOID vgaPutPixel(INT x, INT y, UCHAR c); +VOID vgaPutByte(INT x, INT y, UCHAR c); +VOID vgaGetByte(ULONG offset, + UCHAR *b, UCHAR *g, + UCHAR *r, UCHAR *i); +INT vgaGetPixel(INT x, INT y); +BOOL vgaHLine(INT x, INT y, INT len, UCHAR c); +BOOL vgaVLine(INT x, INT y, INT len, UCHAR c); +INT abs(INT nm); +BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2); diff --git a/reactos/include/ddk/winddi.h b/reactos/include/ddk/winddi.h index 24c9f1d3908..bc15f4aee3d 100644 --- a/reactos/include/ddk/winddi.h +++ b/reactos/include/ddk/winddi.h @@ -1035,6 +1035,8 @@ DWORD APIENTRY EngDeviceIoControl( DWORD nOutBufferSize, DWORD *lpBytesReturned); +VOID STDCALL EngFreeMem(PVOID Mem); + /* EngDeleteClip EngDeleteDriverObj @@ -1049,7 +1051,6 @@ EngEraseSurface EngFillPath EngFindImageProcAddress EngFindResource -EngFreeMem EngFreeModule EngFreeUserMem EngGetCurrentCodePage diff --git a/reactos/subsys/win32k/eng/copybits.c b/reactos/subsys/win32k/eng/copybits.c index 057c1ad76f9..ad499791e5d 100644 --- a/reactos/subsys/win32k/eng/copybits.c +++ b/reactos/subsys/win32k/eng/copybits.c @@ -15,21 +15,58 @@ VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFGDI *DestGDI, SURFGDI *SourceGDI, PRECTL DestRect, POINTL *SourcePoint, - ULONG Delta) + ULONG Delta, XLATEOBJ *ColorTranslation) { - ULONG dy, leftOfSource, leftOfDest, Width; + ULONG dy, leftOfSource, leftOfDest, Width, SourceBPP, DestBPP, RGBulong = 0, idxColor, i, TrivialCopy = 0; + BYTE *SourcePos, *SourceInitial, *DestPos, *DestInitial; // FIXME: Get ColorTranslation passed here and do something with it + if(ColorTranslation == NULL) + { + TrivialCopy = 1; + } else if(ColorTranslation->flXlate & XO_TRIVIAL) + { + TrivialCopy = 1; + } + leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel; leftOfDest = DestRect->left * DestGDI->BytesPerPixel; Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel; - for(dy=DestRect->top; dybottom; dy++) + if(TrivialCopy == 1) { - memcpy(DestSurf->pvBits+Delta*dy+leftOfDest, - SourceSurf->pvBits+Delta*dy+leftOfSource, - Width); + for(dy=DestRect->top; dybottom; dy++) + { + memcpy(DestSurf->pvBits+Delta*dy+leftOfDest, + SourceSurf->pvBits+Delta*dy+leftOfSource, + Width); + } + } else + if(ColorTranslation->flXlate & XO_TABLE) + { + SourceBPP = bytesPerPixel(SourceSurf->iBitmapFormat); + DestBPP = bytesPerPixel(DestSurf->iBitmapFormat); + + SourcePos = SourceSurf->pvBits + + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP); + SourceInitial = SourcePos; + + DestPos = DestSurf->pvBits + + ((DestRect->bottom - DestRect->top) * DestSurf->lDelta) + (DestRect->left * DestBPP); + DestInitial = DestPos; + + for(i=DestRect->left; iright; i++) + { + memcpy(&RGBulong, SourcePos, SourceBPP); + idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong); + memcpy(DestPos, &idxColor, DestBPP); + + SourcePos+=SourceBPP; + DestPos+=DestBPP; + } + SourcePos = SourceInitial + SourceSurf->lDelta; + DestPos = DestInitial + DestSurf->lDelta; } } @@ -70,7 +107,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, // Source surface is device managed if(Source->iType!=STYPE_BITMAP) { - SourceGDI = AccessInternalObjectFromUserObject(Dest); + SourceGDI = AccessInternalObjectFromUserObject(Source); if (SourceGDI->CopyBits!=NULL) { @@ -93,16 +130,19 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, clippingType = Clip->iDComplexity; } - // We don't handle color translation just yet - - if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)) + // We only handle XO_TABLE translations at the momement + if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) || + (ColorTranslation->flXlate & XO_TABLE)) { + SourceGDI = AccessInternalObjectFromUserObject(Source); + DestGDI = AccessInternalObjectFromUserObject(Dest); + switch(clippingType) { case DC_TRIVIAL: CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, - DestRect, SourcePoint, Source->lDelta); + DestRect, SourcePoint, Source->lDelta, ColorTranslation); return(TRUE); @@ -117,7 +157,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, - &rclTmp, &ptlTmp, Source->lDelta); + &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation); return(TRUE); @@ -145,7 +185,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, - prcl, &ptlTmp, Source->lDelta); + prcl, &ptlTmp, Source->lDelta, ColorTranslation); prcl++; diff --git a/reactos/subsys/win32k/eng/surface.c b/reactos/subsys/win32k/eng/surface.c index 8c42d6b6828..4926e594000 100644 --- a/reactos/subsys/win32k/eng/surface.c +++ b/reactos/subsys/win32k/eng/surface.c @@ -191,9 +191,7 @@ BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks) if(Hooks & HOOK_STROKEPATH) SurfGDI->StrokePath = Dc->DriverFunctions.StrokePath; if(Hooks & HOOK_FILLPATH) SurfGDI->FillPath = Dc->DriverFunctions.FillPath; if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath; - if(Hooks & HOOK_LINETO) { SurfGDI->LineTo = Dc->DriverFunctions.LineTo; -DbgPrint("associating LineTo is now %08x\n", SurfGDI->LineTo); -} + if(Hooks & HOOK_LINETO) SurfGDI->LineTo = Dc->DriverFunctions.LineTo; if(Hooks & HOOK_COPYBITS) SurfGDI->CopyBits = Dc->DriverFunctions.CopyBits; if(Hooks & HOOK_SYNCHRONIZE) SurfGDI->Synchronize = Dc->DriverFunctions.Synchronize; if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE; @@ -218,7 +216,8 @@ BOOL EngDeleteSurface(HSURF Surface) SURFOBJ *EngLockSurface(HSURF Surface) { - // FIXME: Do we need to allocate new memory for this user object?? + // FIXME: Do we need to allocate new memory for this user object?? Since there's an unlock.. it appears to be so + // probably because win32k is supposed to do some kind of wierd handle\object thing that we don't return AccessUserObject(Surface); } diff --git a/reactos/subsys/win32k/stubs/stubs.c b/reactos/subsys/win32k/stubs/stubs.c index 38b9239eb4d..b570f932992 100644 --- a/reactos/subsys/win32k/stubs/stubs.c +++ b/reactos/subsys/win32k/stubs/stubs.c @@ -29,7 +29,6 @@ STUB(EngEnumForms) STUB(EngFillPath) STUB(EngFindImageProcAddress) STUB(EngFindResource) -STUB(EngFreeMem) STUB(EngFreeModule) STUB(EngFreeUserMem) STUB(EngGetCurrentCodePage)