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