⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddi_if.cpp

📁 windows ce 3.00 嵌入式操作系统源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Drawing functions

BOOL 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 + -