Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

433 lines
13 KiB

/*****************************************************************************\
* Smart 64k Color Bank Manager
*
* Copyright (c) 1992 Microsoft Corporation
\*****************************************************************************/
#include "driver.h"
/*****************************************************************************\
* pcoBankStart - Start the bank enumeration using the clip object.
*
* Used when the destination is the screen and we can't do the clipping
* ourselves (as we can for blt's).
\*****************************************************************************/
CLIPOBJ* pcoBankStart(
PPDEV ppdev,
RECTL* prclScans,
SURFOBJ* pso,
CLIPOBJ* pco)
{
LONG iTopScan;
// Remember what the last scan is that we're going to, and
// make sure we only try to go as far as we need to. It could
// happen that when get a prclScans bigger than the screen:
ppdev->iLastScan = min(prclScans->bottom, (LONG) ppdev->cyScreen);
// Adjust for those weird cases where we're asked to start enumerating
// above or below the bottom of the screen:
iTopScan = max(0, prclScans->top);
iTopScan = min(iTopScan, (LONG) ppdev->cyScreen - 1);
if (pco->iDComplexity != DC_TRIVIAL)
{
iTopScan = max(pco->rclBounds.top, iTopScan);
ppdev->iLastScan = min(pco->rclBounds.bottom, ppdev->iLastScan);
}
// Map in the top bank:
if (iTopScan < ppdev->rcl1WindowClip.top ||
iTopScan >= ppdev->rcl1WindowClip.bottom)
{
ppdev->pfnBankControl(ppdev, iTopScan, JustifyTop);
}
pso->pvScan0 = ppdev->pvBitmapStart;
if ((pco == NULL) || (pco->iDComplexity == DC_TRIVIAL))
{
// The call may have come down to us as having no clipping, but
// we have to clip to the banks, so use our own clip object:
pco = ppdev->pcoNull;
pco->rclBounds = ppdev->rcl1WindowClip;
ASSERTVGA(pco->fjOptions & OC_BANK_CLIP, "Default BANK_CLIP not set");
ASSERTVGA(pco->iDComplexity == DC_RECT, "Default clip not DC_RECT");
}
else
{
// Save the engine's clip object data that we'll be tromping on:
ppdev->rclSaveBounds = pco->rclBounds;
ppdev->iSaveDComplexity = pco->iDComplexity;
ppdev->fjSaveOptions = pco->fjOptions;
// Let engine know it has to pay attention to the rclBounds of the
// clip object:
pco->fjOptions |= OC_BANK_CLIP;
// Use the bank bounds if they are tighter than the existing
// bounds.
if (pco->rclBounds.top <= ppdev->rcl1WindowClip.top)
pco->rclBounds.top = ppdev->rcl1WindowClip.top;
if (pco->rclBounds.bottom >= ppdev->rcl1WindowClip.bottom)
pco->rclBounds.bottom = ppdev->rcl1WindowClip.bottom;
if ((pco->rclBounds.top >= pco->rclBounds.bottom) ||
(pco->rclBounds.left >= pco->rclBounds.right))
{
// It's conceivable that we could get a situation where our
// draw rectangle is completely disjoint from the specified
// rectangle's rclBounds. Make sure we don't puke on our
// shoes:
pco->rclBounds.left = 0;
pco->rclBounds.top = 0;
pco->rclBounds.right = 0;
pco->rclBounds.bottom = 0;
ppdev->iLastScan = 0;
}
}
return(pco);
}
/*****************************************************************************\
* bBankEnum - Continue the bank enumeration.
\*****************************************************************************/
BOOL bBankEnum(PPDEV ppdev, SURFOBJ* pso, CLIPOBJ* pco)
{
LONG yNewTop = ppdev->rcl1WindowClip.bottom;
if (yNewTop >= ppdev->iLastScan)
{
// Okay, that was the last bank, so restore our structures:
if (pco != ppdev->pcoNull)
{
pco->rclBounds = ppdev->rclSaveBounds;
pco->iDComplexity = ppdev->iSaveDComplexity;
pco->fjOptions = ppdev->fjSaveOptions;
}
return(FALSE);
}
ppdev->pfnBankControl(ppdev, yNewTop, JustifyTop);
ASSERTVGA(yNewTop >= ppdev->rcl1WindowClip.top &&
yNewTop < ppdev->rcl1WindowClip.bottom, "Out of bounds");
// Adjust the pvScan0 because we've moved the window to view
// a different area:
pso->pvScan0 = ppdev->pvBitmapStart;
// Set the bounds to the new bank:
pco->rclBounds.top = yNewTop;
pco->rclBounds.left = ppdev->rcl1WindowClip.left;
pco->rclBounds.bottom = ppdev->rcl1WindowClip.bottom;
pco->rclBounds.right = ppdev->rcl1WindowClip.right;
if (pco != ppdev->pcoNull)
{
// If we were originally given a non-trivial clip object, we have
// to clip to the original bounds:
if (pco->rclBounds.left <= ppdev->rclSaveBounds.left)
pco->rclBounds.left = ppdev->rclSaveBounds.left;
if (pco->rclBounds.right >= ppdev->rclSaveBounds.right)
pco->rclBounds.right = ppdev->rclSaveBounds.right;
if (pco->rclBounds.bottom >= ppdev->rclSaveBounds.bottom)
pco->rclBounds.bottom = ppdev->rclSaveBounds.bottom;
}
return(TRUE);
}
/***************************************************************************\
* vBankStartBltSrc - Start the bank enumeration for when the screen is
* the source.
\***************************************************************************/
VOID vBankStartBltSrc(
PPDEV ppdev,
SURFOBJ* pso,
POINTL* pptlSrc,
RECTL* prclDest,
POINTL* pptlNewSrc,
RECTL* prclNewDest)
{
LONG xRightSrc;
LONG yBottomSrc;
LONG iTopScan = max(0, pptlSrc->y);
if (iTopScan >= (LONG) ppdev->cyScreen)
{
// In some instances we may be asked to start on a scan below the screen.
// Since we obviously won't be drawing anything, don't bother mapping in
// a bank:
return;
}
// Map in the bank:
if (iTopScan < ppdev->rcl1WindowClip.top ||
iTopScan >= ppdev->rcl1WindowClip.bottom)
{
ppdev->pfnBankControl(ppdev, iTopScan, JustifyTop);
}
if (ppdev->rcl1WindowClip.right <= pptlSrc->x)
{
// We have to watch out for those rare cases where we're starting
// on a broken raster and we won't be drawing on the first part:
ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird start bounds");
ppdev->pfnBankNext(ppdev);
}
pso->pvScan0 = ppdev->pvBitmapStart;
// Adjust the source:
pptlNewSrc->x = pptlSrc->x;
pptlNewSrc->y = pptlSrc->y;
// Adjust the destination:
prclNewDest->left = prclDest->left;
prclNewDest->top = prclDest->top;
yBottomSrc = pptlSrc->y + prclDest->bottom - prclDest->top;
prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, yBottomSrc);
prclNewDest->bottom += prclDest->top - pptlSrc->y;
xRightSrc = pptlSrc->x + prclDest->right - prclDest->left;
prclNewDest->right = min(ppdev->rcl1WindowClip.right, xRightSrc);
prclNewDest->right += prclDest->left - pptlSrc->x;
}
/***************************************************************************\
* bBankEnumBltSrc - Continue the bank enumeration for when the screen is
* the source.
\***************************************************************************/
BOOL bBankEnumBltSrc(
PPDEV ppdev,
SURFOBJ* pso,
POINTL* pptlSrc,
RECTL* prclDest,
POINTL* pptlNewSrc,
RECTL* prclNewDest)
{
LONG xLeftSrc;
LONG xRightSrc;
LONG yBottomSrc;
LONG cx = prclDest->right - prclDest->left;
LONG cy = prclDest->bottom - prclDest->top;
LONG dx;
LONG dy;
LONG yBottom = min(pptlSrc->y + cy, (LONG) ppdev->cyScreen);
LONG yNewTop = ppdev->rcl1WindowClip.bottom;
if (ppdev->flBank & BANK_BROKEN_RASTER1)
{
ppdev->pfnBankNext(ppdev);
if (ppdev->rcl1WindowClip.left >= pptlSrc->x + cx)
{
if (ppdev->rcl1WindowClip.bottom < yBottom)
ppdev->pfnBankNext(ppdev);
else
{
// We're done:
return(FALSE);
}
}
}
else if (yNewTop < yBottom)
{
ppdev->pfnBankControl(ppdev, yNewTop, JustifyTop);
if (ppdev->rcl1WindowClip.right <= pptlSrc->x)
{
ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird bounds");
ppdev->pfnBankNext(ppdev);
}
}
else
{
// We're done:
return(FALSE);
}
// Adjust the source:
pso->pvScan0 = ppdev->pvBitmapStart;
pptlNewSrc->x = max(ppdev->rcl1WindowClip.left, pptlSrc->x);
pptlNewSrc->y = yNewTop;
// Adjust the destination:
dy = prclDest->top - pptlSrc->y; // y delta from source to dest
prclNewDest->top = yNewTop + dy;
yBottomSrc = pptlSrc->y + cy;
prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, yBottomSrc) + dy;
dx = prclDest->left - pptlSrc->x; // x delta from source to dest
xLeftSrc = pptlSrc->x;
prclNewDest->left = pptlNewSrc->x + dx;
xRightSrc = pptlSrc->x + cx;
prclNewDest->right = min(ppdev->rcl1WindowClip.right, xRightSrc) + dx;
return(TRUE);
}
/***************************************************************************\
* vBankStartBltDest - Start the bank enumeration for when the screen is
* the destination.
\***************************************************************************/
VOID vBankStartBltDest(
PPDEV ppdev,
SURFOBJ* pso,
POINTL* pptlSrc,
RECTL* prclDest,
POINTL* pptlNewSrc,
RECTL* prclNewDest)
{
LONG iTopScan = max(0, prclDest->top);
if (iTopScan >= (LONG) ppdev->cyScreen)
{
// In some instances we may be asked to start on a scan below the screen.
// Since we obviously won't be drawing anything, don't bother mapping in
// a bank:
return;
}
// Map in the bank:
if (iTopScan < ppdev->rcl1WindowClip.top ||
iTopScan >= ppdev->rcl1WindowClip.bottom)
{
ppdev->pfnBankControl(ppdev, iTopScan, JustifyTop);
}
if (ppdev->rcl1WindowClip.right <= prclDest->left)
{
// We have to watch out for those rare cases where we're starting
// on a broken raster and we won't be drawing on the first part:
ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird start bounds");
ppdev->pfnBankNext(ppdev);
}
pso->pvScan0 = ppdev->pvBitmapStart;
// Adjust the destination:
prclNewDest->left = prclDest->left;
prclNewDest->top = prclDest->top;
prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, prclDest->bottom);
prclNewDest->right = min(ppdev->rcl1WindowClip.right, prclDest->right);
// Adjust the source if there is one:
if (pptlSrc != NULL)
*pptlNewSrc = *pptlSrc;
}
/***************************************************************************\
* bBankEnumBltDest - Continue the bank enumeration for when the screen is
* the destination.
\***************************************************************************/
BOOL bBankEnumBltDest(
PPDEV ppdev,
SURFOBJ* pso,
POINTL* pptlSrc,
RECTL* prclDest,
POINTL* pptlNewSrc,
RECTL* prclNewDest)
{
LONG yBottom = min(prclDest->bottom, (LONG) ppdev->cyScreen);
LONG yNewTop = ppdev->rcl1WindowClip.bottom;
if (ppdev->flBank & BANK_BROKEN_RASTER1)
{
ppdev->pfnBankNext(ppdev);
if (ppdev->rcl1WindowClip.left >= prclDest->right)
{
if (ppdev->rcl1WindowClip.bottom < yBottom)
ppdev->pfnBankNext(ppdev);
else
{
// We're done:
return(FALSE);
}
}
}
else if (yNewTop < yBottom)
{
ppdev->pfnBankControl(ppdev, yNewTop, JustifyTop);
if (ppdev->rcl1WindowClip.right <= prclDest->left)
{
ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird bounds");
ppdev->pfnBankNext(ppdev);
}
}
else
{
// We're done:
return(FALSE);
}
pso->pvScan0 = ppdev->pvBitmapStart;
// Adjust the destination:
prclNewDest->top = yNewTop;
prclNewDest->left = max(ppdev->rcl1WindowClip.left, prclDest->left);
prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, prclDest->bottom);
prclNewDest->right = min(ppdev->rcl1WindowClip.right, prclDest->right);
// Adjust the source if there is one:
if (pptlSrc != NULL)
{
pptlNewSrc->x = pptlSrc->x + (prclNewDest->left - prclDest->left);
pptlNewSrc->y = pptlSrc->y + (prclNewDest->top - prclDest->top);
}
return(TRUE);
}