📄 ddi_if.cpp
字号:
// Drawing functionsBOOL APIENTRY DrvFillPath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, MIX mix, FLONG flOptions) // Simply winding mode - we ignore for now.{#ifdef DEBUG if( (GPE_ZONE_POLY) && !(GPE_ZONE_BLT_HI) ) { ulong oldSettings = dpCurSettings.ulZoneMask; dpCurSettings.ulZoneMask |= 0x0034; // enter, exit & blt hi and lo BOOL v = DrvFillPath(pso,ppo,pco,pbo,pptlBrushOrg,mix,flOptions); dpCurSettings.ulZoneMask = oldSettings; return v; }#endif DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Entering DrvFillPath\r\n"))); BOOL bFailed=false; EdgeList edgeList( ppo->cCurves ); int bMore; int moreClipLists; PATHDATA pd; ULONG cptfx; SCODE sc1=0; SCODE sc2; RECTL *prclCurr; GPEBltParms parms; int i; // FIX xFirst, yFirst, xLast, yLast; POINTFIX firstPoint, lastPoint; // Set up Blt parameters for GPEPolygon::Fill to use TmpGPESurf pDst(pso); GPE *pGPE = SurfobjToGPE(pso); parms.pDst = pDst; parms.pSrc = (GPESurf *)NULL; parms.pMask = (GPESurf *)NULL; parms.prclDst = (RECTL *)NULL; parms.prclMask = (RECTL *)NULL; parms.prclClip = (RECTL *)NULL; // while we prepare blt function parms.xPositive = parms.yPositive = 1; // we don't support overlapped brush & dst parms.pptlBrush = pptlBrushOrg; parms.bltFlags = 0; parms.rop4 = (((ROP4)gaMix[(mix>>8)&0x0f])<<8) | gaMix[mix&0x0f]; // mix -> rop4// parms.rop4 = 0; // TEMPORARY BLACKNESS parms.pBrush = (GPESurf *)NULL; parms.pLookup = (unsigned long *)NULL; parms.pConvert = NULL; parms.solidColor = pbo->iSolidColor; if( pbo ) { if( pbo->iSolidColor == 0xffffffff ) { if( pbo->pvRbrush == NULL ) parms.pBrush = (GPESurf *)( BRUSHOBJ_pvGetRbrush( pbo ) ); else parms.pBrush = (GPESurf *)( pbo->pvRbrush ); } } if( FAILED( pGPE->BltPrepare( &parms ) ) ) { DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Failed to prepare blt for fillpoly operations\r\n"))); DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvFillPath\r\n"))); return FALSE; } // Create GPEPolygon(s) for the path PATHOBJ_vEnumStart(ppo); do { bMore = PATHOBJ_bEnum( ppo, &pd ); cptfx = pd.count; if( !cptfx ){ break; } if( pd.flags & PD_BEGINSUBPATH ){ // Start a new subpath - just remember the first point firstPoint = pd.pptfx[0]; } else { // Continue old subpath if FAILED(edgeList.AddEdge( lastPoint.x, lastPoint.y, pd.pptfx[0].x, pd.pptfx[0].y )){ bMore=false; bFailed=true; } } for( i=0; i<((int)cptfx)-1; i++ ){ if FAILED(edgeList.AddEdge( pd.pptfx[i].x, pd.pptfx[i].y, pd.pptfx[i+1].x, pd.pptfx[i+1].y )){ bMore=false; //The reason we don't return an error immediately is that bFailed=true; //we used to draw a partial path. For BC we will continue to. } } if( pd.flags & PD_ENDSUBPATH ){ // close the subpath if FAILED(edgeList.AddEdge( pd.pptfx[i].x, pd.pptfx[i].y, firstPoint.x, firstPoint.y )){ bMore=false; bFailed=true; } }else{ // continue this subpath with next enumeration lastPoint = pd.pptfx[i]; } } while(bMore); // Now, loop through the cliprect(s), calling GPEPolygon::Fill (via GPEPolygonList) if( ( pco == NULL ) || ( pco->iDComplexity == DC_TRIVIAL ) ) { DEBUGMSG(GPE_ZONE_POLY,(TEXT("Calling PolygonList::Fill() with no clipping\r\n"))); sc1 = edgeList.Fill( &parms, (RECTL *)NULL, pGPE); } else if( pco->iDComplexity == DC_RECT ) { DEBUGMSG(GPE_ZONE_POLY,(TEXT("Calling PolygonList::Fill() with single cliprect\r\n"))); sc1 = edgeList.Fill( &parms, &pco->rclBounds, pGPE ); } else { DEBUGMSG(GPE_ZONE_POLY,(TEXT("Iterating through complex clipping for fillpoly\r\n"))); CLIPENUM ce; for( ce.c = 0, moreClipLists=1; ce.c || moreClipLists; ) // <- Note , & ; { if( ce.c == 0 ) { // Get next list of cliprects from clipobj DEBUGMSG(GPE_ZONE_POLY,(TEXT("Calling CLIPOBJ_bEnum\r\n"))); moreClipLists = CLIPOBJ_bEnum( pco, sizeof(ce), (ULONG *)&ce ); prclCurr = ce.arcl; if( !ce.c ) // empty list !? continue; } ce.c--; DEBUGMSG(GPE_ZONE_POLY,(TEXT("Calling PolygonList::Fill() with complex cliprect\r\n"))); if( FAILED(sc1 = edgeList.Fill( &parms, prclCurr++, pGPE ) ) ) break; } } sc2 = pGPE->BltComplete( &parms ); return ((!FAILED(sc1)) && (!FAILED(sc2)) && (!bFailed));}BOOL APIENTRY DrvRealizeBrush( BRUSHOBJ *pbo, SURFOBJ *psoTarget, SURFOBJ *psoPattern, SURFOBJ *psoMask, XLATEOBJ *pxlo, ULONG iHatch){ DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Entering DrvRealizeBrush\r\n"))); TmpGPESurf tpSrc(psoPattern); TmpGPESurf tpTrg(psoTarget,psoPattern,&tpSrc); GPESurf *pSrc = tpSrc; GPESurf *pTrg = tpTrg; GPESurf *pDst; void *pBits; unsigned long stride; EGPEFormat patFormat = (pTrg->Format() == gpe24Bpp) ? gpe32Bpp : pTrg->Format(); int temporaryPattern = (( pSrc->Format() != patFormat ) || (pxlo->flXlate != XO_TRIVIAL ) ); // If the Target is 24Bpp, we convert the brush to 32Bpp because the EmulatedBlt routine // doesn't handle 24Bpp patterns (they cross 32-bit boundaries and this requires // extra code) // If the pattern and target have different formats, we need to create a GPESurf to // contain the pattern but since GDI destroys the brush without notifying the driver, // the bits associated with the pattern surface must be in the same memory allocation // to avoid memory leaks. int memoryRequired = sizeof(GPESurf); if( temporaryPattern ) { stride = ((( pSrc->Width() * EGPEFormatToBpp[patFormat] + 7 ) / 8 + 3 ) & 0xfffffffc ); memoryRequired += stride * pSrc->Height(); } else stride = pSrc->Stride(); pDst = (GPESurf *)BRUSHOBJ_pvAllocRbrush( pbo, memoryRequired ); if( !pDst ) return FALSE; // memory allocation failed if( temporaryPattern ) pBits = (void *)((unsigned long)(((unsigned char *)pDst)+sizeof(GPESurf)+3)&0xfffffffc); else pBits = pSrc->Buffer(); pDst->Init( pSrc->Width(), pSrc->Height(), pBits, stride, patFormat ); if( temporaryPattern ) { GPEBltParms parms; // Create a color converter to handle depth changes ColorConverter::InitConverter( pxlo, &parms.pColorConverter, &parms.pConvert, &parms.pLookup ); // Blt the bits to the temporary pattern buffer RECTL rcl; rcl.top = 0; rcl.bottom = pSrc->Height(); rcl.left = 0; rcl.right = pSrc->Width(); parms.pDst = pDst; parms.pSrc = pSrc; parms.pMask = (GPESurf *)NULL; parms.pBrush = (GPESurf *)NULL; parms.prclDst = &rcl; parms.prclSrc = &rcl; parms.prclClip = (RECTL *)NULL; parms.solidColor = 0xffffffff; parms.bltFlags = 0; parms.rop4 = 0xCCCC; // SRCCOPY parms.prclMask = (RECTL *)NULL; parms.pptlBrush = (POINTL *)NULL; parms.xPositive = parms.yPositive = 1; SurfobjToGPE(psoTarget)->EmulatedBlt( &parms ); } DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvRealizeBrush\r\n"))); return TRUE;}typedef struct _DRVDEVMODEW{ DEVMODEW devmodew; // DDI definition of mode GPEMode gpeMode; // GPE definition of mode} DRVDEVMODEW;ULONG APIENTRY DrvGetModes( HANDLE hDriver, ULONG cjSize, DEVMODEW *pdm){ DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Entering DrvGetModes\r\n"))); GPE *pGPE = GetGPE(); int numModes = pGPE->NumModes(); ULONG bytesReqd = numModes * sizeof(DRVDEVMODEW); DRVDEVMODEW *pMode = (DRVDEVMODEW *)pdm; GPEMode *pGPEMode; int modeNo; if( !pdm ) { // GDI is asking how much memory is required for the entire mode list DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvGetModes\r\n"))); return bytesReqd; } if( cjSize != bytesReqd ) { DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvGetModes\r\n"))); return 0; // In this DDI, we insist that GDI gives 0 or sizeof(modelist) } memset( pMode, 0, cjSize ); for( modeNo = 0; modeNo < numModes; modeNo++, pMode++ ) { pGPEMode = &(pMode->gpeMode); pGPE->GetModeInfo( pGPEMode, modeNo ); memcpy( &(pMode->devmodew.dmDeviceName), TEXT("GPE"), 8 ); pMode->devmodew.dmSize = sizeof(DEVMODEW); pMode->devmodew.dmDriverExtra = sizeof(GPEMode); pMode->devmodew.dmFields = ( DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ); pMode->devmodew.dmBitsPerPel = pGPEMode->Bpp; pMode->devmodew.dmPelsWidth = pGPEMode->width; pMode->devmodew.dmPelsHeight = pGPEMode->height; pMode->devmodew.dmDisplayFrequency = pGPEMode->frequency; } DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvGetModes\r\n"))); return cjSize;}DHPDEV APIENTRY DrvEnablePDEV( DEVMODEW *pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF *phsurfPatterns, ULONG cjCaps, ULONG *pdevcaps, ULONG cjDevInfo, DEVINFO *pdi, HDEV hdev, LPWSTR pwszDeviceName, HANDLE hDriver){ // Make pGPE static to allow this func to be called more than once static GPE *pGPE; DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Entering DrvEnablePDEV\r\n"))); // Only initialize display driver once. This may be called again by // printer drivers that leave most of the rendering to GPE. if( pGPE == NULL ) { if( ( pGPE = GetGPE() ) == NULL ) { DEBUGMSG(GPE_ZONE_ERROR,(TEXT("ERROR: Failed to instantiate GPE object\r\n"))); DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvEnablePDEV\r\n"))); return (DHPDEV)NULL; } if( !AllocConverters() ) { DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Failed Allocate color converters! Leaving DrvEnablePDEV\r\n"))); return (DHPDEV)NULL; } if( FAILED( pGPE->SetMode( ((DRVDEVMODEW *)pdm)->gpeMode.modeId, &(pdi->hpalDefault) ) ) ) { DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Failed to set mode! Leaving DrvEnablePDEV\r\n"))); return (DHPDEV)NULL; } } GDIINFO *pgdiinfo = (GDIINFO *)pdevcaps; pgdiinfo->ulVersion = DDI_DRIVER_VERSION; pgdiinfo->ulTechnology = DT_RASDISPLAY; pgdiinfo->ulHorzSize = 64; pgdiinfo->ulVertSize = 60; pgdiinfo->ulHorzRes = pdm->dmPelsWidth; pgdiinfo->ulVertRes = pdm->dmPelsHeight; pgdiinfo->ulLogPixelsX = 96; pgdiinfo->ulLogPixelsY = 96; pgdiinfo->cBitsPixel = pdm->dmBitsPerPel; pgdiinfo->cPlanes = 1; pgdiinfo->ulNumColors = 1 << pdm->dmBitsPerPel; pgdiinfo->ulAspectX = 1; pgdiinfo->ulAspectY = 1; pgdiinfo->ulAspectXY = 1; pgdiinfo->flRaster = RC_BITBLT | RC_STRETCHBLT | ((pGPE->IsPaletteSettable())?RC_PALETTE:0); // DEVINFO Graphics capabilities beyond normal uDDI caps; eg, grayscale text output pdi->flGraphicsCaps = pGPE->GetGraphicsCaps(); DEBUGMSG(1,(TEXT("Bits-per-pixel: %d\r\n"), pgdiinfo->cBitsPixel )); DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvEnablePDEV\r\n"))); return (DHPDEV)pGPE;} // BLT Functions// All exposed Drv Blt functions are translated into a call to// AnyBlt directly or indirectly:BOOL APIENTRY AnyBlt( SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, RECTL *prclSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 rop4, unsigned long bltFlags);BOOL APIENTRY DrvPaint(SURFOBJ* pso,CLIPOBJ* pco,BRUSHOBJ* pbo,POINTL* pptlBrush,MIX mix){ DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Entering DrvPaint\r\n"))); DEBUGMSG(GPE_ZONE_ENTER,(TEXT("DrvPaint (mix=0x%04x)\r\n"), mix)); BOOL rc; ROP4 rop4; rop4 = (((ROP4)gaMix[(mix >> 8)&0xf]) << 8) | gaMix[mix & 0xf]; // Since our DrvFillPath routine handles almost all fills, DrvPaint // won't get called all that much (mainly via PaintRgn, FillRgn, or // complex clipped polygons). As such, we save some code and simply // allow DrvBitBlt to handle it: rc = DrvBitBlt(pso, NULL, NULL, pco, NULL, &pco->rclBounds, NULL, NULL, pbo, pptlBrush, rop4 ); DEBUGMSG(GPE_ZONE_ENTER,(TEXT("Leaving DrvPaint\r\n"))); return rc;}BOOL APIENTRY DrvCopyBits( SURFOBJ *psoDest, SURFOBJ *psoSrc,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -