2000-03-17 21:44:02 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: GDI EngCopyBits Function
|
|
|
|
* FILE: subsys/win32k/eng/copybits.c
|
|
|
|
* PROGRAMER: Jason Filby
|
|
|
|
* REVISION HISTORY:
|
|
|
|
* 8/18/1999: Created
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ddk/winddi.h>
|
|
|
|
#include "objects.h"
|
2002-08-18 13:55:11 +00:00
|
|
|
#include "clip.h"
|
2001-03-31 15:35:08 +00:00
|
|
|
#include "../dib/dib.h"
|
2002-01-13 22:52:08 +00:00
|
|
|
#include <include/mouse.h>
|
|
|
|
#include <include/object.h>
|
|
|
|
#include <include/eng.h>
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
|
|
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
|
|
|
PRECTL DestRect, POINTL *SourcePoint,
|
|
|
|
ULONG Delta, XLATEOBJ *ColorTranslation)
|
2000-03-17 21:44:02 +00:00
|
|
|
{
|
2001-03-31 15:35:08 +00:00
|
|
|
ULONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel;
|
|
|
|
|
|
|
|
PFN_DIB_GetPixel Source_DIB_GetPixel;
|
|
|
|
PFN_DIB_PutPixel Dest_DIB_PutPixel;
|
|
|
|
|
|
|
|
DestWidth = DestRect->right - DestRect->left;
|
|
|
|
DestHeight = DestRect->bottom - DestRect->top;
|
|
|
|
CurrentSourceCol = SourcePoint->x;
|
|
|
|
CurrentSourceLine = SourcePoint->y;
|
|
|
|
|
|
|
|
// Assign GetPixel DIB function according to bytes per pixel
|
|
|
|
switch(DestGDI->BitsPerPixel)
|
|
|
|
{
|
|
|
|
case 4:
|
|
|
|
return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
|
|
|
|
DestRect, SourcePoint, Delta, ColorTranslation);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 24:
|
|
|
|
return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
|
|
|
|
DestRect, SourcePoint, Delta, ColorTranslation);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2000-03-17 21:44:02 +00:00
|
|
|
}
|
|
|
|
|
2002-06-15 21:44:08 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
EngCopyBits(SURFOBJ *Dest,
|
|
|
|
SURFOBJ *Source,
|
|
|
|
CLIPOBJ *Clip,
|
|
|
|
XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect,
|
|
|
|
POINTL *SourcePoint)
|
2000-03-17 21:44:02 +00:00
|
|
|
{
|
2001-06-03 10:47:29 +00:00
|
|
|
BOOLEAN ret;
|
2001-03-31 15:35:08 +00:00
|
|
|
SURFGDI *DestGDI, *SourceGDI;
|
|
|
|
BYTE clippingType;
|
|
|
|
RECTL rclTmp;
|
|
|
|
POINTL ptlTmp;
|
|
|
|
RECT_ENUM RectEnum;
|
|
|
|
BOOL EnumMore;
|
|
|
|
|
2001-06-03 10:47:29 +00:00
|
|
|
MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y,
|
|
|
|
(SourcePoint->x + abs(DestRect->right - DestRect->left)),
|
|
|
|
(SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
|
|
|
|
MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
|
|
|
|
// mark the copy block function to be DrvCopyBits instead of the
|
|
|
|
// GDI's copy bit function so as to remove clipping from the
|
|
|
|
// driver's responsibility
|
|
|
|
|
|
|
|
// If one of the surfaces isn't managed by the GDI
|
|
|
|
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
|
|
|
{
|
|
|
|
// Destination surface is device managed
|
|
|
|
if(Dest->iType!=STYPE_BITMAP)
|
|
|
|
{
|
|
|
|
DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
|
|
|
|
|
|
|
|
if (DestGDI->CopyBits!=NULL)
|
2000-03-17 21:44:02 +00:00
|
|
|
{
|
2001-06-03 10:47:29 +00:00
|
|
|
ret = DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
|
|
|
|
|
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
|
|
|
return ret;
|
2000-03-17 21:44:02 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// Source surface is device managed
|
|
|
|
if(Source->iType!=STYPE_BITMAP)
|
|
|
|
{
|
|
|
|
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
if (SourceGDI->CopyBits!=NULL)
|
|
|
|
{
|
2001-06-03 10:47:29 +00:00
|
|
|
ret = SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
|
|
|
|
|
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
|
|
|
return ret;
|
2000-03-17 21:44:02 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// If CopyBits wasn't hooked, BitBlt must be
|
2001-06-03 10:47:29 +00:00
|
|
|
ret = EngBitBlt(Dest, Source,
|
|
|
|
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
|
2002-01-13 22:52:08 +00:00
|
|
|
NULL, NULL, NULL, 0);
|
2001-06-03 10:47:29 +00:00
|
|
|
|
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
|
|
|
return ret;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// Determine clipping type
|
|
|
|
if (Clip == (CLIPOBJ *) NULL)
|
|
|
|
{
|
|
|
|
clippingType = DC_TRIVIAL;
|
|
|
|
} else {
|
|
|
|
clippingType = Clip->iDComplexity;
|
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// We only handle XO_TABLE translations at the momement
|
|
|
|
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
|
|
|
|
(ColorTranslation->flXlate & XO_TABLE))
|
|
|
|
{
|
|
|
|
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
|
|
|
DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
switch(clippingType)
|
|
|
|
{
|
|
|
|
case DC_TRIVIAL:
|
|
|
|
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
2001-06-03 10:47:29 +00:00
|
|
|
|
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
return(TRUE);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
case DC_RECT:
|
|
|
|
// Clip the blt to the clip rectangle
|
|
|
|
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
|
|
|
|
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-06-03 10:47:29 +00:00
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
return(TRUE);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
case DC_COMPLEX:
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
do {
|
|
|
|
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
if (RectEnum.c > 0)
|
|
|
|
{
|
|
|
|
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
|
|
|
RECTL* prcl = &RectEnum.arcl[0];
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
do {
|
|
|
|
EngIntersectRect(prcl, prcl, DestRect);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
|
|
|
|
ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
|
|
|
|
prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
prcl++;
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
} while (prcl < prclEnd);
|
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
} while(EnumMore);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2002-08-18 13:55:11 +00:00
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
2001-06-03 10:47:29 +00:00
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-06-03 10:47:29 +00:00
|
|
|
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
|
|
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
return FALSE;
|
2000-03-17 21:44:02 +00:00
|
|
|
}
|