wrap8bpp.cpp

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 466 行

CPP
466
字号
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright (c) 1997  Microsoft Corporation

Module Name:  

    wrap8bpp.cpp

Abstract:  


Functions:


Notes:


--*/
#include "precomp.h"
#include "cursor.h"

INSTANTIATE_GPE_ZONES(0x3,"GDI Driver","unused1","unused2")	 /* Start with Errors, warnings, and temporary messages */

ULONG * r;
PENGCALLBACKS r2;

BOOL APIENTRY GPEEnableDriver(          // This gets around problems exporting from .lib
	ULONG          iEngineVersion,
	ULONG          cj,
	DRVENABLEDATA *pded,
	PENGCALLBACKS  pEngCallbacks);

BOOL APIENTRY DrvEnableDriver(
	ULONG          iEngineVersion,
	ULONG          cj,
	DRVENABLEDATA *pded,
	PENGCALLBACKS  pEngCallbacks)
{	

	BOOL result;
	result = GPEEnableDriver( iEngineVersion, cj, pded, pEngCallbacks );
	
	// This portion of code is added to get around the buggy call to EngCreatePalette 
	// inside Wrap8bpp:SetMode().
	// This part gets the addresses of the function calls on the stack
	DEBUGMSG( GPE_ZONE_INIT,(TEXT("DrvEnableDriver:iEngineVersion = %x\r\n"), iEngineVersion));
	DEBUGMSG( GPE_ZONE_INIT,(TEXT("DrvEnableDriver:cj = %x\r\n"), cj));
	DEBUGMSG( GPE_ZONE_INIT,(TEXT("DrvEnableDriver:pded = %x\r\n"), pded));

	DEBUGMSG( GPE_ZONE_INIT,(TEXT("DrvEnableDriver:pEngCallbacks = %x\r\n"), pEngCallbacks));
	r = (ULONG *)pEngCallbacks;
	r2 = pEngCallbacks;
	for ( int i =0; i < 13; i ++)
	{
		DEBUGMSG( GPE_ZONE_INIT,(TEXT("pEngCallbacks[%d] = %x\r\n"), i, r[i]));
	}
	// End of added section

	return result;
}

#include "palette.h"
INSTANTIATE_PALETTE

static GPE *pGPE = (GPE *)NULL;
// Main entry point for a GPE-compliant driver
GPE *GetGPE()
{

	if( !pGPE )
		pGPE = new Wrap8bpp();
	return pGPE;
}


Wrap8bpp::Wrap8bpp()
{

	DEBUGMSG( GPE_ZONE_INIT,(TEXT("Wrap8bpp::Wrap8bpp\r\n")));
	DispDrvrInitialize();	// call entry point to 8bpp GDI driver

	// When this DispDrvrInitialize returns, DispDrvrPhysicalFrameBuffer contains
	// the physical address of the screen if it is in 8bpp DIB format. - Alternatively it
	// is NULL - in which case this is a "dirty-rect" driver

	m_ModeInfo.modeId = 0;
	m_ModeInfo.width = m_nScreenWidth =	DispDrvr_cxScreen;
	m_ModeInfo.height = m_nScreenHeight = DispDrvr_cyScreen;
	m_ModeInfo.Bpp = 8;
	m_ModeInfo.frequency = 60;		// not too important
	m_ModeInfo.format = gpe8Bpp;

	m_pMode = &m_ModeInfo;
	

	if( DispDrvrPhysicalFrameBuffer == NULL )
	{
		// it is a "dirty-rect" driver - we create a system memory bitmap to represent
		// the screen and refresh rectangles of this to the screen as they are altered
		m_pPrimarySurface = new GPESurf( m_nScreenWidth, m_nScreenHeight, gpe8Bpp );

		DispDrvrSetDibBuffer( m_pPrimarySurface->Buffer() );
	}
	else
	{
		// The hardware is arranged as a DIB
		// Map it into virtual addr space
		unsigned long fbSize = DispDrvr_cxScreen * DispDrvr_cdwStride * 4;
		m_pVirtualFrameBuffer = VirtualAlloc( 0, fbSize, MEM_RESERVE, PAGE_NOACCESS );
		VirtualCopy( m_pVirtualFrameBuffer, DispDrvrPhysicalFrameBuffer, fbSize,
			PAGE_READWRITE | PAGE_NOCACHE );
			
		m_pPrimarySurface = new GPESurf( m_nScreenWidth, m_nScreenHeight, m_pVirtualFrameBuffer,
			 DispDrvr_cdwStride * 4, gpe8Bpp );
	}
}

SCODE Wrap8bpp::SetMode( int modeId, HPALETTE *pPalette )
{

	if( modeId != 0 )
		return E_INVALIDARG;

	if( pPalette )
	{	
		*pPalette = 
			// EngCreatePalette ---- This original function call causes the system to
			// execute the data section of the memory map
			// Below, by grabbing the EngCreatePalette's stack address, we managed to overcome 
			// the above problem.
		  (* r2->EngCreatePalette)	(
								PAL_INDEXED,
								PALETTE_SIZE, 	// i.e. 256
								(ULONG *)_rgbIdentity,
								0,
								0,
								0
							); 

		DEBUGMSG(1,(TEXT("Created 8 Bpp palette, handle = 0x%08x\r\n"),*pPalette));
	
	  }

	return S_OK;				// Mode is inherently set
}

SCODE Wrap8bpp::GetModeInfo
(
	GPEMode *pMode,
	int modeNo
)
{
	if( modeNo != 0 )
		return E_INVALIDARG;

	*pMode = m_ModeInfo;

	return S_OK;
}

int Wrap8bpp::NumModes()
{
	return 1;
}

//  pMask points to a one bpp surface with a width of cx and a height of (2 x cy). 
//	The top half defines the AND mask for the pointer while the lower half defines the XOR mask. 
//	Taken together, these masks provide two bits of information for each pixel of the pointer image.
//	The image data (arrow, hourglass) is then stored into two DWORD arrays, gCursorMask and gCursorData. 
//	The image is 32 x 32 bytes, or 32 x 32 pixels.
SCODE Wrap8bpp::SetPointerShape(
	GPESurf *pMask,
	GPESurf *pColorSurf,
	int xHot,
	int yHot,
	int cx,
	int cy )
{

	int		i, row, col;
	int		bitMask;
	BYTE	bAND;
	BYTE	bXOR;
	PBYTE	pCM;
	PBYTE	pCD;
	
	DEBUGMSG( GPE_ZONE_CURSOR,
			  (TEXT("Wrap8bpp::SetPointerShape(0x%X, 0x%X, %d, %d, %d, %d)\r\n"),
			  pMask, pColorSurf, xHot, yHot, cx, cy));

	if (!pMask ) {
		// If no mask is provided, turn off the cursor.
		DEBUGMSG (GPE_ZONE_CURSOR, (TEXT("SetPointerShape OFF\r\n")));
		memset (gCursorMask, 0xFF, sizeof(gCursorMask));
		memset (gCursorData, 0x00, sizeof(gCursorData));
	} else {
		DEBUGMSG (GPE_ZONE_CURSOR, (TEXT("SetPointerShape ON\r\n")));
		// One row at a time 
		for (row=0; row < 32; row++) {
			pCM = (PBYTE)(gCursorMask+(row*CURSOR_XSIZE/4));
			pCD = (PBYTE)(gCursorData+(row*CURSOR_XSIZE/4));
			// Clear the row first
			memset (pCM, 0xFF, (CURSOR_XSIZE));
			memset (pCD, 0x00, (CURSOR_XSIZE));
			if (row < (cy)) {
				// cx = cy = 32 every time
				for (col=0; col < cx/8; col++) {
					bAND = ((unsigned char *)pMask->Buffer()+row*pMask->Stride())[col];
					bXOR = ((unsigned char *)pMask->Buffer()+(cy+row)*pMask->Stride())[col];
					// Write in 8 bytes at a time
					for (bitMask=0x0080, i=0; i < 8; bitMask >>=1, i++) {
						pCM[col*8+i] = bAND & bitMask ? 0xFF : 0x00;
						pCD[col*8+i] = bXOR & bitMask ? 0xFF : 0x00;
					}
				}
			}
		}
		
		gxHot = xHot;
		gyHot = yHot;
	}
	return S_OK;
}

//	This function is called each time the cursor position needs to be moved, or hidden
//	If the O/S passes a -1 for x, the cursor will be hidden at the bottom-right of the screen
SCODE Wrap8bpp::MovePointer(
	int x,
	int y )
{
	DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("Wrap8bpp::MovePointer\r\n")));
	DEBUGMSG(GPE_ZONE_CURSOR,(TEXT("Moving cursor to %d,%d\r\n"), x, y ));
	
	if (x == -1)
	{
		DispDrvrMoveCursor(DispDrvr_cxScreen, DispDrvr_cyScreen);	// disable cursor
	}
	else
	{
		DispDrvrMoveCursor(x,y);
	}
	return S_OK;
}

void Wrap8bpp::WaitForNotBusy()
{
	return;
}

int Wrap8bpp::IsBusy()
{
	return 0;	// Never busy as there is no acceleration
}

void Wrap8bpp::GetPhysicalVideoMemory
(
	unsigned long *pPhysicalMemoryBase,
	unsigned long *pVideoMemorySize
)
{
	*pPhysicalMemoryBase = (unsigned long)DispDrvrPhysicalFrameBuffer;
	*pVideoMemorySize = DispDrvr_cdwStride * DispDrvr_cyScreen * 4;
}


SCODE Wrap8bpp::AllocSurface(
	GPESurf **ppSurf,
	int width,
	int height,
	EGPEFormat format,
	int surfaceFlags )
{
	if( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY )
		return E_OUTOFMEMORY;	// Can't allocate video-memory surfaces in the Wrap8bpp environment
	// Allocate from system memory
	DEBUGMSG(GPE_ZONE_CREATE,(TEXT("Creating a GPESurf in system memory. EGPEFormat = %d\r\n"), (int)format ));
	*ppSurf = new GPESurf( width, height, format );
	if( *ppSurf )
	{
		// check we allocated bits succesfully
		if( !((*ppSurf)->Buffer()) )
			delete *ppSurf;	// and then return E_OUTOFMEMORY
		else
			return S_OK;
	}
	return E_OUTOFMEMORY;
}

SCODE Wrap8bpp::WrappedEmulatedLine( GPELineParms *pParms )
{
	SCODE sc = EmulatedLine( pParms );	// Draw to the backup framebuffer

	if( FAILED(sc) )
		return sc;

	// Now, calculate the dirty-rect to refresh to the actual hardware
	RECT bounds;

	int N_plus_1;			// Minor length of bounding rect + 1

	if( pParms->dN )	// The line has a diagonal component (we'll refresh the bounding rect)
		N_plus_1 = 1 + ( ( pParms->cPels * pParms->dN ) / pParms->dM );
	else
		N_plus_1 = 1;

	switch( pParms->iDir )
	{
		case 0:
			bounds.left = pParms->xStart;
			bounds.top = pParms->yStart;
			bounds.right = pParms->xStart + pParms->cPels + 1;
			bounds.bottom = bounds.top + N_plus_1;
			break;
		case 1:
			bounds.left = pParms->xStart;
			bounds.top = pParms->yStart;
			bounds.bottom = pParms->yStart + pParms->cPels + 1;
			bounds.right = bounds.left + N_plus_1;
			break;
		case 2:
			bounds.right = pParms->xStart + 1;
			bounds.top = pParms->yStart;
			bounds.bottom = pParms->yStart + pParms->cPels + 1;
			bounds.left = bounds.right - N_plus_1;
			break;
		case 3:
			bounds.right = pParms->xStart + 1;
			bounds.top = pParms->yStart;
			bounds.left = pParms->xStart - pParms->cPels;
			bounds.bottom = bounds.top + N_plus_1;
			break;
		case 4:
			bounds.right = pParms->xStart + 1;
			bounds.bottom = pParms->yStart + 1;
			bounds.left = pParms->xStart - pParms->cPels;
			bounds.top = bounds.bottom - N_plus_1;
			break;
		case 5:
			bounds.right = pParms->xStart + 1;
			bounds.bottom = pParms->yStart + 1;
			bounds.top = pParms->yStart - pParms->cPels;
			bounds.left = bounds.right - N_plus_1;
			break;
		case 6:
			bounds.left = pParms->xStart;
			bounds.bottom = pParms->yStart + 1;
			bounds.top = pParms->yStart - pParms->cPels;
			bounds.right = bounds.left + N_plus_1;
			break;
		case 7:
			bounds.left = pParms->xStart;
			bounds.bottom = pParms->yStart + 1;
			bounds.right = pParms->xStart + pParms->cPels + 1;
			bounds.top = bounds.bottom - N_plus_1;
			break;
		default:
			DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Invalid direction: %d\r\n"),pParms->iDir));
			return E_INVALIDARG;
	}

	DispDrvrDirtyRectDump( (LPRECT)&bounds );

	return sc;
}
   
			  
SCODE Wrap8bpp::Line(
	GPELineParms *pLineParms,
	EGPEPhase phase )
{
	DEBUGMSG(GPE_ZONE_LINE,(TEXT("Wrap8bpp::Line\r\n")));

	if( phase == gpeSingle || phase == gpePrepare )
	{
		if( ( pLineParms->pDst != m_pPrimarySurface ) || ( DispDrvrPhysicalFrameBuffer != NULL ) )
			pLineParms->pLine = EmulatedLine;
		else
			pLineParms->pLine = (SCODE (GPE::*)(struct GPELineParms *))WrappedEmulatedLine;
	}
	return S_OK;
}

#undef SWAP
#define SWAP(type,a,b) { type tmp; tmp=a; a=b; b=tmp; }

SCODE Wrap8bpp::WrappedEmulatedBlt( GPEBltParms *pParms )
{
	SCODE sc = EmulatedBlt( pParms );	// Draw to the backup framebuffer

	if( FAILED(sc) )
		return sc;

	// Now, calculate the dirty-rect to refresh to the actual hardware
	RECT bounds;

	bounds.left = pParms->prclDst->left;
	bounds.top = pParms->prclDst->top;
	bounds.right = pParms->prclDst->right;
	bounds.bottom = pParms->prclDst->bottom;

	if( bounds.left > bounds.right )
	{
		SWAP( int, bounds.left, bounds.right )
	}
	if( bounds.top > bounds.bottom )
	{
		SWAP( int, bounds.top, bounds.bottom )
	}

	DispDrvrDirtyRectDump( (LPRECT)&bounds );

	return sc;
}


SCODE Wrap8bpp::BltPrepare(
	GPEBltParms *pBltParms )
{
	DEBUGMSG(GPE_ZONE_LINE,(TEXT("Wrap8bpp::BltPrepare\r\n")));

	if( ( pBltParms->pDst != m_pPrimarySurface ) || ( DispDrvrPhysicalFrameBuffer != NULL ) )
		pBltParms->pBlt = EmulatedBlt;
	else
		pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *))WrappedEmulatedBlt;

	return S_OK;
}

// This function would be used to undo the setting of clip registers etc
SCODE Wrap8bpp::BltComplete( GPEBltParms *pBltParms )
{
	return S_OK;
}

int Wrap8bpp::InVBlank()
{
	return 0;
}

SCODE Wrap8bpp::SetPalette
(
	const PALETTEENTRY *src,
	unsigned short firstEntry,
	unsigned short numEntries
)
{
	return S_OK;
}

void RegisterDDHALAPI()
{
	;	// No DDHAL support in wrapper
}

ulong BitMasks[] = { 0x0001,0x0002,0x0000 };

ULONG *APIENTRY DrvGetMasks(
    DHPDEV     dhpdev)
{
	return BitMasks;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?