www.pudn.com > s3c2410bsp_ce400_v100.zip > s3c2410disp.cpp
/*++ 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) 2001. Samsung Electronics, co. ltd All rights reserved. Module Name: Abstract: This file implements the S3C2410 LCD function rev: 2002.4.4 : First S3C2410 version (kwangyoon LEE, kwangyoon@samsung.com) 2002.1.31 : CE.NET port (kwangyoon LEE, kwangyoon@samsung.com) Notes: --*/ #include "precomp.h" #ifdef CLEARTYPE #include#endif DWORD gdwLCDVirtualFrameBase; INSTANTIATE_GPE_ZONES(0x3,"MGDI Driver","unused1","unused2") // Start with errors and warnings static GPE *gGPE = (GPE*)NULL; static ulong gBitMasks[] = { 0xF800, 0x07E0, 0x001F }; // 565 MODE static TCHAR gszBaseInstance[256] = _T("Drivers\\Display\\S3C2410\\CONFIG"); #define dim(x) (sizeof(x) / sizeof(x[0])) // This prototype avoids problems exporting from .lib BOOL APIENTRY GPEEnableDriver(ULONG engineVersion, ULONG cj, DRVENABLEDATA *data, PENGCALLBACKS engineCallbacks); // GWES will invoke this routine once prior to making any other calls into the driver. // This routine needs to save its instance path information and return TRUE. If it // returns FALSE, GWES will abort the display initialization. BOOL APIENTRY DisplayInit(LPCTSTR pszInstance, DWORD dwNumMonitors) { DWORD dwStatus; HKEY hkDisplay; BOOL fOk = FALSE; RETAILMSG(0, (_T("SALCD2: display instance '%s', num monitors %d\r\n"), pszInstance != NULL ? pszInstance : _T(" "), dwNumMonitors)); if(pszInstance != NULL) { _tcsncpy(gszBaseInstance, pszInstance, dim(gszBaseInstance)); } // sanity check the path by making sure it exists dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, gszBaseInstance, 0, 0, &hkDisplay); if(dwStatus == ERROR_SUCCESS) { RegCloseKey(hkDisplay); fOk = TRUE; } else { RETAILMSG(0, (_T("SALCD2: DisplayInit: can't open '%s'\r\n"), gszBaseInstance)); } return fOk; } BOOL APIENTRY DrvEnableDriver(ULONG engineVersion, ULONG cj, DRVENABLEDATA *data, PENGCALLBACKS engineCallbacks) { BOOL fOk = FALSE; // make sure we know where our registry configuration is if(gszBaseInstance[0] != 0) { fOk = GPEEnableDriver(engineVersion, cj, data, engineCallbacks); } return fOk; } // // Main entry point for a GPE-compliant driver // GPE *GetGPE(void) { if (!gGPE) { gGPE = new S3C2410DISP(); } return gGPE; } WORD TempBuffer[241][320]; S3C2410DISP::S3C2410DISP (void) { RETAILMSG(0, (TEXT("++S3C2410DISP::S3C2410DISP\r\n"))); // setup up display mode related constants m_nScreenWidth = 240; m_nScreenHeight = 320; m_colorDepth = 16; m_cbScanLineLength = m_nScreenWidth * 2; m_FrameBufferSize = m_nScreenHeight * m_cbScanLineLength; // memory map register access window, frame buffer, and program LCD controller InitializeHardware(); #ifdef ROTATE m_iRotate = 0; SetRotateParms(); #endif //ROTATE // setup ModeInfo structure m_ModeInfo.modeId = 0; m_ModeInfo.width = m_nScreenWidth; m_ModeInfo.height = m_nScreenHeight; m_ModeInfo.Bpp = m_colorDepth; m_ModeInfo.format = gpe16Bpp; m_ModeInfo.frequency = 60; // ? m_pMode = &m_ModeInfo; // allocate primary display surface #ifdef ROTATE m_pPrimarySurface = new GPESurfRotate(m_nScreenWidthSave, m_nScreenHeightSave, (void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_ModeInfo.format); #else m_pPrimarySurface = new GPESurf(m_nScreenWidth, m_nScreenHeight, (void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_ModeInfo.format); #endif //!ROTATE memset ((void*)m_pPrimarySurface->Buffer(), 0x0, m_FrameBufferSize); // init cursor related vars m_CursorVisible = FALSE; m_CursorDisabled = TRUE; m_CursorForcedOff = FALSE; memset (&m_CursorRect, 0x0, sizeof(m_CursorRect)); m_CursorBackingStore = NULL; m_CursorXorShape = NULL; m_CursorAndShape = NULL; #ifdef CLEARTYPE HKEY hKey; DWORD dwValue; ULONG ulGamma = DEFAULT_CT_GAMMA; if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE,szGamma,0, NULL,0,0,0,&hKey,&dwValue)) { if (dwValue == REG_OPENED_EXISTING_KEY) { DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(LONG); if (ERROR_SUCCESS == RegQueryValueEx(hKey,szGammaValue,0,&dwType,(BYTE *)&dwValue,&dwSize)) { ulGamma = dwValue; } } else if (dwValue == REG_CREATED_NEW_KEY ) { RegSetValueEx(hKey,szGammaValue,0,REG_DWORD,(BYTE *)&ulGamma,sizeof(DWORD)); } RegCloseKey(hKey); } SetClearTypeBltGamma(ulGamma); SetClearTypeBltMasks(gBitMasks[0], gBitMasks[1], gBitMasks[2]); #endif //CLEARTYPE RETAILMSG(0, (TEXT("--S3C2410DISP::S3C2410DISP\r\n"))); } void S3C2410DISP::InitializeHardware (void) { WORD *ptr; DWORD index; HKEY hkDisplay = NULL; DWORD dwLCDPhysicalFrameBase; DWORD dwStatus, dwType, dwSize; RETAILMSG(0, (_T("++S3C2410DISP::InitializeHardware\r\n"))); // open the registry key and read our configuration dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, gszBaseInstance, 0, 0, &hkDisplay); dwType = REG_DWORD; if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) { dwSize = sizeof(DWORD); dwStatus = RegQueryValueEx(hkDisplay, _T("LCDVirtualFrameBase"), NULL, &dwType, (LPBYTE) &gdwLCDVirtualFrameBase, &dwSize); } if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) { dwSize = sizeof(DWORD); dwStatus = RegQueryValueEx(hkDisplay, _T("LCDPhysicalFrameBase"), NULL, &dwType, (LPBYTE) &dwLCDPhysicalFrameBase, &dwSize); } // close the registry key if(hkDisplay != NULL) { RegCloseKey(hkDisplay); } // did we get everything? if(dwStatus != ERROR_SUCCESS) { RETAILMSG(0, (_T("SALCD2: InitializeHardware: couldn't get registry configuration\r\n"))); return; } // map frame buffer into process space memory m_VirtualFrameBuffer = (DWORD)VirtualAlloc(0, (0x40000), MEM_RESERVE, PAGE_NOACCESS); if (m_VirtualFrameBuffer == NULL) { RETAILMSG(0,(TEXT("m_VirtualFrameBuffer is not allocated\n\r"))); return; } else if (!VirtualCopy((PVOID)m_VirtualFrameBuffer, (PVOID)gdwLCDVirtualFrameBase, (0x40000), PAGE_READWRITE | PAGE_NOCACHE)) { RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is not mapped\n\r"))); VirtualFree((PVOID)m_VirtualFrameBuffer, 0, MEM_RELEASE); return; } RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is mapped at %x(PHY : %x)\n\r"), m_VirtualFrameBuffer, gdwLCDVirtualFrameBase)); RETAILMSG(0, (TEXT("Clearing frame buffer !!!\n\r"))); ptr = (WORD *)m_VirtualFrameBuffer; // clear rest of frame buffer out for (index = 0; index < 320*240; index++) { if(index < 3200) { ptr[index] = 0xf800; } else if(index < 6400) { ptr[index] = 0x07e0; } else if(index < 9600) { ptr[index] = 0x001f; } else { ptr[index] = 0xffff; } } RETAILMSG(0, (_T("--S3C2410DISP::InitializeHardware\r\n"))); } SCODE S3C2410DISP::SetMode (INT modeId, HPALETTE *palette) { RETAILMSG(0, (TEXT("++S3C2410DISP::SetMode\r\n"))); if (modeId != 0) { RETAILMSG(0, (TEXT("S3C2410DISP::SetMode Want mode %d, only have mode 0\r\n"),modeId)); return E_INVALIDARG; } if (palette) { *palette = EngCreatePalette (PAL_BITFIELDS, 0, NULL, gBitMasks[0], gBitMasks[1], gBitMasks[2]); } RETAILMSG(0, (TEXT("--S3C2410DISP::SetMode\r\n"))); return S_OK; } SCODE S3C2410DISP::GetModeInfo(GPEMode *mode, INT modeNumber) { RETAILMSG(0, (TEXT("++S3C2410DISP::GetModeInfo\r\n"))); if (modeNumber != 0) { return E_INVALIDARG; } *mode = m_ModeInfo; RETAILMSG(0, (TEXT("--S3C2410DISP::GetModeInfo\r\n"))); return S_OK; } int S3C2410DISP::NumModes() { RETAILMSG(0, (TEXT("++S3C2410DISP::NumModes\r\n"))); RETAILMSG(0, (TEXT("--S3C2410DISP::NumModes\r\n"))); return 1; } void S3C2410DISP::CursorOn (void) { UCHAR *ptrScreen = (UCHAR*)m_pPrimarySurface->Buffer(); UCHAR *ptrLine; UCHAR *cbsLine; #ifndef ROTATE UCHAR *xorLine; UCHAR *andLine; #endif //!ROTATE int x, y; if (!m_CursorForcedOff && !m_CursorDisabled && !m_CursorVisible) { #ifdef ROTATE RECTL rSave; int iRotate; #endif //ROTATE if (!m_CursorBackingStore) { RETAILMSG(0, (TEXT("S3C2410DISP::CursorOn - No backing store available\r\n"))); return; } #ifdef ROTATE rSave = m_CursorRect; RotateRectl(&m_CursorRect); #endif //ROTATE for (y = m_CursorRect.top; y < m_CursorRect.bottom; y++) { if (y < 0) { continue; } #ifdef ROTATE if (y >= m_nScreenHeightSave) #else if (y >= m_nScreenHeight) #endif //ROTATE { break; } ptrLine = &ptrScreen[y * m_pPrimarySurface->Stride()]; cbsLine = &m_CursorBackingStore[(y - m_CursorRect.top) * (m_CursorSize.x * (m_colorDepth >> 3))]; #ifndef ROTATE xorLine = &m_CursorXorShape[(y - m_CursorRect.top) * m_CursorSize.x]; andLine = &m_CursorAndShape[(y - m_CursorRect.top) * m_CursorSize.x]; #endif //!ROTATE for (x = m_CursorRect.left; x < m_CursorRect.right; x++) { if (x < 0) { continue; } #ifdef ROTATE if (x >= m_nScreenWidthSave) #else if (x >= m_nScreenWidth) #endif //!ROTATE { break; } #ifdef ROTATE switch (m_iRotate) { case DMDO_0: iRotate = (y - m_CursorRect.top)*m_CursorSize.x + x - m_CursorRect.left; break; case DMDO_90: iRotate = (x - m_CursorRect.left)*m_CursorSize.x + m_CursorSize.y - 1 - (y - m_CursorRect.top); break; case DMDO_180: iRotate = (m_CursorSize.y - 1 - (y - m_CursorRect.top))*m_CursorSize.x + m_CursorSize.x - 1 - (x - m_CursorRect.left); break; case DMDO_270: iRotate = (m_CursorSize.x -1 - (x - m_CursorRect.left))*m_CursorSize.x + y - m_CursorRect.top; break; default: iRotate = (y - m_CursorRect.top)*m_CursorSize.x + x - m_CursorRect.left; break; } #endif //ROTATE cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3)] = ptrLine[x * (m_colorDepth >> 3)]; #ifdef ROTATE ptrLine[x * (m_colorDepth >> 3)] &= m_CursorAndShape[iRotate]; ptrLine[x * (m_colorDepth >> 3)] ^= m_CursorXorShape[iRotate]; #else ptrLine[x * (m_colorDepth >> 3)] &= andLine[x - m_CursorRect.left]; ptrLine[x * (m_colorDepth >> 3)] ^= xorLine[x - m_CursorRect.left]; #endif //ROTATE if (m_colorDepth > 8) { cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3) + 1] = ptrLine[x * (m_colorDepth >> 3) + 1]; #ifdef ROTATE ptrLine[x * (m_colorDepth >> 3) + 1] &= m_CursorAndShape[iRotate]; ptrLine[x * (m_colorDepth >> 3) + 1] ^= m_CursorXorShape[iRotate]; #else ptrLine[x * (m_colorDepth >> 3) + 1] &= andLine[x - m_CursorRect.left]; ptrLine[x * (m_colorDepth >> 3) + 1] ^= xorLine[x - m_CursorRect.left]; #endif //ROTATE if (m_colorDepth > 16) { cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3) + 2] = ptrLine[x * (m_colorDepth >> 3) + 2]; #ifdef ROTATE ptrLine[x * (m_colorDepth >> 3) + 2] &= m_CursorAndShape[iRotate]; ptrLine[x * (m_colorDepth >> 3) + 2] ^= m_CursorXorShape[iRotate]; #else ptrLine[x * (m_colorDepth >> 3) + 2] &= andLine[x - m_CursorRect.left]; ptrLine[x * (m_colorDepth >> 3) + 2] ^= xorLine[x - m_CursorRect.left]; #endif //ROTATE } } } } #ifdef ROTATE m_CursorRect = rSave; #endif m_CursorVisible = TRUE; } } void S3C2410DISP::CursorOff (void) { UCHAR *ptrScreen = (UCHAR*)m_pPrimarySurface->Buffer(); UCHAR *ptrLine; UCHAR *cbsLine; int x, y; if (!m_CursorForcedOff && !m_CursorDisabled && m_CursorVisible) { #ifdef ROTATE RECTL rSave; #endif //ROTATE if (!m_CursorBackingStore) { RETAILMSG(0, (TEXT("S3C2410DISP::CursorOff - No backing store available\r\n"))); return; } #ifdef ROTATE rSave = m_CursorRect; RotateRectl(&m_CursorRect); #endif //ROTATE for (y = m_CursorRect.top; y < m_CursorRect.bottom; y++) { // clip to displayable screen area (top/bottom) if (y < 0) { continue; } #ifndef ROTATE if (y >= m_nScreenHeight) #else if (y >= m_nScreenHeightSave) #endif //!ROTATE { break; } ptrLine = &ptrScreen[y * m_pPrimarySurface->Stride()]; cbsLine = &m_CursorBackingStore[(y - m_CursorRect.top) * (m_CursorSize.x * (m_colorDepth >> 3))]; for (x = m_CursorRect.left; x < m_CursorRect.right; x++) { // clip to displayable screen area (left/right) if (x < 0) { continue; } #ifndef ROTATE if (x >= m_nScreenWidth) #else if (x>= m_nScreenWidthSave) #endif //!ROTATE { break; } ptrLine[x * (m_colorDepth >> 3)] = cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3)]; if (m_colorDepth > 8) { ptrLine[x * (m_colorDepth >> 3) + 1] = cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3) + 1]; if (m_colorDepth > 16) { ptrLine[x * (m_colorDepth >> 3) + 2] = cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3) + 2]; } } } } #ifdef ROTATE m_CursorRect = rSave; #endif //ROTATE m_CursorVisible = FALSE; } } SCODE S3C2410DISP::SetPointerShape(GPESurf *pMask, GPESurf *pColorSurf, INT xHot, INT yHot, INT cX, INT cY) { UCHAR *andPtr; // input pointer UCHAR *xorPtr; // input pointer UCHAR *andLine; // output pointer UCHAR *xorLine; // output pointer char bAnd; char bXor; int row; int col; int i; int bitMask; RETAILMSG(0, (TEXT("S3C2410DISP::SetPointerShape(0x%X, 0x%X, %d, %d, %d, %d)\r\n"),pMask, pColorSurf, xHot, yHot, cX, cY)); // turn current cursor off CursorOff(); // release memory associated with old cursor if (m_CursorBackingStore) { delete (void*)m_CursorBackingStore; m_CursorBackingStore = NULL; } if (m_CursorXorShape) { delete (void*)m_CursorXorShape; m_CursorXorShape = NULL; } if (m_CursorAndShape) { delete (void*)m_CursorAndShape; m_CursorAndShape = NULL; } if (!pMask) // do we have a new cursor shape { m_CursorDisabled = TRUE; // no, so tag as disabled } else { m_CursorDisabled = FALSE; // yes, so tag as not disabled // allocate memory based on new cursor size m_CursorBackingStore = new UCHAR[(cX * (m_colorDepth >> 3)) * cY]; m_CursorXorShape = new UCHAR[cX * cY]; m_CursorAndShape = new UCHAR[cX * cY]; // store size and hotspot for new cursor m_CursorSize.x = cX; m_CursorSize.y = cY; m_CursorHotspot.x = xHot; m_CursorHotspot.y = yHot; andPtr = (UCHAR*)pMask->Buffer(); xorPtr = (UCHAR*)pMask->Buffer() + (cY * pMask->Stride()); // store OR and AND mask for new cursor for (row = 0; row < cY; row++) { andLine = &m_CursorAndShape[cX * row]; xorLine = &m_CursorXorShape[cX * row]; for (col = 0; col < cX / 8; col++) { bAnd = andPtr[row * pMask->Stride() + col]; bXor = xorPtr[row * pMask->Stride() + col]; for (bitMask = 0x0080, i = 0; i < 8; bitMask >>= 1, i++) { andLine[(col * 8) + i] = bAnd & bitMask ? 0xFF : 0x00; xorLine[(col * 8) + i] = bXor & bitMask ? 0xFF : 0x00; } } } } return S_OK; } SCODE S3C2410DISP::MovePointer(INT xPosition, INT yPosition) { RETAILMSG(0, (TEXT("S3C2410DISP::MovePointer(%d, %d)\r\n"), xPosition, yPosition)); CursorOff(); if (xPosition != -1 || yPosition != -1) { // compute new cursor rect m_CursorRect.left = xPosition - m_CursorHotspot.x; m_CursorRect.right = m_CursorRect.left + m_CursorSize.x; m_CursorRect.top = yPosition - m_CursorHotspot.y; m_CursorRect.bottom = m_CursorRect.top + m_CursorSize.y; CursorOn(); } return S_OK; } void S3C2410DISP::WaitForNotBusy(void) { RETAILMSG(0, (TEXT("S3C2410DISP::WaitForNotBusy\r\n"))); return; } int S3C2410DISP::IsBusy(void) { RETAILMSG(0, (TEXT("S3C2410DISP::IsBusy\r\n"))); return 0; } void S3C2410DISP::GetPhysicalVideoMemory(unsigned long *physicalMemoryBase, unsigned long *videoMemorySize) { RETAILMSG(0, (TEXT("S3C2410DISP::GetPhysicalVideoMemory\r\n"))); *physicalMemoryBase = gdwLCDVirtualFrameBase; *videoMemorySize = m_cbScanLineLength * m_nScreenHeight; } SCODE S3C2410DISP::AllocSurface(GPESurf **surface, INT width, INT height, EGPEFormat format, INT surfaceFlags) { RETAILMSG(0, (TEXT("S3C2410DISP::AllocSurface\r\n"))); if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY) { 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; // Clean up } else { return S_OK; } } return E_OUTOFMEMORY; } SCODE S3C2410DISP::WrappedEmulatedLine (GPELineParms *lineParameters) { SCODE retval; RECT bounds; int N_plus_1; // Minor length of bounding rect + 1 // calculate the bounding-rect to determine overlap with cursor if (lineParameters->dN) // The line has a diagonal component (we'll refresh the bounding rect) { N_plus_1 = 2 + ((lineParameters->cPels * lineParameters->dN) / lineParameters->dM); } else { N_plus_1 = 1; } switch(lineParameters->iDir) { case 0: bounds.left = lineParameters->xStart; bounds.top = lineParameters->yStart; bounds.right = lineParameters->xStart + lineParameters->cPels + 1; bounds.bottom = bounds.top + N_plus_1; break; case 1: bounds.left = lineParameters->xStart; bounds.top = lineParameters->yStart; bounds.bottom = lineParameters->yStart + lineParameters->cPels + 1; bounds.right = bounds.left + N_plus_1; break; case 2: bounds.right = lineParameters->xStart + 1; bounds.top = lineParameters->yStart; bounds.bottom = lineParameters->yStart + lineParameters->cPels + 1; bounds.left = bounds.right - N_plus_1; break; case 3: bounds.right = lineParameters->xStart + 1; bounds.top = lineParameters->yStart; bounds.left = lineParameters->xStart - lineParameters->cPels; bounds.bottom = bounds.top + N_plus_1; break; case 4: bounds.right = lineParameters->xStart + 1; bounds.bottom = lineParameters->yStart + 1; bounds.left = lineParameters->xStart - lineParameters->cPels; bounds.top = bounds.bottom - N_plus_1; break; case 5: bounds.right = lineParameters->xStart + 1; bounds.bottom = lineParameters->yStart + 1; bounds.top = lineParameters->yStart - lineParameters->cPels; bounds.left = bounds.right - N_plus_1; break; case 6: bounds.left = lineParameters->xStart; bounds.bottom = lineParameters->yStart + 1; bounds.top = lineParameters->yStart - lineParameters->cPels; bounds.right = bounds.left + N_plus_1; break; case 7: bounds.left = lineParameters->xStart; bounds.bottom = lineParameters->yStart + 1; bounds.right = lineParameters->xStart + lineParameters->cPels + 1; bounds.top = bounds.bottom - N_plus_1; break; default: RETAILMSG(0, (TEXT("Invalid direction: %d\r\n"), lineParameters->iDir)); return E_INVALIDARG; } // check for line overlap with cursor and turn off cursor if overlaps if (m_CursorVisible && !m_CursorDisabled && m_CursorRect.top < bounds.bottom && m_CursorRect.bottom > bounds.top && m_CursorRect.left < bounds.right && m_CursorRect.right > bounds.left) { CursorOff(); m_CursorForcedOff = TRUE; } // do emulated line retval = EmulatedLine (lineParameters); // se if cursor was forced off because of overlap with line bouneds and turn back on if (m_CursorForcedOff) { m_CursorForcedOff = FALSE; CursorOn(); } return retval; } SCODE S3C2410DISP::Line(GPELineParms *lineParameters, EGPEPhase phase) { RETAILMSG(0, (TEXT("S3C2410DISP::Line\r\n"))); if (phase == gpeSingle || phase == gpePrepare) { if ((lineParameters->pDst != m_pPrimarySurface)) { lineParameters->pLine = EmulatedLine; } else { lineParameters->pLine = (SCODE (GPE::*)(struct GPELineParms *)) WrappedEmulatedLine; } } return S_OK; } SCODE S3C2410DISP::BltPrepare(GPEBltParms *blitParameters) { RECTL rectl; RETAILMSG(0, (TEXT("S3C2410DISP::BltPrepare\r\n"))); // default to base EmulatedBlt routine blitParameters->pBlt = EmulatedBlt; // see if we need to deal with cursor if (m_CursorVisible && !m_CursorDisabled) { // check for destination overlap with cursor and turn off cursor if overlaps if (blitParameters->pDst == m_pPrimarySurface) // only care if dest is main display surface { if (blitParameters->prclDst != NULL) // make sure there is a valid prclDst { rectl = *blitParameters->prclDst; // if so, use it } else { rectl = m_CursorRect; // if not, use the Cursor rect - this forces the cursor to be turned off in this case } if (m_CursorRect.top < rectl.bottom && m_CursorRect.bottom > rectl.top && m_CursorRect.left < rectl.right && m_CursorRect.right > rectl.left) { CursorOff(); m_CursorForcedOff = TRUE; } } // check for source overlap with cursor and turn off cursor if overlaps if (blitParameters->pSrc == m_pPrimarySurface) // only care if source is main display surface { if (blitParameters->prclSrc != NULL) // make sure there is a valid prclSrc { rectl = *blitParameters->prclSrc; // if so, use it } else { rectl = m_CursorRect; // if not, use the CUrsor rect - this forces the cursor to be turned off in this case } if (m_CursorRect.top < rectl.bottom && m_CursorRect.bottom > rectl.top && m_CursorRect.left < rectl.right && m_CursorRect.right > rectl.left) { CursorOff(); m_CursorForcedOff = TRUE; } } } #ifdef ROTATE if (m_iRotate && (blitParameters->pDst == m_pPrimarySurface || blitParameters->pSrc == m_pPrimarySurface)) { blitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))EmulatedBltRotate; } #endif //ROTATE #ifdef CLEARTYPE if (((blitParameters->rop4 & 0xffff) == 0xaaf0 ) && (blitParameters->pMask->Format() == gpe8Bpp)) { switch (m_colorDepth) { case 16: blitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst16; return S_OK; case 24: blitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst24; return S_OK; case 32: blitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst32; return S_OK; default: break; } } #endif //CLEARTYPE // see if there are any optimized software blits available EmulatedBltSelect02(blitParameters); EmulatedBltSelect08(blitParameters); EmulatedBltSelect16(blitParameters); return S_OK; } SCODE S3C2410DISP::BltComplete(GPEBltParms *blitParameters) { RETAILMSG(0, (TEXT("S3C2410DISP::BltComplete\r\n"))); // see if cursor was forced off because of overlap with source or destination and turn back on if (m_CursorForcedOff) { m_CursorForcedOff = FALSE; CursorOn(); } return S_OK; } INT S3C2410DISP::InVBlank(void) { RETAILMSG(0, (TEXT("S3C2410DISP::InVBlank\r\n"))); return 0; } SCODE S3C2410DISP::SetPalette(const PALETTEENTRY *source, USHORT firstEntry, USHORT numEntries) { RETAILMSG(0, (TEXT("S3C2410DISP::SetPalette\r\n"))); if (firstEntry < 0 || firstEntry + numEntries > 256 || source == NULL) { return E_INVALIDARG; } return S_OK; } ULONG S3C2410DISP::GetGraphicsCaps() { #ifdef CLEARTYPE return GCAPS_GRAY16 | GCAPS_CLEARTYPE; #else return GCAPS_GRAY16; #endif } void RegisterDDHALAPI(void) { return; // no DDHAL support } #if defined(CLEARTYPE) || defined(ROTATE) extern GetGammaValue(ULONG * pGamma); extern SetGammaValue(ULONG ulGamma, BOOL bUpdateReg); ULONG S3C2410DISP::DrvEscape( SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut) { if (iEsc == DRVESC_GETGAMMAVALUE) { return GetGammaValue((ULONG *)pvOut); } else if (iEsc == DRVESC_SETGAMMAVALUE) { return SetGammaValue(cjIn, *(BOOL *)pvIn); } #ifdef ROTATE if (iEsc == DRVESC_GETSCREENROTATION) { *(int *)pvOut = ((DMDO_0 | DMDO_90 | DMDO_180 | DMDO_270) << 8) | ((BYTE)m_iRotate); return DISP_CHANGE_SUCCESSFUL; } else if (iEsc == DRVESC_SETSCREENROTATION) { if ((cjIn == DMDO_0) || (cjIn == DMDO_90) || (cjIn == DMDO_180) || (cjIn == DMDO_270) ) { return DynRotate(cjIn); } return DISP_CHANGE_BADMODE; } #endif //ROTATE & ROTATE return 0; } #endif //CLEARTYPE ULONG *APIENTRY DrvGetMasks(DHPDEV dhpdev) { return gBitMasks; } #ifdef ROTATE void S3C2410DISP::SetRotateParms() { int iswap; switch(m_iRotate) { case DMDO_0: m_nScreenHeightSave = m_nScreenHeight; m_nScreenWidthSave = m_nScreenWidth; break; case DMDO_180: m_nScreenHeightSave = m_nScreenHeight; m_nScreenWidthSave = m_nScreenWidth; break; case DMDO_90: case DMDO_270: iswap = m_nScreenHeight; m_nScreenHeight = m_nScreenWidth; m_nScreenWidth = iswap; m_nScreenHeightSave = m_nScreenWidth; m_nScreenWidthSave = m_nScreenHeight; break; default: m_nScreenHeightSave = m_nScreenHeight; m_nScreenWidthSave = m_nScreenWidth; break; } return; } LONG S3C2410DISP::DynRotate(int angle) { GPESurfRotate *pSurf = (GPESurfRotate *)m_pPrimarySurface; if (angle == m_iRotate) return DISP_CHANGE_SUCCESSFUL; m_iRotate = angle; switch(m_iRotate) { case DMDO_0: case DMDO_180: m_nScreenHeight = m_nScreenHeightSave; m_nScreenWidth = m_nScreenWidthSave; break; case DMDO_90: case DMDO_270: m_nScreenHeight = m_nScreenWidthSave; m_nScreenWidth = m_nScreenHeightSave; break; } m_pMode->width = m_nScreenWidth; m_pMode->height = m_nScreenHeight; pSurf->SetRotation(m_nScreenWidth, m_nScreenHeight, angle); return DISP_CHANGE_SUCCESSFUL; } #endif //ROTATE