📄 dispdrvr.c
字号:
/*++
File Name: Dispdrvr.c
Copyright (c) 1995, 1996, 1997 Microsoft Corporation
Copyright 1997 Motorola. All Rights Reserved.
Abstract: Color LCD driver for WinCE/MPC821
Notes: This driver is coded and tested for NEC NL6448AC33-10
--*/
#include <windows.h>
#include <types.h>
#include <WTYPES.H>
#include <mpc8xx.h>
#include <dd_serv.h>
//#include <platform.h>
#include "dispdrvr.h"
#include "cursor.h"
// To utilize the CE system palette for the color RAM table setup
#include "palette.h"
INSTANTIATE_PALETTE
// Different debug message zones
#ifdef DEBUG
#define GPE_ZONE_ERROR DEBUGZONE(0)
#define GPE_ZONE_WARNING DEBUGZONE(1)
#define GPE_ZONE_PERF DEBUGZONE(2)
#define GPE_ZONE_TEMP DEBUGZONE(3)
#define GPE_ZONE_ENTER DEBUGZONE(4)
#define GPE_ZONE_INIT DEBUGZONE(5)
#define GPE_ZONE_BLT_HI DEBUGZONE(6)
#define GPE_ZONE_BLT_LO DEBUGZONE(7)
#define GPE_ZONE_CREATE DEBUGZONE(8)
#define GPE_ZONE_FLIP DEBUGZONE(9)
#define GPE_ZONE_LINE DEBUGZONE(10)
#define GPE_ZONE_HW DEBUGZONE(11)
#define GPE_ZONE_POLY DEBUGZONE(12)
#define GPE_ZONE_CURSOR DEBUGZONE(13)
#define GPE_ZONE_REGISTERS DEBUGZONE(14)
#define GPE_ZONE_FRAME DEBUGZONE(15)
#endif
// Cursor Support
BOOL gDrawCursorFlag;
RECT gCursorRect;
DWORD gCursorData[CURSOR_BYTES / 4];
DWORD gCursorMask[CURSOR_BYTES / 4];
DWORD gxHot;
DWORD gyHot;
/*
/* The following section contains the GDI required global variables. */
#if (defined(MOUSE_CURSOR_ON) || defined(TOUCH_CURSOR_ON))
void * DispDrvrPhysicalFrameBuffer = (void *)0;
DWORD* PHYSICAL_FRAME_BUFFER; // Mapping of the VGA display memory
#else
void * DispDrvrPhysicalFrameBuffer; /* The GDI frame buffer */
#endif
int DispDrvr_cxScreen; /* The number of pixel in one row of the screen */
int DispDrvr_cyScreen; /* The number of pixel in one column of the screen */
int DispDrvr_HORZSIZE; /* Height, in millimeters of the LCD. */
int DispDrvr_VERTSIZE; /* Width, in millimeters of the LCD. */
int DispDrvr_LOGPIXELSX; /* Number of pixels per logical inch */
int DispDrvr_LOGPIXELSY; /* along screen width and height. */
int DispDrvr_cdwStride; /* Number of DWORDS in a line. */
CRITICAL_SECTION gDisplayMutex;
/* Virtual address pointer to the internal dual port memory map region. */
static PDA *immr;
/* Virtual address pointer to the GDI composition buffer. */
PBYTE v_pvDib = NULL;
/* Actual virtual pointer to the frame-buffer. */
PBYTE v_pvScreen;
/* CONTRAST CONTROL */
// Nulled v_pDisplayRegs to inform CE that we supported no contrast control in this driver.
PVBYTE v_pDisplayRegs = NULL;
/* FUNCTION PROTOTYPE DEFINITIONS. */
BOOL CPM_LCD_Init(LCD_Info_Type LCD_Info);
void LCD_Init_Test(LCD_Info_Type LCD_Info); // Test Prototype
/* END OF FUNCTION PROTOTYPE DEFINITIONS. */
/* The following function is only used when double-buffering is utilized.
It must be called if cursor support is to be implemented.*/
void DispDrvrDirtyRectDump (LPCRECT prc)
{
DWORD *pdwCurrentDest;
BYTE *pbCurrentDest;
BYTE *currentSource;
INT xLeft, yTop, xRight, yBottom;
INT srcByteCount, srcRightMarginBytes;
INT yCurrent;
INT iLineOffset;
INT gStride = DispDrvr_cdwStride * 4; //the actual stride in bytes
INT i;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrDirtyRectDump()\r\n")));
if (v_pvDib == NULL)
return;
xLeft = prc->left; // Align src to byte, dest to byte boundary
yTop = prc->top;
xRight = prc->right; // Align src to byte, dest to byte boundary
yBottom = prc->bottom;
// Keep the rectangle on the screen
if (xLeft < 0)
xLeft = 0;
if (yTop < 0)
yTop = 0;
if (xRight > DispDrvr_cxScreen)
xRight = DispDrvr_cxScreen;
if (yBottom > DispDrvr_cyScreen)
yBottom = DispDrvr_cyScreen;
// Make sure rectangle boundaries are acceptable
if (xLeft >= xRight || yTop >= yBottom)
{
return;
}
// Point to GPE surface
currentSource = v_pvDib + yTop * DispDrvr_cxScreen + xLeft;
// Span of rectangle in bytes
srcByteCount = xRight - xLeft;
// Distance to offset to next line after drawing the current line
srcRightMarginBytes = DispDrvr_cxScreen - xRight + xLeft;
EnterCriticalSection(&gDisplayMutex);
for (yCurrent = yTop; yCurrent < yBottom; yCurrent++)
{
iLineOffset = yCurrent;
//Point to physical frame buffer
pbCurrentDest = (BYTE *)(v_pvScreen + iLineOffset * gStride +
xLeft);
// Draw into physical framebuffer
for (i = (srcByteCount); i > 0; i--)
{
*pbCurrentDest++ = *currentSource++;
}
currentSource += srcRightMarginBytes;
}
// Only paint if the cursor's rectangle got dirty.
if (gDrawCursorFlag &&
gCursorRect.left < xRight && gCursorRect.right > xLeft &&
gCursorRect.top < yBottom && gCursorRect.bottom > yTop)
{
INT index;
INT dataIndex = 0;
INT cursorBottom;
INT rightClip = 0;
DWORD rightMask = 0xFFFFFFFF;
// Clip off mouse if past bottom of screen
cursorBottom = gCursorRect.bottom;
if (cursorBottom > DispDrvr_cyScreen)
{
cursorBottom = DispDrvr_cyScreen;
}
// Now clip off mouse if past right side of screen
if (gCursorRect.right > DispDrvr_cxScreen)
{
rightClip = gCursorRect.right - DispDrvr_cxScreen;
rightMask >>= (rightClip & 0x00000003) << 3;
}
for (yCurrent = gCursorRect.top; yCurrent < cursorBottom; yCurrent++)
{
iLineOffset = yCurrent;
// Point to physical frame buffer
pdwCurrentDest = (DWORD *)(v_pvScreen +
iLineOffset * gStride + gCursorRect.left);
// Put cursor image into frame buffer while adjusting for clipping on right
// side of screen
for (index = (CURSOR_XSIZE - rightClip) >> 2; index > 0; index--)
{
*pdwCurrentDest &= gCursorMask[dataIndex];
*pdwCurrentDest++ ^= gCursorData[dataIndex++];
}
if ((rightClip & 0x3) != 0)
{
*pdwCurrentDest &= gCursorMask[dataIndex] | ~rightMask;
*pdwCurrentDest++ ^= gCursorData[dataIndex++] & rightMask;
}
dataIndex += rightClip >> 2;
}
}
LeaveCriticalSection(&gDisplayMutex);
}
//
//
/* This function gives the display driver a pointer to the composition buffer. */
void DispDrvrSetDibBuffer (void * pv)
{
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrSetDibBuffer\r\n")));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
ASSERT (0 == v_pvDib);
v_pvDib = pv;
ASSERT (0 != v_pvDib);
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
}
/* GDI calls this routine before anything is done
Hardware specific tasks can be carried out here,
for example, setting display width or initialize hardware.
If everything is taken care of at boot time, nothing needs
to be done here. */
void DispDrvrInitialize (void)
{
LCD_Info_Type LCD_Info;
//There are other libs linked with this file to form the display driver. This ulZoneMask applies to all of them.
// You can adjust the debug message volume here
#ifdef DEBUG
dpCurSettings.ulZoneMask |= 0xffff;
#endif
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrInit: %x \r\n"),&DispDrvrInitialize));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
// The LCD specific values are defined in dispdrvr.h according to specific panel
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("Getting LCD panel specific config\r\n")));
LCD_Info.LCD_Type = LCD_TFT_DISPLAY | LCD_COLOR_DISPLAY;
LCD_Info.Columns = usCOLUMNS;
LCD_Info.Rows = usROWS;
LCD_Info.Width = usSCREEN_HORZSIZE;
LCD_Info.Height = usSCREEN_VERTSIZE;
LCD_Info.Nbr_data_bits = usNBR_BITS ;
LCD_Info.Wait_between_lines = usWAIT_BETWEEN_LINES;
LCD_Info.Wait_between_frames = usWAIT_BETWEEN_FRAMES;
LCD_Info.Vertical_sync_pulse = usV_SYNC_PULSE;
LCD_Info.Bits_per_pixel = ubBITS_PER_PIXEL;
LCD_Info.Frame_buffer_addr = dwADS_PHYS_FRAME_BUFF_ADDR; // set in dma.h
/* Setup the following for the GDI sub-system. */
DispDrvr_cxScreen = LCD_Info.Columns;
DispDrvr_cyScreen = LCD_Info.Rows;
DispDrvr_HORZSIZE = LCD_Info.Width; /* width, in millimeters of the LCD. */
DispDrvr_VERTSIZE = LCD_Info.Height; /* height, in millimeters of the LCD. */
DispDrvr_LOGPIXELSX = (int) (DispDrvr_cxScreen / DispDrvr_HORZSIZE * 25.4); /* Number of pixels per logical inch along screen width*/
DispDrvr_LOGPIXELSY = (int) (DispDrvr_cyScreen / DispDrvr_VERTSIZE * 25.4); /* Number of pixels per logical inch along screen height*/
DispDrvr_cdwStride = LCD_Info.Columns * LCD_Info.Bits_per_pixel / 32; /* Number of DWORDS in a line. */
/* Tell GDI the location of the frame-buffer. */
#if (defined(MOUSE_CURSOR_ON) || defined(TOUCH_CURSOR_ON))
PHYSICAL_FRAME_BUFFER = (void *) PTOV(LCD_Info.Frame_buffer_addr);
#else
DispDrvrPhysicalFrameBuffer = (void *) PTOV(LCD_Info.Frame_buffer_addr);
#endif
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("LCD_Info.LCD_Type: %x \r\n"),LCD_Info.LCD_Type));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("LCD_Info.Rows: %x \r\n"),LCD_Info.Rows));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("LCD_Info.Wait_between_lines: %x \r\n"),LCD_Info.Wait_between_lines));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("LCD_Info.Wait_between_frames: %x \r\n"),LCD_Info.Wait_between_frames));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("LCD_Info.Bits_per_pixel: %x \r\n"),LCD_Info.Bits_per_pixel));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("LCD_Info.Frame_buffer_addr: %x \r\n"),LCD_Info.Frame_buffer_addr));
/* Now initialize the LCD function in the MPC8xx CPM. */
if (CPM_LCD_Init(LCD_Info)!=TRUE) {
DEBUGMSG(GPE_ZONE_ERROR, (TEXT(" CPM_LCD_Init failed\r\n")));
goto error_return;
}
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_cdwStride: %x\r\n"), DispDrvr_cdwStride));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvrBuf: %x \r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_cxScreen: %x \r\n"), DispDrvr_cxScreen));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_cyScreen: %x \r\n"), DispDrvr_cyScreen));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_HORZSIZE: %x \r\n"), DispDrvr_HORZSIZE));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_VERTSIZE: %x \r\n"), DispDrvr_VERTSIZE));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_LOGPIXELSX: %x \r\n"), DispDrvr_LOGPIXELSX));
DEBUGMSG(GPE_ZONE_INIT, (TEXT(" DispDrvr_LOGPIXELSY: %x \r\n"), DispDrvr_LOGPIXELSY));
//v_pscreen
v_pvScreen = VirtualAlloc(0, FRAME_BUFFER_SIZE, MEM_RESERVE,PAGE_NOACCESS);
if (v_pvScreen == NULL) {
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("DispDrvrInitialize: Could not allocate the frame buffer!\r\n")));
goto error_return;
}
#if (defined(MOUSE_CURSOR_ON) || defined(TOUCH_CURSOR_ON))
if (!VirtualCopy(v_pvScreen,PHYSICAL_FRAME_BUFFER, FRAME_BUFFER_SIZE, PAGE_READWRITE|
PAGE_NOCACHE)) {
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("DispDrvrInitialize: frame buffer copy failed!\r\n")));
goto error_return;
}
#else
if (!VirtualCopy(v_pvScreen,DispDrvrPhysicalFrameBuffer, FRAME_BUFFER_SIZE, PAGE_READWRITE|
PAGE_NOCACHE)) {
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("DispDrvrInitialize: frame buffer copy failed!\r\n")));
goto error_return;
}
#endif
DEBUGMSG(GPE_ZONE_TEMP, (TEXT("Calling LCD_Init_Test.\r\n")));
LCD_Init_Test(LCD_Info);
DEBUGMSG(GPE_ZONE_TEMP, (TEXT("LCD_Init_Test done.\r\n")));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("v_pDisplayRegs %x\r\n"), v_pDisplayRegs));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrInitialize Returning normally. \r\n")));
// Initialize Cursor
InitializeCriticalSection(&gDisplayMutex);
gDrawCursorFlag = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -