📄 dispdrvr.c
字号:
dstStep = DispDrvr_cyScreen*bytesPerPixel; //portrait frame buffer step
srcMarginWidth2 = DispDrvr_cxScreen* bytesPerPixel + ((xRight-xLeft)) ;
dstMarginWidth2 = (xRight-xLeft)*dstStep/bytesPerPixel;
}
pSrcBuf = gDibBuffer +srcStartRow +xLeft;
EnterCriticalSection(&displayMutex);
if (bDoRotation)
{
for (row = yTop;row < yBottom;row++)
{
i=srcWidthB;
while (i > 0)
{
if (i<4 || ((unsigned)pDstBuf & 0x3) || ((unsigned)pSrcBuf & 0x3))
{
*pDstBuf++ = *pSrcBuf;
pSrcBuf++;
i-=1;
}
else
{
*(unsigned *)pDstBuf = *(unsigned *)pSrcBuf;
pDstBuf+=4;
pSrcBuf+=4;
i-=4;
}
}
pSrcBuf += srcMarginWidth;
pDstBuf += dstMarginWidth;
}
}
else
{
DirtyRectDumpPortraitLoop_C_rectfill(pDstBuf,
srcColor,
yTop,
yBottom,
srcWidthB,
bytesPerRow,
bytesPerPixel,
srcMarginWidth,
dstMarginWidth);
}
// Cursor update request?.
if (gDrawCursorFlag &&
gCursorRect.left*bytesPerPixel < xRight && gCursorRect.right*bytesPerPixel > xLeft &&
(DWORD)gCursorRect.top < yBottom && (DWORD)gCursorRect.bottom > yTop)
{
DWORD srcRowMarginB;
DWORD cursorSizeXB;
yTop=gCursorRect.top;
// Clip off cursor if past bottom of screen
yBottom = gCursorRect.bottom > gDibBufferHeight ? gDibBufferHeight : gCursorRect.bottom;
// Now clip off cursor if past right side of screen
clipWidthB=gCursorRect.right > gDibBufferWidth ? gCursorRect.right -gDibBufferWidth : 0;
clipWidthB*=bytesPerPixel;
xLeft=gCursorRect.left*bytesPerPixel;
cursorWidthB=CURSOR_XSIZE*bytesPerPixel;
cursorSizeXB=(gCursorRect.right - gCursorRect.left)*bytesPerPixel;
srcWidthB=cursorSizeXB - clipWidthB;
srcRowMarginB = cursorWidthB - cursorSizeXB;
if (bDoRotation)
{
srcStartRow = 0;
srcMarginWidth = 0;
dstStartRow = yTop * bytesPerRow;
dstMarginWidth = bytesPerRow-srcWidthB;
pDstBuf = gFrameBuffer + dstStartRow + xLeft;
}
else
{
srcStartRow = (yBottom-yTop-1) * cursorWidthB;
srcMarginWidth = (yBottom-yTop) * cursorWidthB;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop))*bytesPerPixel;
pDstBuf = gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom)*bytesPerPixel;
}
pSrcBuf =(BYTE *)gCursorData + srcStartRow;
pSrcMask =(BYTE *)gCursorMask + srcStartRow;
if (bDoRotation)
{
for (row=yTop;row<yBottom;row++)
{
i=srcWidthB;
pSrcBuf += srcRowMarginB;
pSrcMask += srcRowMarginB;
while (i > 0)
{
if (i<4 || ((unsigned)pDstBuf & 0x3) || ((unsigned)pSrcBuf & 0x3))
{
*pDstBuf &= *pSrcMask;
*pDstBuf++ ^= *pSrcBuf;
pSrcMask++;
pSrcBuf++;
i-=1;
}
else
{
*(unsigned *)pDstBuf &= *(unsigned *)pSrcMask;
*(unsigned *)pDstBuf ^= *(unsigned *)pSrcBuf;
pDstBuf+=4;
pSrcMask+=4;
pSrcBuf+=4;
i-=4;
}
}
pSrcMask += clipWidthB;
pSrcBuf += clipWidthB;
pDstBuf += dstMarginWidth;
}
}
else
{
pSrcBuf += srcRowMarginB;
pSrcMask += srcRowMarginB;
for (i=0;i<srcWidthB/bytesPerPixel;i++)
{
for (row=yTop;row<yBottom;row++)
{
for (j=0;j<bytesPerPixel;j++)
{
*pDstBuf &= *(pSrcMask+j);
*pDstBuf++ ^= *(pSrcBuf+j);
}
pSrcBuf-=cursorWidthB;
pSrcMask-=cursorWidthB;
}
pSrcBuf +=srcMarginWidth+2;
pSrcMask +=srcMarginWidth+2;
pDstBuf +=dstMarginWidth;
}
}
}
LeaveCriticalSection(&displayMutex);
}
}
void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color)
{
WORD *pDstBuf;
WORD srcColor = (WORD)color;
DWORD xLeft,yTop,xRight,yBottom;
DWORD srcWidthB,dstMarginWidth;
DWORD dstStartRow;
if (bAllowOSFrameBufferUpdates)
{
xLeft = prc->left < 0 ? 0 : prc->left;
yTop = prc->top < 0 ? 0 : prc->top;
xRight = prc->right > gDibBufferWidth ? gDibBufferWidth : prc->right;
yBottom = prc->bottom > gDibBufferHeight ? gDibBufferHeight : prc->bottom;
if ((LONG)xLeft >= (LONG)xRight || (LONG)yTop >= (LONG)yBottom) return;
srcWidthB = xRight -xLeft;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop));
pDstBuf = (WORD*)gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom);
EnterCriticalSection(&displayMutex);
ellipse_core_ASM(srcColor, (dstMarginWidth+1)*2,srcWidthB,pDstBuf);
LeaveCriticalSection(&displayMutex);
}
}
void DispDrvrMoveCursor(INT32 xLocation,INT32 yLocation)
{
// First clear the cursor's old location
gDrawCursorFlag = FALSE;
DispDrvrDirtyRectDump(&gCursorRect);
// Now set the new location of the cursor and redraw
gCursorRect.left = xLocation - gxHot;
gCursorRect.top = yLocation - gyHot;
gCursorRect.right = gCursorRect.left + CURSOR_XSIZE;
gCursorRect.bottom = gCursorRect.top + CURSOR_YSIZE;
if (gCursorRect.left < 0)
{
gCursorRect.left = 0;
}
gDrawCursorFlag = TRUE;
DispDrvrDirtyRectDump(&gCursorRect);
}
#define VIDEO_REG_PATH TEXT("Drivers\\Display\\PXA255\\Config")
#define VIDEO_ROW_RES TEXT("CxScreen")
#define VIDEO_COL_RES TEXT("CyScreen")
#define PIXEL_DEPTH TEXT("Bpp")
#define VIDEO_DISPLAY_TYPE TEXT("DisplayType")
BOOL ReadRegistryData()
{
LONG regError;
HKEY hKey;
DWORD dwDataSize;
TCHAR DisplayType[64];
bpp=0;
DispDrvr_cyScreen = 0;
DispDrvr_cxScreen = 0;
// Open the registry key
regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,VIDEO_REG_PATH,0,KEY_ALL_ACCESS,&hKey);
if (regError != ERROR_SUCCESS)
{
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed opening \\Drivers\\Display\\PXA255\\Config key, Error 0x%X\r\n"),regError));
return(FALSE);
}
// Display width
dwDataSize = sizeof(DispDrvr_cxScreen);
regError = RegQueryValueEx(hKey,VIDEO_ROW_RES, NULL, NULL,(LPBYTE)&DispDrvr_cxScreen,&dwDataSize);
if (regError != ERROR_SUCCESS)
{
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display x value, Error 0x%X\r\n"),regError));
return(FALSE);
}
// Display height
dwDataSize = sizeof(DispDrvr_cyScreen);
regError = RegQueryValueEx(hKey,VIDEO_COL_RES,NULL,NULL,(LPBYTE)&DispDrvr_cyScreen,&dwDataSize);
if (regError != ERROR_SUCCESS)
{
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display y value, Error 0x%X\r\n"),regError));
return(FALSE);
}
// Color depth
dwDataSize = sizeof(bpp);
regError=RegQueryValueEx(hKey,PIXEL_DEPTH,NULL,NULL,(LPBYTE)&bpp,&dwDataSize);
if (regError != ERROR_SUCCESS)
{
bpp=0;
}
// Display Type
dwDataSize = sizeof(DisplayType);
regError = RegQueryValueEx(hKey,VIDEO_DISPLAY_TYPE,NULL,NULL,(LPBYTE)DisplayType,&dwDataSize);
if (regError != ERROR_SUCCESS)
{
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display type, Error 0x%X\r\n"),regError));
return(FALSE);
}
RegCloseKey (hKey);
RETAILMSG(1, (TEXT(" bpp: 0x%x\r\n CxScreen: 0x%x\r\n CyScreen: 0x%x\r\nDisplay Type: %s\r\n"), bpp, DispDrvr_cxScreen, DispDrvr_cyScreen,DisplayType));
if (_wcsicmp(DisplayType, TEXT("LTM04C380K")) == 0)
nDisplayType = LTM04C380K;
else if (_wcsicmp(DisplayType, TEXT("LTM04C387S")) == 0)
nDisplayType = LTM04C387S;
else if (_wcsicmp(DisplayType, TEXT("LQ039Q2DS54")) == 0)
nDisplayType = LQ039Q2DS54;
else if (_wcsicmp(DisplayType, TEXT("LM8V31")) == 0)
nDisplayType = LM8V31;
else if (_wcsicmp(DisplayType, TEXT("LM057QCTT03")) == 0)
nDisplayType = LM057QCTT03;
else if (_wcsicmp(DisplayType, TEXT("TFTQVGA")) == 0)
nDisplayType = TFTQVGA;
else if (_wcsicmp(DisplayType, TEXT("LQ64D341")) == 0)
nDisplayType = LQ64D341;
else
nDisplayType = NONE;
// bDoRotation is used to indicate whether or not a rotation of the frame buffer
// is required in order to orient it correctly for the target display.
bDoRotation = FALSE;
switch (nDisplayType)
{
case LTM04C380K: // fall through
case LTM04C387S: // fall through
// case LQ039Q2DS54: // fall through
case LM8V31: // fall through
case LM057QCTT03: // fall through
case TFTQVGA:
if (DispDrvr_cxScreen > DispDrvr_cyScreen)
bDoRotation = TRUE;
break;
case LQ039Q2DS54: // fall through
case LQ64D341:
if (DispDrvr_cxScreen < DispDrvr_cyScreen)
bDoRotation = TRUE;
break;
default:
break;
}
// Calculate the stride of the frame buffer (in DWORDs)
DispDrvr_cdwStride = DispDrvr_cxScreen/4*bpp/8;
return(TRUE);
}
void LCDClearStatusReg()
{
// Clear the status register by writing 1's to each bit.
v_pLcdRegs->LCSR = ( LCD_LDD | LCD_SOF | LCD_BER | LCD_ABC | LCD_IUL |
LCD_IUU | LCD_OU | LCD_QD | LCD_EOF | LCD_BS |
LCD_SINT );
}
// Display the contents of a given page of video ram.
// This function assumes that the frame buffer has been arranged into one contiguous region.
// If your implementation uses frame buffers that are not contiguous, then you'll have to
// change the implementation of this function to explicitly set/determine
// each frame buffer start address.
void DisplayPageBuffer(int page)
{
if (page < NUM_FRAME_BUFFERS)
{
EnterCriticalSection(&frameDescriptorMutex);
activeFrameBuffer = page;
// Set the physical address of the frame buffer for all three frame descriptors
frameDescriptorCh0fd1->FSADR = LCD_FSADR(FRAME_BUFFER_0_BASE_PHYSICAL +activeFrameBuffer*frameBufferSize);
frameDescriptorCh0fd2->FSADR = LCD_FSADR(FRAME_BUFFER_0_BASE_PHYSICAL +activeFrameBuffer*frameBufferSize);
frameDescriptorCh1->FSADR = LCD_FSADR(FRAME_BUFFER_0_BASE_PHYSICAL +activeFrameBuffer*frameBufferSize+(frameBufferSize/2));
LeaveCriticalSection(&frameDescriptorMutex);
}
}
void ScrollBuffer(int direction)
{
EnterCriticalSection(&frameDescriptorMutex);
// Set the physical address of the frame buffer for all three frame descriptors
if (direction == 1) // scroll up
{
frameDescriptorCh0fd1->FSADR += DispDrvr_cdwStride << 2;
frameDescriptorCh0fd2->FSADR += DispDrvr_cdwStride << 2;
frameDescriptorCh1->FSADR += DispDrvr_cdwStride << 2;
}
else // scroll down
{
frameDescriptorCh0fd1->FSADR -= DispDrvr_cdwStride << 2;
frameDescriptorCh0fd2->FSADR -= DispDrvr_cdwStride << 2;
frameDescriptorCh1->FSADR -= DispDrvr_cdwStride << 2;
}
LeaveCriticalSection(&frameDescriptorMutex);
}
// This code must be run in Kernel mode in order to access the page tables.
// Clear the cache attribute and set the bufferable attribute for the given section descriptor
void ConfigureFrameBufferSectionDescriptor(unsigned int descriptor)
{
unsigned int *pDescriptor;
pDescriptor = (unsigned int *)descriptor;
*pDescriptor &= ~0x8;
*pDescriptor |= 0x4;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -