Implemented DrvCopybits

Minor fixes

svn path=/trunk/; revision=1116
This commit is contained in:
Jason Filby 2000-04-10 20:17:34 +00:00
parent 5b7a3113d5
commit 04a84d5ab8
11 changed files with 1078 additions and 87 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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; j<SourcePoint->y+dy; j++)
{
initial = GDIpos;
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+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; i<SourcePoint->x+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; j<SourcePoint->y+dy; j++)
if(ColorTranslation == NULL)
{
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+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; j<SourcePoint->y+dy; j++)
{
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
{
idxColor = vgaGetPixel(i, j);
RtlCopyMemory(GDIpos, &idxColor, 1);
GDIpos++;
}
GDIpos = initial + Dest->lDelta;
}
} else {
// Color translation
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
{
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+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 {

View file

@ -0,0 +1,859 @@
#include <ddk/winddi.h>
#include <internal\i386\io.h>
#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; j<DestRect->bottom; j++)
{
spx = SourcePoint->x;
for(i=DestRect->left; i<DestRect->right; 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; j<DestRect->bottom; 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; j<DestRect->bottom; j++)
{
spx = SourcePoint->x;
for(i=DestRect->left; i<DestRect->right; 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; j<bottom; j++)
{
spx = xSource;
for(i=left; i<right; i++)
{
c = vgaGetPixel(spx, spy);
RtlCopyMemory(DestSurf->StartBmp+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; x<ulNumSlices-1; x++)
{
// 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);
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; x<ulNumSlices-1; x++)
{
// 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);
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; x<ulNumSlices-1; x++)
{
// 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);
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; x<ulNumSlices-1; x++)
{
// 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);
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; x<ulNumSlices-1; x++)
{
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);
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; x<ulNumSlices-1; x++)
{
// 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);
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);
}

View file

@ -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);

View file

@ -1,10 +1,21 @@
#include <ddk/ntddk.h>
#include <ddk/ntddvid.h>
#include <ddk/winddi.h>
#include "vgavideo.h"
#include <internal/i386/io.h>
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;
}

View file

@ -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);

View file

@ -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

View file

@ -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; dy<DestRect->bottom; dy++)
if(TrivialCopy == 1)
{
memcpy(DestSurf->pvBits+Delta*dy+leftOfDest,
SourceSurf->pvBits+Delta*dy+leftOfSource,
Width);
for(dy=DestRect->top; dy<DestRect->bottom; 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; i<DestRect->right; 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++;

View file

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

View file

@ -29,7 +29,6 @@ STUB(EngEnumForms)
STUB(EngFillPath)
STUB(EngFindImageProcAddress)
STUB(EngFindResource)
STUB(EngFreeMem)
STUB(EngFreeModule)
STUB(EngFreeUserMem)
STUB(EngGetCurrentCodePage)