📄 pxa255_lcd.cpp
字号:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.
Module Name: pxa255_lcd.cpp
Date Created: 9/22/2003
Abstract:
Functions:
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <nkintr.h>
#include "pxa255.h"
#include "precomp.h"
#include "cursor.h"
#ifdef DO_DISPPERF
#include "dispperf.h"
#endif
#define NUM_FRAME_BUFFERS 1
extern "C" void DispDrvrSetPalette(const PALETTEENTRY *,USHORT,USHORT);
extern "C" void DisplayPageBuffer(int page);
extern "C" volatile LCD_PALETTE_T *v_pPaletteBuffer;
extern "C" BOOL bAllowOSFrameBufferUpdates;
extern "C" void ScrollBuffer(int direction);
extern "C" void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color);
extern "C" void DispDrvrDirtyRectDump_rectfill(LPCRECT prc,DWORD color);
extern "C" BOOL bDoRotation;
extern "C" BOOL gDrawCursorFlag;
extern "C" BOOL gUseDispDrvrPhysicalFrameBuffer;
extern "C" PBYTE gFrameBuffer; // pointer to first byte of screen memory
extern "C" volatile LCD_PALETTE_T *v_pPaletteBuffer;
extern "C" int gDibBufferWidth;
extern "C" int gDibBufferHeight;
// Function pointer to the caller's vertical blank interrupt processing function.
void (*fnVerticalBlankInterrupt)(int page);
#ifdef DD_ENABLE
DDGPE *pGPE = (DDGPE *)NULL;
#else // DD_ENABLE
static GPE *pGPE = (GPE *)NULL;
#endif // DD_ENABLE
// These masks are used to extract the color component for a 16 bit pixel value. 5 bits red, 6 bits green, 5 bits blue.
ulong BitMasks[] = {0xF800, 0x07E0, 0x001F};
INSTANTIATE_GPE_ZONES(0x3,"GDI Driver","unused1","unused2") /* Start with Errors, warnings, and temporary messages */
BOOL APIENTRY GPEEnableDriver(
ULONG iEngineVersion,
ULONG cj,
DRVENABLEDATA *pded,
PENGCALLBACKS pEngCallbacks);
BOOL APIENTRY DrvEnableDriver(
ULONG iEngineVersion,
ULONG cj,
DRVENABLEDATA *data,
PENGCALLBACKS pEngineCallbacks)
{
GPEEnableDriver(iEngineVersion,cj,data,pEngineCallbacks);
return (TRUE);
}
// List of supported modes
GPEMode g_ModeInfo[4];
int g_nNumModes = 0;
// Main entry point for a GPE-compliant driver
GPE *GetGPE(void)
{
if (!pGPE)
{
pGPE = new SA2Video();
}
return (pGPE);
}
BOOL SA2Video::IsrThreadProc()
{
return (TRUE);
}
DWORD LCDIsrThread(SA2Video *p)
{
p->IsrThreadProc();
return (0);
}
BOOL SA2Video::IsrThreadStart()
{
HANDLE hthrd;
hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)LCDIsrThread,this,0,NULL);
CloseHandle(hthrd);
return (TRUE);
}
VOID SA2Video::PowerHandler(BOOL bOff)
{
DispDrvrPowerHandler(bOff);
}
SA2Video::SA2Video(void)
{
DEBUGMSG(GPE_ZONE_INIT,(TEXT("SA2Video::SA2Video\r\n")));
// Determine the display type
// Setup the LCD controller for that display
// Power up and enable the display
DispDrvrInitialize();
// Allow the driver to use any of the popular resolutions that are
// smaller than it's physical display.
g_ModeInfo[0].modeId = 0;
g_ModeInfo[0].width = DispDrvr_cxScreen;
g_ModeInfo[0].height = DispDrvr_cyScreen;
g_ModeInfo[0].Bpp = bpp;
g_ModeInfo[0].frequency = 60;
g_ModeInfo[0].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
g_ModeInfo[1].modeId = 1;
g_ModeInfo[1].width = 176;
g_ModeInfo[1].height = 220;
g_ModeInfo[1].Bpp = bpp;
g_ModeInfo[1].frequency = 60;
g_ModeInfo[1].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
g_ModeInfo[2].modeId = 2;
g_ModeInfo[2].width = 240;
g_ModeInfo[2].height = 320;
g_ModeInfo[2].Bpp = bpp;
g_ModeInfo[2].frequency = 60;
g_ModeInfo[2].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
g_ModeInfo[3].modeId = 3;
g_ModeInfo[3].width = 320;
g_ModeInfo[3].height = 240;
g_ModeInfo[3].Bpp = bpp;
g_ModeInfo[3].frequency = 60;
g_ModeInfo[3].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
if (DispDrvr_cxScreen > 320)
{
g_nNumModes = 4;
}
else if (DispDrvr_cxScreen > 240)
{
g_nNumModes = 3;
}
else
{
g_nNumModes = 1;
}
}
SCODE SA2Video::SetMode(int modeId,HPALETTE *pPalette)
{
if (modeId < 0 || modeId >= g_nNumModes)
return (E_INVALIDARG);
// Select the appropriate mode
m_pMode = &g_ModeInfo[modeId];
m_nScreenWidth = m_pMode->width;
m_nScreenHeight = m_pMode->height;
#ifdef DD_ENABLE
m_pModeEx.modeInfo = g_ModeInfo[modeId];
#endif
if (!gUseDispDrvrPhysicalFrameBuffer)
{
// The GPE will allocate a virtual frame buffer and draw to that.
// The driver will copy this virtual frame buffer to the physical frame buffer
// using the dirty rectangle algorithm.
#ifdef DD_ENABLE
PVOID pMem = VirtualAlloc(NULL, 1024*1024*2, MEM_RESERVE, PAGE_NOACCESS);
pMem = VirtualAlloc(pMem, m_nScreenWidth * m_nScreenHeight * (bpp == 8 ? 1 : 2 ), MEM_COMMIT, PAGE_READWRITE);
m_pPrimarySurface = new DDGPESurf(m_nScreenWidth,m_nScreenHeight,pMem,m_nScreenWidth * (bpp == 8 ? 1 : 2),m_pMode->format);
#else
m_pPrimarySurface = new GPESurf(m_nScreenWidth,m_nScreenHeight,m_pMode->format);
#endif
// Clear the video memory
memset(m_pPrimarySurface->Buffer(),0,m_pPrimarySurface->Height()*m_pPrimarySurface->Width());
DispDrvrSetDibBuffer(m_pPrimarySurface->Buffer());
gDibBufferWidth = m_pPrimarySurface->Width();
gDibBufferHeight = m_pPrimarySurface->Height();
}
else
{
// The GPE will draw directly to the physical frame buffer.
m_pVirtualFrameBuffer = gFrameBuffer;
// Init the frame buffer to color pattern -
#ifdef DD_ENABLE
m_pPrimarySurface = new DDGPESurf(m_nScreenWidth,m_nScreenHeight,m_pVirtualFrameBuffer,
DispDrvr_cdwStride * 4,m_pMode->format);
#else
m_pPrimarySurface = new GPESurf(m_nScreenWidth,m_nScreenHeight,m_pVirtualFrameBuffer,
DispDrvr_cdwStride * 4,m_pMode->format);
#endif
}
// Here, we use EngCreatePalette to create a palette that that MGDI will use as a
// stock palette
if (pPalette)
{
*pPalette = EngCreatePalette(PAL_BITFIELDS,0,NULL,BitMasks[0],BitMasks[1],BitMasks[2]);
}
return (S_OK);
}
SCODE SA2Video::GetModeInfo(GPEMode *pMode,int modeNumber)
{
if (modeNumber < 0 || modeNumber >= g_nNumModes)
return (E_INVALIDARG);
*pMode = g_ModeInfo[modeNumber];
return (S_OK);
}
int SA2Video::NumModes(void)
{
return (g_nNumModes);
}
SCODE SA2Video::SetPointerShape(GPESurf *pMask,GPESurf *pColorSurf,int xHot,int yHot,int cX,int cY)
{
int row,colByte;
BYTE *pAND;
BYTE *pXOR;
BYTE bitMask;
unsigned i;
if (!pMask)
{ // Turn off the cursor.
memset((BYTE *)gCursorMask,0xFF,sizeof(gCursorMask));
memset((BYTE *)gCursorData,0x00,sizeof(gCursorData));
}
else
{
i=0;
for (row=0;row<cY;row++)
{
for (colByte=0;colByte<cX/8;colByte++)
{
pAND=(unsigned char *)pMask->Buffer()+(row*pMask->Stride())+colByte;
pXOR=pAND+(cY*pMask->Stride());
for (bitMask=0x0080;bitMask;bitMask>>=1)
{
gCursorMask[i] = (*pAND & bitMask) ? 0xFFFF : 0x0000;
gCursorData[i] = (*pXOR & bitMask) ? 0xFFFF : 0x0000;
i++;
}
}
}
gxHot=xHot;
gyHot=yHot;
}
return (S_OK);
}
SCODE SA2Video::MovePointer(int xPosition,int yPosition)
{
if (xPosition == -1)
{
// disable cursor
DispDrvrMoveCursor(DispDrvr_cxScreen,DispDrvr_cyScreen);
}
else
{
// enable cursor
DispDrvrMoveCursor(xPosition,yPosition);
}
return (S_OK);
}
void SA2Video::WaitForNotBusy(void)
{
return;
}
int SA2Video::IsBusy(void)
{
return (0); // Never busy as there is no acceleration
}
SCODE SA2Video::AllocSurface(GPESurf **surface,INT width,INT height,EGPEFormat format,INT surfaceFlags)
{
if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
{
// Can't allocate video-memory surfaces in the SA2Video environment
return (E_OUTOFMEMORY);
}
// Allocate from system memory
*surface = new GPESurf(width,height,format);
if (*surface != NULL)
{
// Check that the bits were allocated succesfully
if (((*surface)->Buffer()) == NULL)
{
delete *surface;
}
else
{
return (S_OK);
}
}
return (E_OUTOFMEMORY);
}
SCODE SA2Video::WrappedEmulatedLine(GPELineParms *pParms)
{
SCODE code = EmulatedLine(pParms); // Draw to the backup framebuffer
if (FAILED(code))
return (code);
// 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 = 2 + ((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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -