|
Introduction to Writing Windows CE Display Drivers(6) It is important to note that the GPE classes haven't changed very much since version 2.0, so the information presented here should be useful and accurate across many different versions of Windows CE. Improving the Display Driver ClassesAs useful as these C++ classes are for writing display drivers in Windows CE, it is clear that additional base functionality can be included to further simplify display driver development. The two classes to be improved upon are GPE and GPESurf. Since the source for these classes is not provided, we need to derive classes from them in order to improve them. These new classes are called NewGPE and NewGPESurf.
A good starting point for building the NewGPE class is configuration and initialization. The NewGPE class is designed to require as little modification or overriding of functions as possible. The class constructor, NewGPE(), provides default initialization for the variables. Currently, the only variable that would need to be changed here is m_bIsVGADevice, if a non-VGA device is being used. This variable is used to enable mapping of the VGA registers as well as selection of some default VGA functionality, done elsewhere in the driver. NewGPE::NewGPE() { // Flags for hardware features // m_bIsVGADevice = TRUE;// default to VGA device m_bHWCursor = FALSE;// default to software cursor m_b555Mode = FALSE;// default to 5-6-5 mode for 16Bpp // NOTE: // The following data members are modified to their final values // by the default implementation of SetMode and shouldn't need to // modified here or in ModeInit. // m_pPrimarySurface = NULL;// pointer to primary display surface m_nScreenWidth = 0;// display width m_nScreenHeight = 0;// display height m_pMode = NULL; // pointer to information on current mode m_p2DVideoMemory = NULL; // pointer to video memory manager m_pLAW = NULL;// pointer to linear access window memset(&m_ulBitMasks[0], 0, sizeof(m_ulBitMasks)); // bit masks // NOTE: // The following data members MUST be modified to their final // values by the display hardware specific function ModeInit. // m_nLAWPhysical = 0;// the physical address of the linear access // window for accessing the frame buffer m_nLAWSize = 0;// size of linear access window m_nVideoMemorySize = 0; // size of video memory, which can be different // than the linear access window m_nVideoMemoryStart = 0;// offset within the linear access window to the // start of video memory (usually is 0) m_nScreenStride = 0; // number of bytes per display line}To allow these functions to be hardware independent, mode information used by NumModes() and GetModeInfo() is taken from the variable m_gpeModeTable, a table of the supported display modes. This variable needs to be initialized by the driver developer based on the modes that will be supported by the driver. It is statically defined in the provided source file NEWGPE.CPP. However, this could be changed so that the table is instead loaded from the registry or a file when the driver is first run. int NewGPE::NumModes(){ // count the number of entries in the mode table BOOL bDone = FALSE; int nIndex = 0; while (!bDone) {if (m_gpeModeTable[nIndex].Bpp==0) {// no more entries in the tablebDone = TRUE;}else {// count entry and go to next entrynIndex++;} } return nIndex;}SCODE NewGPE::GetModeInfo( GPEMode *pMode, int modeNo ){ // make sure that the mode is valid (index is zero based) if ((modeNo<0) (modeNo>=NumModes()))return E_INVALIDARG; // get data from mode table *pMode = m_gpeModeTable[modeNo]; return S_OK;}The SetMode() function has been written to require no additional modification. It handles all the hardware independent mode initialization. The first step is to verify the selected mode from the list of supported modes. Once this is complete, the hardware dependent mode initialization function, ModeInit(), is called. The ModeInit() function must be overridden or modified to initialize the specific hardware and setup certain variables used elsewhere in the initialization process. These variables are:
|