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.
 
 
 
 
 
 

395 lines
11 KiB

/******************************Module*Header*******************************\
* Module Name: PAINT.c
* Author: Noel VanHook
* Date: Mar. 21, 1995
* Purpose: Handle calls to DrvPaint
*
* Copyright (c) 1995 Cirrus Logic, Inc.
*
\**************************************************************************/
/*
This module handles calls to DrvPaint() by converting them into calls
to DrvBitBlt(). The only conversion needed to to change the MIX into
a ROP4.
*/
#include "precomp.h"
#define PAINT_DBG_LEVEL 1
//==========================================================================
//
// In an attempt to trace the problems with the FIFO, we supply a few
// macros that will allow us to easily try different FIFO stratagies.
//
//
// This macro is executed at the start of every BLT, before any registers
// are written.
//
#define STARTBLT() \
do { \
}while (0)
//
// This macro is executed at the top of inner BLT loops.
// If there were clipping, for example, STARTBLT() would be executed
// once at the start of the BLT, and STARTBLTLOOP() would be executed
// before each rectangle in the clip list.
//
#define STARTBLTLOOP() \
do { \
REQUIRE(0); \
}while (0)
//==========================================================================
//
// Table to convert ROP2 codes to ROP3 codes.
//
BYTE Rop2ToRop3[]=
{
0xFF, // R2_WHITE /* 1 */
0x00, // R2_BLACK /* 0 */
0x05, // R2_NOTMERGEPEN /* DPon */
0x0A, // R2_MASKNOTPEN /* DPna */
0x0F, // R2_NOTCOPYPEN /* PN */
0x50, // R2_MASKPENNOT /* PDna */
0x55, // R2_NOT /* Dn */
0x5A, // R2_XORPEN /* DPx */
0x5F, // R2_NOTMASKPEN /* DPan */
0xA0, // R2_MASKPEN /* DPa */
0xA5, // R2_NOTXORPEN /* DPxn */
0xAA, // R2_NOP /* D */
0xAF, // R2_MERGENOTPEN /* DPno */
0xF0, // R2_COPYPEN /* P */
0xF5, // R2_MERGEPENNOT /* PDno */
0xFA, // R2_MERGEPEN /* DPo */
0xFF // R2_WHITE /* 1 */
};
//
// If data logging is enabled, Prototype the logging files.
//
#if LOG_CALLS
void LogPaint(
int acc,
SURFOBJ* psoDest,
MIX mix,
CLIPOBJ* pco,
BRUSHOBJ* pbo);
//
// If data logging is not enabled, compile out the calls.
//
#else
#define LogPaint(acc, psoDest, mix, pco, pbo)
#endif
/**************************************************************************\
* DrvPaint *
* *
* Paint the clipping region with the specified brush *
* Accomplished by converting into a call to DrvBitBlt() *
* *
\**************************************************************************/
BOOL DrvPaint
(
SURFOBJ *pso,
CLIPOBJ *pco,
BRUSHOBJ *pbo,
POINTL *pptlBrush,
MIX mix
)
{
ULONG fg_rop, bg_rop, rop4;
DWORD color;
PPDEV ppdev;
#if NULL_PAINT
{
if (pointer_switch) return TRUE;
}
#endif
ppdev = (PPDEV) pso->dhpdev;
ASSERTMSG (ppdev,"No PDEV in DrvPaint.");
SYNC_W_3D(ppdev);
//
// The destination rectangle is defined by the clipping region,
// so we should never get a null clipping region.
//
ASSERTMSG (pco, "DrvPaint without a clip object!\n");
DISPDBG((PAINT_DBG_LEVEL,"Drvpaint: Entry.\n"));
// Are we painting to a device bitmap?
if (pso->iType == STYPE_DEVBITMAP)
{
// Yes.
PDSURF pdsurf = (PDSURF)pso->dhsurf;
// Is the device bitmap currently in host memory?
if ( pdsurf->pso )
{
// Yes. Move it into off screen memory.
if ( !bCreateScreenFromDib(ppdev, pdsurf) )
{
// We couldn't move it to off-screen memory.
LogPaint(1, pso, mix, pco, pbo);
return EngPaint(pdsurf->pso, pco, pbo, pptlBrush, mix);
}
}
// The device bitmap now resides in off-screen memory.
// This is the offset to it.
ppdev->ptlOffset.x = pdsurf->ptl.x;
ppdev->ptlOffset.y = pdsurf->ptl.y;
}
else
{
// No, we are not painting to a device bitmap.
ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
}
//
// DrvPaint is most often called with
// mix 0D (PAT COPY) and mix 06 (DEST INVERT).
// It behooves us, therefore, to handle these as
// special cases... provided they aren't clipped.
//
if ((pco->iDComplexity != DC_COMPLEX))
{
// =================== PATCOPY ==================================
if (mix == 0x0D0D)
{
ASSERTMSG(pbo, "DrvPaint PATCOPY without a brush.\n");
if (pbo->iSolidColor != 0xFFFFFFFF) // Solid color
{
color = pbo->iSolidColor;
switch (ppdev->ulBitCount)
{
case 8: // For 8 bpp duplicate byte 0 into byte 1.
color |= (color << 8);
case 16: // For 8,16 bpp, duplicate the low word into the high word.
color |= (color << 16);
break;
}
REQUIRE(9);
LL_BGCOLOR(color, 0);
LL_DRAWBLTDEF(0x100700F0, 0);
LL_OP0(pco->rclBounds.left + ppdev->ptlOffset.x,
pco->rclBounds.top + ppdev->ptlOffset.y);
LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left),
(pco->rclBounds.bottom - pco->rclBounds.top));
LogPaint(0, pso, mix, pco, pbo);
return TRUE;
} // End PATCOPY with solid color.
else // PATCOPY with a brush.
{
DWORD bltdef = 0x1000;
if (SetBrush(ppdev, &bltdef, pbo, pptlBrush))
{
REQUIRE(7);
LL_DRAWBLTDEF((bltdef << 16) | 0x00F0, 0);
LL_OP0 (pco->rclBounds.left + ppdev->ptlOffset.x,
pco->rclBounds.top + ppdev->ptlOffset.y);
LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left) ,
(pco->rclBounds.bottom - pco->rclBounds.top) );
LogPaint(0, pso, mix, pco, pbo);
return TRUE;
}
} // End PATCOPY with a brush
} // End PATCOPY
// ======================= DEST INVERT ============================
else if (mix == 0x0606)
{
REQUIRE(7);
LL_DRAWBLTDEF(0x11000055, 0);
LL_OP0(pco->rclBounds.left + ppdev->ptlOffset.x,
pco->rclBounds.top + ppdev->ptlOffset.y);
LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left),
(pco->rclBounds.bottom - pco->rclBounds.top) );
LogPaint(0, pso, mix, pco, pbo);
return TRUE;
} // End DEST INVERT
} // End special cases
// First, convert the fg and bg mix into a fg and bg rop
fg_rop = Rop2ToRop3[ (mix & 0x0F) ]; // convert fg mix to fg rop.
bg_rop = Rop2ToRop3[ ((mix>>8) & 0x0F) ]; // convert bg mix to bg rop
rop4 = (bg_rop<<8) | fg_rop; // build rop4.
//
// Now convert Paint to BitBLT
//
LogPaint(2, pso, mix, pco, pbo);
DISPDBG((PAINT_DBG_LEVEL,"Drvpaint: Convert to DrvBitBlt().\n"));
return DrvBitBlt(pso, // Target
(SURFOBJ *) NULL, // Source
(SURFOBJ *) NULL, // Mask
pco, // Clip object
(XLATEOBJ *) NULL, // Xlate object
&(pco->rclBounds), // Dest rectangle.
(PPOINTL) NULL, // Src point.
(PPOINTL) NULL, // Mask point.
pbo, // Brush
pptlBrush, // Brush alignment
rop4); // ROP4
}
#if LOG_CALLS
// ============================================================================
//
// Everything from here down is for data logging and is not used in the
// production driver.
//
// ============================================================================
// ****************************************************************************
//
// LogPaint()
// This routine is called only from DrvPaint()
// Dump information to a file about what is going on in DrvPaint land.
//
// ****************************************************************************
void LogPaint(
int acc,
SURFOBJ* psoDest,
MIX mix,
CLIPOBJ* pco,
BRUSHOBJ* pbo)
{
PPDEV dppdev,sppdev,ppdev;
char buf[256];
int i;
BYTE fg_rop, bg_rop;
ULONG iDComplexity;
ppdev = (PPDEV) (psoDest ? psoDest->dhpdev : 0);
#if ENABLE_LOG_SWITCH
if (pointer_switch == 0) return;
#endif
i = sprintf(buf,"DrvPaint: ");
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
switch(acc)
{
case 0: // Accelerated
i = sprintf(buf, "ACCL ");
break;
case 1: // Punted
i = sprintf(buf,"PUNT host ");
break;
case 2: // Punted
i = sprintf(buf, "PUNT BitBlt ");
break;
default:
i = sprintf(buf, "PUNT unknown ");
break;
}
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
//
// Check the DEST
//
if (psoDest)
{
if (psoDest->iType == STYPE_DEVBITMAP)
{
i = sprintf(buf, "Id=%p ", psoDest->dhsurf);
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
if ( ((PDSURF)psoDest->dhsurf)->pso )
i = sprintf(buf,"DST=DH ");
else
i = sprintf(buf,"DST=DF ");
}
else if (psoDest->hsurf == ppdev->hsurfEng)
i = sprintf(buf,"DST=S ");
else
i = sprintf(buf,"DST=H ");
}
else
i = sprintf(buf,"DST=N ");
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
//
// Check the MIX
//
i = sprintf(buf,"MIX = 0x%04X ", mix);
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
//
// Check the type of clipping.
//
iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
i = sprintf(buf,"CLIP=%s ",
(iDComplexity==DC_TRIVIAL ? "T":
(iDComplexity == DC_RECT ? "R" : "C" )));
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
//
// Type of pattern.
//
if (pbo == NULL)
{
i = sprintf(buf,"BRUSH=N ");
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
}
else if (pbo->iSolidColor == 0xFFFFFFFF )
{
i = sprintf(buf,"BRUSH=P ");
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
}
else
{
i = sprintf(buf,"BRUSH=0x%08X ",(pbo->iSolidColor));
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
}
i = sprintf(buf,"\r\n");
WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
}
#endif