graphicsdeviceinterface/screendriver/sbit/Cdsb.cpp
changeset 0 5d03bc08d59c
child 26 15986eb6c500
child 45 36b2e23a8629
--- /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 );
+	}
+
+