sl@0: // Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: #undef __WINS__ sl@0: #include "../sgeneric/scdraw.h" sl@0: #elif defined(__WINS__) sl@0: #include "_WININC.H" sl@0: #endif sl@0: sl@0: sl@0: // sl@0: // CGenericDirectScreenBitmap: Implementation of generic CDirectScreenBitmap class sl@0: // sl@0: NONSHARABLE_CLASS(CGenericDirectScreenBitmap) : public CDirectScreenBitmap sl@0: { sl@0: public: sl@0: CGenericDirectScreenBitmap(); sl@0: CGenericDirectScreenBitmap(TInt aScreenNo); sl@0: ~CGenericDirectScreenBitmap(); sl@0: sl@0: public: sl@0: // Pure virtual from CDirectScreenBitmap sl@0: virtual TInt Create(const TRect& aScreenRect, TSettingsFlags aSettingsFlags); sl@0: virtual TInt BeginUpdate(TAcceleratedBitmapInfo& aBitmapInfo); sl@0: virtual void EndUpdate(TRequestStatus& aComplete); sl@0: virtual void EndUpdate(const TRect& aScreenRect, TRequestStatus& aComplete); sl@0: virtual void Close(); sl@0: sl@0: public: sl@0: enum TDsbPanic sl@0: { sl@0: EPanicAlreadyCreated = 1, sl@0: EPanicNotCreated = 2, sl@0: EPanicInvalidMode = 3, sl@0: EPanicOutOfBounds = 4, sl@0: EPanicNotWordAligned = 5, sl@0: EPanicInvalidRect = 6, sl@0: EPanicIncompleteRequest = 7, sl@0: EPanicHandleReturnedIncorrect = 8 sl@0: }; sl@0: static void Panic(TDsbPanic aPanic); sl@0: sl@0: private: sl@0: TInt DoCreate(); sl@0: sl@0: #ifdef __WINS__ sl@0: TRgb ExtractRgb(TUint8* aBuffer,TInt aPixelOffset) const; sl@0: void WinsUpdate(const TRect& aScreenRect); sl@0: #endif sl@0: sl@0: private: sl@0: #ifndef __WINS__ sl@0: TInt iVideoAddress; sl@0: #endif sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: CScreenDeviceHelper iSurfaceUpdater; sl@0: TUidPixelFormat iPixelFormat; sl@0: #endif sl@0: TAcceleratedBitmapInfo iBitmapInfo; sl@0: TUint32 iSettingsFlags; sl@0: TRect iUpdateRect; sl@0: TInt iDisplayOffsetLines; sl@0: TInt iBytesPerPixel; sl@0: TInt iDisplayOffsetPixel; sl@0: TBool iCreated; sl@0: TInt iScreenNo; sl@0: RChunk iChunk; sl@0: TBool iHasChunk; sl@0: }; sl@0: sl@0: // sl@0: // Create a new instance of a DSB sl@0: // The default screen (with number 0) will be used sl@0: EXPORT_C CDirectScreenBitmap* CDirectScreenBitmap::NewL() sl@0: { sl@0: CGenericDirectScreenBitmap* pDsb=new(ELeave) CGenericDirectScreenBitmap; sl@0: return(pDsb); sl@0: } sl@0: sl@0: // sl@0: // Create a new instance of a DSB sl@0: // The screen with aScreenNo number will be used sl@0: EXPORT_C CDirectScreenBitmap* CDirectScreenBitmap::NewL(TInt aScreenNo) sl@0: { sl@0: CGenericDirectScreenBitmap* pDsb = new (ELeave) CGenericDirectScreenBitmap(aScreenNo); sl@0: return pDsb; sl@0: } sl@0: sl@0: CGenericDirectScreenBitmap::CGenericDirectScreenBitmap() : sl@0: #ifndef __WINS__ sl@0: iVideoAddress(NULL), sl@0: #endif sl@0: iBitmapInfo(), sl@0: iSettingsFlags(ENone), sl@0: iUpdateRect(), sl@0: iDisplayOffsetLines(0), sl@0: iBytesPerPixel(0), sl@0: iDisplayOffsetPixel(0), sl@0: iHasChunk(EFalse) sl@0: { sl@0: } sl@0: sl@0: CGenericDirectScreenBitmap::CGenericDirectScreenBitmap(TInt aScreenNo) : sl@0: iScreenNo(aScreenNo) sl@0: { sl@0: } sl@0: sl@0: CGenericDirectScreenBitmap::~CGenericDirectScreenBitmap() sl@0: { sl@0: Close(); sl@0: } sl@0: sl@0: // sl@0: // Create a DSB object using a region of the screen previously sl@0: // 'claimed' via the Window Servers Direct Screen Acceass API sl@0: // sl@0: TInt CGenericDirectScreenBitmap::Create(const TRect& aScreenRect, TSettingsFlags aSettingsFlags) sl@0: { sl@0: __ASSERT_ALWAYS(!iCreated, Panic(EPanicAlreadyCreated)); sl@0: sl@0: __ASSERT_ALWAYS((aSettingsFlags&(EDoubleBuffer|EIncrementalUpdate)) != sl@0: (EDoubleBuffer|EIncrementalUpdate), Panic(EPanicInvalidMode)); sl@0: sl@0: //Initialize iScreenNo - its value occupies upper 5 bits of aSettingsFlags. sl@0: //(32 - 1) is max allowed screen number sl@0: iScreenNo = static_cast ((aSettingsFlags & 0xF8000000) >> 27); sl@0: sl@0: // Find the screen dimensions from the HAL and validate sl@0: TInt screenWidth = 0; sl@0: TInt screenHeight = 0; sl@0: sl@0: TInt r = HAL::Get(iScreenNo, HALData::EDisplayXPixels, screenWidth); sl@0: if (r!=KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: sl@0: r = HAL::Get(iScreenNo, HALData::EDisplayYPixels,screenHeight); sl@0: if (r!=KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: sl@0: __ASSERT_ALWAYS(aScreenRect.iTl.iX >= 0 && sl@0: aScreenRect.iTl.iY >= 0 && sl@0: ((aScreenRect.Width() <= screenWidth && sl@0: aScreenRect.Height() <= screenHeight) sl@0: || sl@0: (aScreenRect.Width() <= screenHeight && sl@0: aScreenRect.Height() <= screenWidth)), sl@0: Panic(EPanicOutOfBounds)); sl@0: sl@0: __ASSERT_ALWAYS(aScreenRect.Width() > 0 && sl@0: aScreenRect.Height() > 0, Panic(EPanicInvalidRect)); sl@0: sl@0: iUpdateRect = aScreenRect; sl@0: iSettingsFlags = aSettingsFlags; sl@0: sl@0: r = DoCreate(); sl@0: if(r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: sl@0: // Check that LHS is word-aligned sl@0: const TUint pixelStartInBytes = aScreenRect.iTl.iX*iBytesPerPixel; sl@0: const TUint pixelEndInBytes = aScreenRect.iBr.iX*iBytesPerPixel; sl@0: sl@0: // Check the alignment sl@0: __ASSERT_ALWAYS(!(pixelStartInBytes & 0x03), Panic(EPanicNotWordAligned)); sl@0: __ASSERT_ALWAYS(!(pixelEndInBytes & 0x03), Panic(EPanicNotWordAligned)); sl@0: sl@0: const TUint scanlineBytes = pixelEndInBytes-pixelStartInBytes; sl@0: sl@0: #ifndef __WINS__ sl@0: iVideoAddress += pixelStartInBytes + // X Offset sl@0: iUpdateRect.iTl.iY*iDisplayOffsetLines + // Y Offset sl@0: iDisplayOffsetPixel; // Pixel (Palette) Offset sl@0: #endif sl@0: sl@0: // Since this is a generic implementation, we only require one sl@0: // buffer for both incremental and double buffered mode sl@0: iBitmapInfo.iAddress = (TUint8*)User::Alloc(scanlineBytes * iUpdateRect.Height()); sl@0: if(!iBitmapInfo.iAddress) sl@0: return KErrNoMemory; sl@0: sl@0: iBitmapInfo.iSize = TSize(iUpdateRect.Width(), iUpdateRect.Height()); sl@0: iBitmapInfo.iLinePitch = scanlineBytes; sl@0: iBitmapInfo.iPhysicalAddress = 0; sl@0: sl@0: // All done sl@0: iCreated = ETrue; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: #ifndef __WINS__ sl@0: // sl@0: // Attempt to initialise using the HAL sl@0: // sl@0: TInt CGenericDirectScreenBitmap::DoCreate() sl@0: { sl@0: // For GCE, if multiple modes are supported, only one needs to be returned. sl@0: // On the emulator, what is returned via EDisplayMode can be set via ColorDepth setting in epoc.ini sl@0: // On the hardware, 24/32bpp color mode is returned via EDisplayMode as pre-defined. sl@0: TInt displayMode = 0; sl@0: TInt r1 = HAL::Get(iScreenNo, HALData::EDisplayMode, displayMode); sl@0: if (r1!=KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: sl@0: TInt bitsPerPixel = displayMode; sl@0: sl@0: r1 = HAL::Get(iScreenNo, HALData::EDisplayBitsPerPixel, bitsPerPixel); sl@0: if (r1!=KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: iBytesPerPixel = (bitsPerPixel+7) >> 3; sl@0: sl@0: // Store the important driver parameters to avoid HAL calls when drawing sl@0: iDisplayOffsetPixel = displayMode; sl@0: r1 = HAL::Get(iScreenNo, HALData::EDisplayOffsetToFirstPixel, iDisplayOffsetPixel); sl@0: if (r1!=KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: iDisplayOffsetLines = displayMode; sl@0: r1 = HAL::Get(iScreenNo, HALData::EDisplayOffsetBetweenLines, iDisplayOffsetLines); sl@0: if (r1!=KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: sl@0: TInt val = 0; sl@0: r1 = HAL::Get(iScreenNo, HALData::EDisplayMemoryHandle,val); sl@0: if (r1 == KErrNotSupported) sl@0: { sl@0: // EDisplayMemoryHandle is not supported, use the address instead sl@0: r1 = HAL::Get(iScreenNo, HALData::EDisplayMemoryAddress, iVideoAddress); sl@0: if (r1!=KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: } sl@0: else if (r1 == KErrNone) sl@0: { sl@0: // EDisplayMemoryHandle is supported, use the handle base address sl@0: __ASSERT_ALWAYS(val != 0, Panic(EPanicHandleReturnedIncorrect)); sl@0: RChunk chunk; sl@0: r1 = chunk.SetReturnedHandle(val); sl@0: if (r1 != KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: iChunk = chunk; sl@0: r1 = iChunk.Duplicate(RThread(), EOwnerProcess); sl@0: chunk.Close(); sl@0: if (r1 != KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: iVideoAddress = (TInt)iChunk.Base(); sl@0: iHasChunk = ETrue; sl@0: } sl@0: else sl@0: { sl@0: return r1; sl@0: } sl@0: sl@0: // The HAL doesn't specify explicit dislpay modes, so we need sl@0: // to calculate the mode using bitsPerPixel and isMono sl@0: TBool isMono = displayMode; sl@0: r1 = HAL::Get(iScreenNo, HALData::EDisplayIsMono, isMono); sl@0: if (r1!=KErrNone) sl@0: { sl@0: return r1; sl@0: } sl@0: switch(bitsPerPixel) sl@0: { sl@0: // EGray2, EGray4, EGray16, EColor16 not supported on the hardware sl@0: // The generic scdv support EGray2, EGray4, EGray16, EColor16 on the emulator sl@0: // However, the low display modes should not be used. sl@0: case 1: sl@0: iBitmapInfo.iPixelShift = 0; sl@0: iBitmapInfo.iDisplayMode = EGray2; sl@0: iBytesPerPixel = 2; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatUnknown; sl@0: #endif sl@0: break; sl@0: case 2: sl@0: iBitmapInfo.iPixelShift = 1; sl@0: iBitmapInfo.iDisplayMode = EGray4; sl@0: iBytesPerPixel = 2; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatUnknown; sl@0: #endif sl@0: break; sl@0: case 4: sl@0: iBitmapInfo.iPixelShift = 2; sl@0: iBitmapInfo.iDisplayMode = isMono ? EGray16 : EColor16; sl@0: iBytesPerPixel = 2; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatUnknown; sl@0: #endif sl@0: break; sl@0: case 8: sl@0: iBitmapInfo.iPixelShift = 3; sl@0: iBitmapInfo.iDisplayMode = isMono ? EGray256 : EColor256; sl@0: iBytesPerPixel = 2; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatUnknown; sl@0: #endif sl@0: break; sl@0: case 12: sl@0: iBitmapInfo.iPixelShift = 4; sl@0: iBitmapInfo.iDisplayMode = EColor4K; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatXRGB_4444; sl@0: #endif sl@0: break; sl@0: case 16: sl@0: iBitmapInfo.iPixelShift = 4; sl@0: iBitmapInfo.iDisplayMode = EColor64K; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatRGB_565; sl@0: #endif sl@0: break; sl@0: case 24: sl@0: case 32: sl@0: iBitmapInfo.iPixelShift = 5; sl@0: iBitmapInfo.iDisplayMode = EColor16MA; sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iPixelFormat = EUidPixelFormatARGB_8888; sl@0: iBytesPerPixel = 4; sl@0: #endif sl@0: break; sl@0: default: sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: TInt ret = iSurfaceUpdater.Construct(iScreenNo,iPixelFormat,displayMode); sl@0: if (ret != KErrNone) sl@0: { sl@0: return ret; sl@0: } sl@0: #endif sl@0: sl@0: return KErrNone; sl@0: } sl@0: #endif sl@0: sl@0: #ifdef __WINS__ sl@0: // sl@0: // Attempt to initialise for WINS sl@0: // This is intended for use if HAL initialisation fails. sl@0: // sl@0: TInt CGenericDirectScreenBitmap::DoCreate() sl@0: { sl@0: RWindows* window = ::WindowHandler(iScreenNo); sl@0: if(window) sl@0: { sl@0: iBitmapInfo.iDisplayMode = window->iDisplayMode; sl@0: iDisplayOffsetLines = window->iEpocBitmapLinePitch; sl@0: iDisplayOffsetPixel = 0; sl@0: sl@0: switch(iBitmapInfo.iDisplayMode) sl@0: { sl@0: case EGray2: sl@0: iBitmapInfo.iPixelShift = 0; sl@0: iBytesPerPixel = 1; sl@0: break; sl@0: case EGray4: sl@0: iBitmapInfo.iPixelShift = 1; sl@0: iBytesPerPixel = 1; sl@0: break; sl@0: case EGray16: sl@0: case EColor16: sl@0: iBitmapInfo.iPixelShift = 2; sl@0: iBytesPerPixel = 1; sl@0: break; sl@0: case EGray256: sl@0: case EColor256: sl@0: iBitmapInfo.iPixelShift = 3; sl@0: iBytesPerPixel = 1; sl@0: break; sl@0: case EColor4K: sl@0: case EColor64K: sl@0: iBitmapInfo.iPixelShift = 4; sl@0: iBytesPerPixel = 2; sl@0: break; sl@0: case EColor16M: sl@0: iBitmapInfo.iPixelShift = 5; sl@0: iBytesPerPixel = 3; sl@0: break; sl@0: case ERgb: sl@0: case EColor16MU: sl@0: case EColor16MA: sl@0: case EColor16MAP: sl@0: iBitmapInfo.iPixelShift = 5; sl@0: iBytesPerPixel = 4; sl@0: break; sl@0: default: sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: else sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: // sl@0: // Begin update - aBitmapinfo returns the current bitmap sl@0: // sl@0: TInt CGenericDirectScreenBitmap::BeginUpdate(TAcceleratedBitmapInfo& aBitmapInfo) sl@0: { sl@0: __ASSERT_ALWAYS(iCreated, Panic(EPanicNotCreated)); sl@0: aBitmapInfo = iBitmapInfo; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: #ifdef __WINS__ sl@0: sl@0: void CGenericDirectScreenBitmap::WinsUpdate(const TRect& aScreenRect) sl@0: { sl@0: const TUint dS = iBitmapInfo.iLinePitch; sl@0: const TUint offY = aScreenRect.iTl.iY - iUpdateRect.iTl.iY; sl@0: TUint8* pS = iBitmapInfo.iAddress + (offY*dS); sl@0: RWindows* window = ::WindowHandler(iScreenNo); sl@0: TInt orientation=window->Orientation(); sl@0: TRect orientedRect; sl@0: TSize orientedSize; sl@0: sl@0: orientedSize = window->GetOrientedSize(); sl@0: orientedRect = window->GetOrientedRect(aScreenRect); sl@0: sl@0: TInt BrX = iUpdateRect.iBr.iX-1; sl@0: TInt BrY = iUpdateRect.iBr.iY-1; sl@0: sl@0: for(TInt y=aScreenRect.iTl.iY; y < aScreenRect.iBr.iY; y++) sl@0: { sl@0: sl@0: TRgb pixelColor; sl@0: sl@0: TInt xSource = aScreenRect.iTl.iX-iUpdateRect.iTl.iX; sl@0: sl@0: for(TInt x = aScreenRect.iTl.iX; x < aScreenRect.iBr.iX; x++) sl@0: { sl@0: TUint8* pD; sl@0: sl@0: switch(orientation) sl@0: { sl@0: case 0: sl@0: pD = window->PixelAddress(x, y); sl@0: break; sl@0: case 1: sl@0: pD = window->PixelAddress(y, BrX-x); sl@0: break; sl@0: case 2: sl@0: pD = window->PixelAddress(BrX-x, BrY-y); sl@0: break; sl@0: case 3: sl@0: pD = window->PixelAddress(BrY-y, x); sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: sl@0: // Convert the user colour to RGB, as required by the WINS Emulator sl@0: pixelColor = ExtractRgb(pS, xSource++); sl@0: sl@0: pD[0] = TUint8(pixelColor.Blue()); sl@0: pD[1] = TUint8(pixelColor.Green()); sl@0: pD[2] = TUint8(pixelColor.Red()); sl@0: sl@0: } sl@0: pS += dS; sl@0: } sl@0: sl@0: RRegion region; sl@0: region.AddRect(orientedRect); sl@0: window->Update(region,orientedSize); sl@0: region.Close(); sl@0: } sl@0: sl@0: #endif sl@0: sl@0: // sl@0: // End Update - Commit changes to the Frame Buffer sl@0: // sl@0: void CGenericDirectScreenBitmap::EndUpdate(TRequestStatus& aComplete) sl@0: { sl@0: __ASSERT_ALWAYS(iCreated, Panic(EPanicNotCreated)); sl@0: sl@0: TUint8* pS = iBitmapInfo.iAddress; sl@0: const TUint dS = iBitmapInfo.iLinePitch; sl@0: sl@0: #ifdef __WINS__ sl@0: sl@0: WinsUpdate(iUpdateRect); sl@0: sl@0: #else sl@0: TUint8* pD = (TUint8*)iVideoAddress; sl@0: const TUint dD = iDisplayOffsetLines; sl@0: sl@0: for(TInt y=iUpdateRect.Height(); y>0; y--) sl@0: { sl@0: Mem::Move((void *)pD, (void *)pS, dS); sl@0: pS += dS; sl@0: pD += dD; sl@0: } sl@0: #endif sl@0: sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: // update the region and complete notification on the client's TRequestStatus sl@0: // This means the backbuffer is held up until the surface update has completed sl@0: // notification. sl@0: iSurfaceUpdater.UpdateRegion(iUpdateRect); sl@0: iSurfaceUpdater.Update(aComplete); sl@0: #else sl@0: // In the generic implementation, complete the request immediately to allow the client sl@0: // to render to the back buffer sl@0: TRequestStatus* pComplete=&aComplete; sl@0: User::RequestComplete(pComplete,KErrNone); sl@0: #endif sl@0: sl@0: } sl@0: sl@0: // sl@0: // End Update - Commit changes within the given area to the Frame Buffer sl@0: // sl@0: void CGenericDirectScreenBitmap::EndUpdate(const TRect& aScreenRect, TRequestStatus& aComplete) sl@0: { sl@0: __ASSERT_ALWAYS(iCreated, Panic(EPanicNotCreated)); sl@0: sl@0: __ASSERT_ALWAYS(aScreenRect.iTl.iX >= iUpdateRect.iTl.iX && sl@0: aScreenRect.iTl.iY >= iUpdateRect.iTl.iY && sl@0: aScreenRect.iBr.iX <= iUpdateRect.iBr.iX && sl@0: aScreenRect.iBr.iY <= iUpdateRect.iBr.iY, Panic(EPanicOutOfBounds)); sl@0: sl@0: __ASSERT_ALWAYS(aScreenRect.Width() > 0 && sl@0: aScreenRect.Height() > 0, Panic(EPanicInvalidRect)); sl@0: sl@0: // We can only use this functionality in Incremental Update mode sl@0: __ASSERT_ALWAYS(iSettingsFlags == CDirectScreenBitmap::EIncrementalUpdate, Panic(EPanicInvalidMode)); sl@0: sl@0: const TUint offY = aScreenRect.iTl.iY - iUpdateRect.iTl.iY; sl@0: sl@0: const TUint dS = iBitmapInfo.iLinePitch; sl@0: sl@0: #ifdef __WINS__ sl@0: sl@0: WinsUpdate(aScreenRect); sl@0: sl@0: #else sl@0: sl@0: TInt xLeft = aScreenRect.iTl.iX*iBytesPerPixel; sl@0: TInt xRight = aScreenRect.iBr.iX*iBytesPerPixel; sl@0: sl@0: // We have already tested the limits against iUpdateRect, which is sl@0: // word aligned, so we are safe to perform a round up/down here sl@0: // without fear of overrunning the buffer. sl@0: sl@0: xLeft &= ~0x03; sl@0: xRight = (xRight+0x03)&~0x03; sl@0: sl@0: const TUint offX = xLeft - iUpdateRect.iTl.iX*iBytesPerPixel; sl@0: sl@0: const TUint bytesToCopy = xRight-xLeft; sl@0: sl@0: const TUint dD = iDisplayOffsetLines; sl@0: sl@0: TUint8* pS = iBitmapInfo.iAddress + offX + (offY*dS); sl@0: TUint8* pD = (TUint8*)iVideoAddress + offX + (offY*dD); sl@0: sl@0: for(TInt y=aScreenRect.Height(); y>0; y--) sl@0: { sl@0: Mem::Move((void *)pD, (void *)pS, bytesToCopy); sl@0: pS += dS; sl@0: pD += dD; sl@0: } sl@0: #endif sl@0: sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: // update the region and complete notification on the client's TRequestStatus sl@0: // This means the backbuffer is held up until the surface update has completed sl@0: // notification. sl@0: iSurfaceUpdater.UpdateRegion(iUpdateRect); sl@0: iSurfaceUpdater.Update(aComplete); sl@0: #else sl@0: // In the generic implementation, complete the request immediately to allow the client sl@0: // to render to the back buffer sl@0: TRequestStatus* pComplete=&aComplete; sl@0: User::RequestComplete(pComplete,KErrNone); sl@0: #endif sl@0: sl@0: } sl@0: sl@0: #ifdef __WINS__ sl@0: // sl@0: // Extracts the RGB value of the specidied pixel from the buffer sl@0: // sl@0: TRgb CGenericDirectScreenBitmap::ExtractRgb(TUint8* aBuffer,TInt aPixelOffset) const sl@0: { sl@0: switch (iBitmapInfo.iDisplayMode) sl@0: { sl@0: case EGray2: sl@0: { sl@0: TUint8 byte = *(aBuffer + (aPixelOffset >> 3)); sl@0: if (byte & (1 << (aPixelOffset & 7))) sl@0: return KRgbWhite; sl@0: return KRgbBlack; sl@0: } sl@0: case EGray4: sl@0: { sl@0: TUint8 byte = *(aBuffer + (aPixelOffset >> 2)); sl@0: byte >>= ((aPixelOffset & 3) << 1); sl@0: return TRgb::_Gray4(byte & 3); sl@0: } sl@0: case EGray16: sl@0: { sl@0: TUint8 byte = *(aBuffer + (aPixelOffset >> 1)); sl@0: if (aPixelOffset & 1) sl@0: byte >>= 4; sl@0: return TRgb::_Gray16(byte & 0xf); sl@0: } sl@0: case EGray256: sl@0: return TRgb::_Gray256(*(aBuffer + aPixelOffset)); sl@0: case EColor16: sl@0: { sl@0: TUint8 byte = *(aBuffer + (aPixelOffset >> 1)); sl@0: if (aPixelOffset & 1) sl@0: byte >>= 4; sl@0: return TRgb::Color16(byte & 0xf); sl@0: } sl@0: case EColor256: sl@0: return TRgb::Color256(*(aBuffer + aPixelOffset)); sl@0: case EColor4K: sl@0: { sl@0: TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset); sl@0: return TRgb::_Color4K(doubleByte & 0xfff); sl@0: } sl@0: case EColor64K: sl@0: { sl@0: TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset); sl@0: return TRgb::_Color64K(doubleByte); sl@0: } sl@0: case EColor16M: sl@0: { sl@0: aBuffer += aPixelOffset * 3; sl@0: TInt value = *aBuffer++; sl@0: value |= *aBuffer++ << 8; sl@0: value |= *aBuffer << 16; sl@0: return TRgb::_Color16M(value); sl@0: } sl@0: case ERgb: sl@0: return *(((TRgb*)aBuffer) + aPixelOffset); sl@0: case EColor16MU: sl@0: { sl@0: aBuffer += aPixelOffset * 4; sl@0: TInt value = *aBuffer++; sl@0: value |= *aBuffer++ << 8; sl@0: value |= *aBuffer << 16; sl@0: return TRgb::_Color16MU(value); sl@0: } sl@0: case EColor16MA: sl@0: { sl@0: aBuffer += aPixelOffset * 4; sl@0: TInt value = *aBuffer++; sl@0: value |= *aBuffer++ << 8; sl@0: value |= *aBuffer++ << 16; sl@0: value |= *aBuffer << 24; sl@0: return TRgb::_Color16MA(value); sl@0: } sl@0: case EColor16MAP: sl@0: { sl@0: aBuffer += aPixelOffset * 4; sl@0: TInt value = *aBuffer++; sl@0: value |= *aBuffer++ << 8; sl@0: value |= *aBuffer++ << 16; sl@0: value |= *aBuffer << 24; sl@0: return TRgb::_Color16MAP(value); sl@0: } sl@0: default: sl@0: break; sl@0: }; sl@0: return KRgbBlack; sl@0: } sl@0: #endif sl@0: sl@0: sl@0: // sl@0: // Close - Deallocate resources and cancel outstanding updates sl@0: // sl@0: void CGenericDirectScreenBitmap::Close() sl@0: { sl@0: if(iCreated) sl@0: { sl@0: #ifdef SYMBIAN_GRAPHICS_GCE sl@0: iSurfaceUpdater.CancelUpdateNotification(); sl@0: #endif sl@0: User::Free(iBitmapInfo.iAddress); sl@0: iBitmapInfo.iAddress = NULL; sl@0: iCreated = EFalse; sl@0: } sl@0: if (iHasChunk) sl@0: { sl@0: iChunk.Close(); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // Panic the user if a serious error occurs sl@0: // sl@0: void CGenericDirectScreenBitmap::Panic(TDsbPanic aPanic) sl@0: { sl@0: _LIT( KPanicString, "CGenericDirectScreenBitmap" ); sl@0: User::Panic( KPanicString, aPanic ); sl@0: } sl@0: sl@0: