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 + -
显示快捷键?