I've been given a unfinished printer driver to try to fix, unfortunately I've
never worked on a driver, GDI, or windows before. In a call to DrvBitBlt, the
Dest surface is my device managed surface, the source surface contains the
correct image (in this case a piece of text from a pdf that is been sent as
an image because we don't have the correct font), and Rop4=0x8888. The code
for handling BitBlt currently doesn't support Rops that use the destination
so we punt back to GDI(EngBitBlt). the output from copybits is a black image.
If I replace the Rop value with 0xCCCC, and then call EngBitBlt, I get the
correct output. I was wondering: What exactly causes the problem.
Various things I have read on the net mention that you must use a Engine
Managed Surface when you call the Eng functions, is this true? Because if I
replace the Rop4 value I get the correct result.
My idea to fix it involves creating a engine managed surface alongside my
device surface in DrvEnableSurface, store it in my driver, and then use the
eng surface when I call EngBitBlt. the problem is that DrvCopyBits is then
never called,
The code for creating the surface is
HSURF PDevObj::doCreateSurface()
{
SIZEL SurfSize;
HSURF surf;
//HBITMAP bitmap;
FLONG hooks= HOOK_BITBLT |
HOOK_COPYBITS |
HOOK_FILLPATH |
HOOK_LINETO |
HOOK_STRETCHBLT |
HOOK_STRETCHBLTROP |
HOOK_STROKEANDFILLPATH |
HOOK_STROKEPATH |
HOOK_TEXTOUT;
GDI_MESSAGE("doCreateSurface\n");
SurfSize.cx = (LONG)ourGDIInfo.ulHorzRes;
SurfSize.cy = (LONG)ourGDIInfo.ulVertRes;
ourSurf = (HSURF)EngCreateDeviceSurface((DHSURF)ownerPDev, SurfSize,
BMF_24BPP);
//Create Engine Managed Surface for punting
engSurf = EngCreateBitmap(SurfSize, 3 * SurfSize.cy, BMF_24BPP,
BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
GDI_ASSERT((ourSurf != NULL));
if (ourSurf == NULL)
return NULL;
if (!EngAssociateSurface((HSURF)engSurf, (HDEV)engPDev, hooks))
{
surf = (HSURF)engSurf;
doDeleteSurface();
EngDeleteSurface(surf);
GDI_MESSAGE("doCreateSurface - EngAssociateSurface failed for Eng
Managed Surface\n");
return NULL;
}
/* HOOK_xxx values must match those in the DrvFuncTable */
if (!EngAssociateSurface(ourSurf, (HDEV)engPDev, hooks))
{
surf = ourSurf;
doDeleteSurface();
EngDeleteSurface(surf);
GDI_MESSAGE("doCreateSurface - EngAssociateSurface failed\n");
return NULL;
}
return ourSurf;
}
This is the version of DrvBitBlt I am using
BOOL
DrvBitBlt(
SURFOBJ *psoDst,
SURFOBJ *psoSrc,
SURFOBJ *psoMask,
CLIPOBJ *pco,
XLATEOBJ *pxlo,
PRECTL prclDst,
PPOINTL pptlSrc,
PPOINTL pptlMask,
BRUSHOBJ *pbo,
PPOINTL pptlBrushOrg,
ROP4 Rop4
)
{
bool ret;
IPDevObj *pPDevObj = GDISurface_getPDevObj(psoDst);
SURFOBJ *pso;
if (psoDst->iType == STYPE_BITMAP)
return FALSE;
pPDevObj = GDISurface_getPDevObj(psoDst);
if (pPDevObj == NULL)
return FALSE;
GDI_MESSAGE_LOGGER(pPDevObj->getLogger(), "DrvBitBlt\n");
if (pPDevObj->bitBlt(psoSrc, psoMask, pco, pxlo, prclDst, pptlSrc,
pptlMask, pbo, pptlBrushOrg, Rop4))
return TRUE;
/* Couldn't do it so punt */
pso = EngLockSurface((HSURF)pPDevObj->engSurf);
ret = EngBitBlt(pso, psoSrc, psoMask, pco, pxlo, prclDst, pptlSrc,
pptlMask, pbo, pptlBrushOrg, Rop4);
EngUnlockSurface(pso);
return ret;
}
I added the EngLockSurface and EngUnlockSurface lines, and modified the
EngBitBlt to use the locked surface instead of psoDst.
In this case pDevObj->bitBlt will return false.
Any help will be appreciated (if in Sydney, Australia I will buy you a beer).
If I have posted this in the wrong place, could you tell me where I should
have posted?