Home | History | Annotate | Download | only in EKA2
      1 #include "dsa.h"
      2 #include "sdlepocapi.h"
      3 #include <cdsb.h>
      4 
      5 
      6 LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
      7 	{
      8 	return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
      9 	}
     10 
     11 
     12 NONSHARABLE_CLASS(TDsa)
     13 	{
     14 	public:
     15 		inline TDsa(const CDsa& aDsa);
     16 		inline TBool IsFlip() const;
     17 		inline TBool IsTurn() const;
     18 		inline const TSize& SwSize() const;
     19 		inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const;
     20 	private:
     21 		const CDsa& iDsa;
     22 	};
     23 
     24 
     25 inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa)
     26 	{
     27 	}
     28 
     29 inline TBool TDsa::IsTurn() const
     30 	{
     31 	return iDsa.iStateFlags & CDsa::EOrientation90;
     32 	}
     33 
     34 inline TBool TDsa::IsFlip() const
     35 	{
     36 	return iDsa.iStateFlags & CDsa::EOrientation180;
     37 	}
     38 
     39 inline const TSize& TDsa::SwSize() const
     40 	{
     41 	return iDsa.SwSize();
     42 	}
     43 
     44 inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const
     45 	{
     46 	iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight);
     47 	}
     48 
     49 template<class T, class S>
     50 void ClipCopy(const TDsa& iDsa, TUint8* aTarget,
     51  					const TUint8* aSource,
     52  					const TRect& aUpdateRect,
     53  					const TRect& aSourceRect)
     54 	{
     55 	const S* source = reinterpret_cast<const S*>(aSource);
     56 	const TInt lineWidth = aSourceRect.Width();
     57 
     58 	source += (aUpdateRect.iTl.iY * lineWidth);
     59 	const TInt sourceStartOffset = aUpdateRect.iTl.iX;
     60 	source += sourceStartOffset;
     61 
     62 	T* targetPtr = reinterpret_cast<T*>(aTarget);
     63 
     64 	const TInt scanLineWidth = iDsa.SwSize().iWidth;
     65 
     66 	targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth;
     67 	const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
     68 
     69 	targetPtr += targetStartOffset;
     70 
     71 
     72 	const TInt height = aUpdateRect.Height();
     73 
     74 	const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth;
     75 	const TInt copyLen = aUpdateRect.Width();
     76 
     77 
     78 	if(iDsa.IsFlip())
     79 		{
     80 
     81 		targetPtr += scanLineWidth *  (height - 1);
     82 
     83 		for(TInt i = 0; i < height; i++) //source is always smaller
     84 			{
     85 			iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
     86 			source += lineMove;
     87 			targetPtr -= scanLineWidth;
     88 			}
     89 		}
     90 	else
     91 		{
     92 
     93 
     94 		for(TInt i = 0; i < height; i++) //source is always smaller
     95 			{
     96 			iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
     97 			source += lineMove;
     98 			targetPtr += scanLineWidth; // >> 2;
     99 			}
    100 		}
    101 
    102 	}
    103 
    104 
    105 
    106 NONSHARABLE_CLASS(CDsaA) : public CDsa
    107 	{
    108 	public:
    109 		CDsaA(RWsSession& aSession);
    110 	private:
    111 		~CDsaA();
    112 		TUint8* LockSurface();
    113 		void UnlockHWSurfaceRequestComplete();
    114 		void UnlockHwSurface();
    115 		void CreateSurfaceL();
    116 		void Wipe(TInt aLength);
    117 		void Free();
    118 		void Update(CFbsBitmap& aBmp);
    119 		void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
    120 		TInt ExternalUpdate();
    121 	//	void ExternalUpdate();
    122 	protected:
    123 		CFbsBitmap* iBmp;
    124 		CFbsBitmap* iCopyBmp;
    125 	};
    126 
    127 
    128 CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession)
    129 	{
    130 	}
    131 
    132 
    133 void CDsaA::Free()
    134 	{
    135 	delete iBmp;
    136 	iBmp = NULL;
    137 	}
    138 
    139 CDsaA::~CDsaA()
    140 	{
    141 	__ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
    142 	delete iCopyBmp;
    143 	}
    144 
    145 TUint8* CDsaA::LockSurface()
    146 	{
    147 	iBmp->LockHeap();
    148 	return reinterpret_cast<TUint8*>(iBmp->DataAddress());
    149 	}
    150 
    151 void CDsaA::UnlockHWSurfaceRequestComplete()
    152 	{
    153 	PANIC(KErrNotSupported);
    154 	}
    155 
    156 void CDsaA::UnlockHwSurface()
    157 	{
    158 	iBmp->UnlockHeap();
    159 	SetUpdating(EFalse);
    160 	Update(*iBmp);
    161 	}
    162 
    163 void CDsaA::Update(CFbsBitmap& aBmp)
    164 	{
    165 	if(!Blitter(aBmp))
    166 		{
    167 		if(SwSize() == HwRect().Size())
    168 			Dsa().Gc()->BitBlt(HwRect().iTl, &aBmp);
    169 		else
    170 			Dsa().Gc()->DrawBitmap(HwRect(), &aBmp);
    171 		}
    172 	DrawOverlays();
    173 	Dsa().ScreenDevice()->Update();
    174 	}
    175 void CDsaA::CreateSurfaceL()
    176 	{
    177 	delete iBmp;
    178 	iBmp = NULL;
    179 	iBmp  = new (ELeave) CFbsBitmap();
    180 	User::LeaveIfError(iBmp->Create(SwSize(), DisplayMode()));
    181 	}
    182 
    183 void CDsaA::Wipe(TInt aLength) //dont call in drawing
    184 	{
    185 	iBmp->LockHeap();
    186 	Mem::FillZ(iBmp->DataAddress(), aLength);
    187 	iBmp->UnlockHeap();
    188 	}
    189 
    190 
    191 
    192 TInt CDsaA::ExternalUpdate()
    193 	{
    194 	if(iCopyBmp->Handle() == 0)
    195 		{
    196 		const TInt err = iCopyBmp->Duplicate(iBmp->Handle());
    197 		if(err != KErrNone)
    198 			return err;
    199 		}
    200 	Update(*iCopyBmp);
    201 	return KErrNone;
    202 	}
    203 
    204 void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
    205 	{
    206 	iCopyBmp = new (ELeave) CFbsBitmap();
    207 	CDsa::ConstructL(aWindow, aDevice);
    208 	}
    209 
    210 
    211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    212 
    213 NONSHARABLE_CLASS(MDsbObs)
    214 	{
    215 	public:
    216 		virtual void SurfaceReady() = 0;
    217 		virtual CDirectScreenBitmap& Dsb() = 0;
    218 	};
    219 
    220 NONSHARABLE_CLASS(CDsbSurface) : public CActive
    221 	{
    222 	public:
    223 		CDsbSurface(MDsbObs& aDsb);
    224 		TUint8* Address();
    225 		void Complete();
    226 		~CDsbSurface();
    227 	private:
    228 		void RunL();
    229 		void DoCancel();
    230 	private:
    231 		MDsbObs& iDsb;
    232 		TUint8* iAddress;
    233 	};
    234 
    235 CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
    236 	{
    237 	CActiveScheduler::Add(this);
    238 	}
    239 
    240 CDsbSurface::~CDsbSurface()
    241 	{
    242 	Cancel();
    243 	}
    244 
    245 void CDsbSurface::Complete()
    246 	{
    247 	if(iAddress != NULL && !IsActive())
    248 		{
    249 		iAddress = NULL;
    250 		SetActive();
    251 		iDsb.Dsb().EndUpdate(iStatus);
    252 		}
    253 	}
    254 
    255 TUint8* CDsbSurface::Address()
    256 	{
    257 	if(iAddress == NULL && !IsActive())
    258 		{
    259 		TAcceleratedBitmapInfo info;
    260 		if(KErrNone == iDsb.Dsb().BeginUpdate(info))
    261 			iAddress = info.iAddress;
    262 		}
    263 	return iAddress;
    264 	}
    265 
    266 void CDsbSurface::RunL()
    267 	{
    268 	iDsb.SurfaceReady();
    269 	}
    270 
    271 void CDsbSurface::DoCancel()
    272 	{
    273 	//empty
    274 	}
    275 
    276 NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs
    277 	{
    278 	public:
    279 		CDsaB(RWsSession& aSession, TInt aFlags);
    280 	private:
    281 		~CDsaB();
    282 		TUint8* LockSurface();
    283 		void UnlockHWSurfaceRequestComplete();
    284 		void UnlockHwSurface();
    285 		void CreateSurfaceL();
    286 		void Wipe(TInt aLength);
    287 		void RecreateL();
    288 		void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
    289 		CDirectScreenBitmap& Dsb();
    290 		void SurfaceReady();
    291 		TInt ExternalUpdate();
    292 	private:
    293 		CDsbSurface* iSurface1;
    294 		CDsbSurface* iSurface2;
    295 		CDirectScreenBitmap* iDsb;
    296 		TInt iType;
    297 	};
    298 
    299 CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsa(aSession), iType(aFlags)
    300 	{
    301 	}
    302 
    303 
    304 
    305 void CDsaB::UnlockHWSurfaceRequestComplete()
    306 	{
    307 	iSurface1->Complete();
    308 	if(iSurface2 != NULL)
    309 		iSurface2->Complete();
    310 	}
    311 
    312 void CDsaB::CreateSurfaceL()
    313 	{
    314 	__ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported));
    315 	}
    316 
    317 void CDsaB::Wipe(TInt aLength) //dont call in drawing
    318 	{
    319 	TUint8* addr = LockSurface();
    320 	if(addr != NULL)
    321 		{
    322 		Mem::FillZ(addr, aLength);
    323 		UnlockHwSurface();
    324 		}
    325 	}
    326 
    327 
    328 void CDsaB::UnlockHwSurface()
    329 	{
    330 	EpocSdlEnv::Request(CDsa::ERequestUpdate);
    331 	}
    332 
    333 TUint8* CDsaB::LockSurface()
    334 	{
    335 	TUint8* addr =  iSurface1->Address();
    336 	if(addr == NULL && iSurface2 != NULL)
    337 		addr =  iSurface2->Address();
    338 	SetUpdating(addr == NULL);
    339 	return addr;
    340 	}
    341 
    342 void CDsaB::SurfaceReady()
    343 	{
    344 	SetUpdating(EFalse);
    345 	}
    346 
    347 CDirectScreenBitmap& CDsaB::Dsb()
    348 	{
    349 	return *iDsb;
    350 	}
    351 
    352 void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
    353 	{
    354 	if(iDsb == NULL)
    355 		iDsb = CDirectScreenBitmap::NewL();
    356 	CDsa::ConstructL(aWindow, aDevice);
    357 	if(iSurface1 == NULL)
    358 		iSurface1 = new (ELeave) CDsbSurface(*this);
    359 	if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer)
    360 		iSurface2 = new (ELeave) CDsbSurface(*this);
    361 	}
    362 
    363 CDsaB::~CDsaB()
    364 	{
    365 	delete iSurface1;
    366 	delete iSurface2;
    367 	delete iDsb;
    368 	}
    369 
    370 void CDsaB::RecreateL()
    371 	{
    372     iDsb->Close();
    373     iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType));
    374 	}
    375 
    376 TInt CDsaB::ExternalUpdate()
    377 	{
    378 	if(LockSurface())
    379 		{
    380 		UnlockHWSurfaceRequestComplete();
    381 		return KErrNone;
    382 		}
    383 	return KErrNotReady;
    384 	}
    385 
    386 
    387 /////////////////////////////////////////////////////////////////////////////////////////////////////
    388 
    389 
    390 CDsa* CDsa::CreateL(RWsSession& aSession)
    391 	{
    392 	if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB))
    393 		{
    394 		TInt flags = CDirectScreenBitmap::ENone;
    395 		if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer))
    396 			flags |= CDirectScreenBitmap::EDoubleBuffer;
    397 		if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate))
    398 			flags |= CDirectScreenBitmap::EIncrementalUpdate;
    399 		return new (ELeave) CDsaB(aSession, flags);
    400 		}
    401     else
    402         return new (ELeave) CDsaA(aSession);
    403 	}
    404 
    405 
    406 void CDsa::RecreateL()
    407 	{
    408 	}
    409 
    410 void CDsa::Free()
    411 	{
    412 	}
    413 
    414 TSize CDsa::WindowSize() const
    415 	{
    416 	TSize size = iSwSize;
    417 	if(iStateFlags & EOrientation90)
    418 		{
    419 		const TInt tmp = size.iWidth;
    420 		size.iWidth = size.iHeight;
    421 		size.iHeight = tmp;
    422 		}
    423 	return size;
    424 	}
    425 
    426 void CDsa::SetSuspend()
    427 	{
    428 	iStateFlags |= ESdlThreadSuspend;
    429 	}
    430 
    431 void CDsa::ReleaseStop()
    432 	{
    433 	iStateFlags &= ~ESdlThreadExplicitStop;
    434 	}
    435 
    436 
    437 TBool CDsa::Stopped() const
    438 	{
    439 	return (iStateFlags & ESdlThreadExplicitStop);
    440 	}
    441 
    442 void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation)
    443 	{
    444 	TInt flags = 0;
    445 	switch(aOrientation)
    446 		{
    447 		case CSDL::EOrientation90:
    448 			flags = EOrientation90;
    449 			break;
    450 		case CSDL::EOrientation180:
    451 			flags = EOrientation180;
    452 			break;
    453 		case CSDL::EOrientation270:
    454 			flags = EOrientation90 | EOrientation180;
    455 			break;
    456 		case CSDL::EOrientation0:
    457 			flags = 0;
    458 			break;
    459 		}
    460 	if(flags != (iStateFlags & EOrientationFlags))
    461 		{
    462 		iStateFlags |= EOrientationChanged;
    463 		iNewFlags = flags; //cannot be set during drawing...
    464 		}
    465 	}
    466 
    467 CDsa::~CDsa()
    468     {
    469     if(iDsa != NULL)
    470         {
    471         iDsa->Cancel();
    472         }
    473     iOverlays.Close();
    474     delete iDsa;
    475     User::Free(iLut256);
    476     }
    477 
    478 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
    479     {
    480     if(iDsa != NULL)
    481     	{
    482     	iDsa->Cancel();
    483     	delete iDsa;
    484     	iDsa = NULL;
    485     	}
    486 
    487     iDsa = CDirectScreenAccess::NewL(
    488     				iSession,
    489 					aDevice,
    490 					aWindow,
    491 					*this);
    492 
    493 	if(iLut256 == NULL)
    494 		iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32));
    495 	iTargetMode = aWindow.DisplayMode();
    496 	iTargetBpp = BytesPerPixel(DisplayMode());
    497 	iScreenRect = TRect(aWindow.Position(), aWindow.Size());
    498 	SetTargetRect();
    499     RestartL();
    500     }
    501 
    502 void CDsa::DrawOverlays()
    503 	{
    504 	const TInt last = iOverlays.Count() - 1;
    505 	for(TInt i = last; i >= 0 ; i--)
    506 		iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize());
    507 	}
    508 
    509 TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
    510 	{
    511 	TInt i;
    512 	for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++)
    513 		{}
    514 	const TOverlay overlay = {&aOverlay, aPriority};
    515 	return iOverlays.Insert(overlay, i);
    516 	}
    517 
    518 TInt CDsa::RemoveOverlay(MOverlay& aOverlay)
    519 	{
    520 	for(TInt i = 0; i < iOverlays.Count(); i++)
    521 		{
    522 		if(iOverlays[i].iOverlay == &aOverlay)
    523 			{
    524 			iOverlays.Remove(i);
    525 			return KErrNone;
    526 			}
    527 		}
    528 	return KErrNotFound;
    529 	}
    530 
    531 void CDsa::LockPalette(TBool aLock)
    532 	{
    533 	if(aLock)
    534 		iStateFlags |= EPaletteLocked;
    535 	else
    536 		iStateFlags &= ~EPaletteLocked;
    537 	}
    538 TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette)
    539 	{
    540 	if(iLut256 == NULL)
    541 		return KErrNotFound;
    542 	const TInt count = aCount - aFirst;
    543 	if(count > 256)
    544 		return KErrArgument;
    545 	if(iStateFlags & EPaletteLocked)
    546 		return KErrNone;
    547 	for(TInt i = aFirst; i < count; i++) //not so busy here:-)
    548 		{
    549 		iLut256[i] = aPalette[i];
    550 		}
    551 	return KErrNone;
    552 	}
    553 
    554 
    555 
    556 void CDsa::RestartL()
    557     {
    558     //const TBool active = iDsa->IsActive();
    559 
    560     //if(!active)
    561 
    562     iDsa->StartL();
    563 
    564     const RRegion* r = iDsa->DrawingRegion();
    565     const TRect rect = r->BoundingRect();
    566     iDsa->Gc()->SetClippingRegion(r);
    567 
    568     if(rect != iScreenRect)
    569     	{
    570     //	iDsa->Cancel();
    571     	return ;
    572    	 	}
    573 
    574 
    575 
    576     //iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip
    577 	//targetrect shall no change
    578 	SetTargetRect();
    579 	RecreateL();
    580 
    581     iStateFlags |= ERunning;
    582 
    583     ReleaseStop();
    584     if(iStateFlags & ESdlThreadSuspend)
    585     	{
    586     	EpocSdlEnv::Resume();
    587     	iStateFlags &= ~ ESdlThreadSuspend;
    588     	}
    589     EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
    590     }
    591 
    592 CDsa::CDsa(RWsSession& aSession) :
    593  	iSession(aSession),
    594   	iStateFlags(0)
    595 	{
    596 //	CActiveScheduler::Add(this);
    597 	iCFTable[0] = CopyMem;
    598 	iCFTable[1] = CopyMemFlipReversed;
    599 	iCFTable[2] = CopyMemReversed;
    600 	iCFTable[3] = CopyMemFlip;
    601 
    602 	iCFTable[4] = Copy256;
    603 	iCFTable[5] = Copy256FlipReversed;
    604 	iCFTable[6] = Copy256Reversed;
    605 	iCFTable[7] = Copy256Flip;
    606 
    607 
    608 	iCFTable[8] = CopySlow;
    609 	iCFTable[9] = CopySlowFlipReversed;
    610 	iCFTable[10] = CopySlowReversed;
    611 	iCFTable[11] = CopySlowFlip;
    612 	}
    613 
    614 RWsSession& CDsa::Session()
    615 	{
    616 	return iSession;
    617 	}
    618 
    619 TInt CDsa::RedrawRequest()
    620 	{
    621 	if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
    622 		{
    623 		return ExternalUpdate();
    624 		}
    625 	return KErrNotReady;
    626 	}
    627 
    628 TUint8* CDsa::LockHwSurface()
    629 	{
    630 	if((iStateFlags & EUpdating) == 0) //else frame is skipped
    631 		{
    632 		return LockSurface();
    633 		}
    634 	return NULL;
    635 	}
    636 
    637 /*
    638 void CDsa::RunL()
    639 	{
    640 	iStateFlags &= ~EUpdating;
    641 	}
    642 
    643 
    644 void CDsa::DoCancel()
    645 	{
    646 	iStateFlags &= ~EUpdating;
    647 	//nothing can do, just wait?
    648 	}
    649 */
    650 
    651 
    652 TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode)
    653 	{
    654 	if(aHwSurface && aMode != DisplayMode())
    655 		return KErrArgument;
    656 
    657 	iSourceMode = aMode;
    658 
    659 	iSourceBpp = BytesPerPixel(aMode);
    660 
    661 	const TSize size = WindowSize();
    662 	if(aSize.iWidth > size.iWidth)
    663 		return KErrTooBig;
    664 	if(aSize.iHeight > size.iHeight)
    665 		return KErrTooBig;
    666 
    667 	TRAPD(err, CreateSurfaceL());
    668 	if(err != KErrNone)
    669 		return err;
    670 
    671 	SetCopyFunction();
    672 
    673 	return KErrNone;
    674 	}
    675 
    676 
    677 void CDsa::CreateZoomerL(const TSize& aSize)
    678 	{
    679 	iSwSize = aSize;
    680 	iStateFlags |= EResizeRequest;
    681 	CreateSurfaceL();
    682 	SetTargetRect();
    683 	}
    684 
    685 
    686 /*
    687 void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode)
    688 	{
    689 	CFbsBitmap* s = new CFbsBitmap();
    690 	s->Create(aSz, aMode);
    691 	s->LockHeap();
    692 	TUint32* addr = s->DataAddress();
    693 	Mem::Copy(addr, aData, aLength);
    694 	s->UnlockHeap();
    695 	s->Save(aName);
    696 	s->Reset();
    697 	delete s;
    698 	}
    699 
    700 void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz)
    701 	{
    702 	CFbsBitmap* s = new CFbsBitmap();
    703 	s->Create(aSz, EColor64K);
    704 	TBitmapUtil bmp(s);
    705 	bmp.Begin(TPoint(0, 0));
    706 	for(TInt j = 0; j < aSz.iHeight; j++)
    707 		{
    708 		bmp.SetPos(TPoint(0, j));
    709 		for(TInt i = 0; i < aSz.iWidth; i++)
    710 			{
    711 			bmp.SetPixel(*aData);
    712 			aData++;
    713 			bmp.IncXPos();
    714 			}
    715 		}
    716 	bmp.End();
    717 	s->Save(aName);
    718 	s->Reset();
    719 	delete s;
    720 	}
    721 
    722 TBuf<16> FooName(TInt aFoo)
    723 	{
    724 	TBuf<16> b;
    725 	b.Format(_L("C:\\pic%d.mbm"), aFoo);
    726 	return b;
    727 	}
    728 
    729 void ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos)
    730 	{
    731 	const TInt iSourceBpp = 1;
    732 	const TInt iTargetBpp = 4;
    733 	const TInt iScanLineWidth = 800;
    734 
    735 	TUint8* target = aTarget;
    736 	const TUint8* source = aSource;
    737 	const TInt lineWidth = aRect.Width();
    738 	source += iSourceBpp * (aRect.iTl.iY * lineWidth);
    739 	const TInt sourceStartOffset = iSourceBpp *  aRect.iTl.iX;
    740 	source += sourceStartOffset;
    741 	target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth);
    742 	const TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX);
    743 	target += targetStartOffset;
    744 	TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
    745 	const TInt targetWidth = iScanLineWidth >> 2;
    746 	const TInt height = aRect.Height();
    747 	}
    748 */
    749 /*
    750 void CDsa::ClipCopy(TUint8* aTarget,
    751  					const TUint8* aSource,
    752  					const TRect& aUpdateRect,
    753  					const TRect& aSourceRect) const
    754 	{
    755 	//TUint8* target = aTarget;
    756 	const TUint32* source = (const TUint32*) aSource;
    757 	const TInt lineWidth = aSourceRect.Width();
    758 
    759 	source +=  (aUpdateRect.iTl.iY * lineWidth);
    760 	const TInt sourceStartOffset =   aUpdateRect.iTl.iX;
    761 	source += sourceStartOffset;
    762 
    763 	TUint32* targetPtr = reinterpret_cast<TUint32*>(aTarget);
    764 
    765 	targetPtr +=  (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * SwSize().iWidth;
    766 	const TInt targetStartOffset =  (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
    767 
    768 	targetPtr += targetStartOffset;
    769 
    770 //	TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
    771 
    772 	const TInt targetWidth32 = SwSize().iWidth;
    773 
    774 	const TInt height = aUpdateRect.Height();
    775 
    776 	const TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
    777 	const TInt copyLen = aUpdateRect.Width();
    778 
    779 
    780 	if(iStateFlags & EOrientation180)
    781 		{
    782 
    783 		targetPtr += targetWidth32 *  (height - 1);
    784 
    785 		for(TInt i = 0; i < height; i++) //source is always smaller
    786 			{
    787 			iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height);
    788 			source += lineMove;
    789 			targetPtr -= targetWidth32;
    790 			}
    791 		}
    792 	else
    793 		{
    794 
    795 
    796 		for(TInt i = 0; i < height; i++) //source is always smaller
    797 			{
    798 			iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height);
    799 			source += lineMove;
    800 			targetPtr += targetWidth32; // >> 2;
    801 			}
    802 		}
    803 
    804 	}
    805 
    806 */
    807 
    808 void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos) const
    809 	{
    810 	TUint8* target = aTarget;
    811 	const TUint8* source = aSource;
    812 	const TInt lineWidth = aRect.Width();
    813 	source += iSourceBpp * (aRect.iTl.iY * lineWidth);
    814 	TInt sourceStartOffset = iSourceBpp *  aRect.iTl.iX;
    815 	source += sourceStartOffset;
    816 	target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth);
    817 	TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX);
    818 	target += targetStartOffset;
    819 	TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
    820 	const TInt targetWidth = iScanLineWidth >> 2;
    821 	const TInt height = aRect.Height();
    822 
    823 	TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
    824 
    825 	if(iStateFlags & EOrientation180)
    826 		{
    827 
    828 		targetPtr += targetWidth *  (height - 1);
    829 
    830 		for(TInt i = 0; i < height; i++) //source is always smaller
    831 			{
    832 			iCopyFunction(*this, targetPtr, source, lineWidth, height);
    833 			source += lineMove;
    834 			targetPtr -= targetWidth;
    835 			}
    836 		}
    837 	else
    838 		{
    839 
    840 
    841 		for(TInt i = 0; i < height; i++) //source is always smaller
    842 			{
    843 			iCopyFunction(*this, targetPtr, source, lineWidth, height);
    844 			source += lineMove;
    845 			targetPtr += targetWidth;
    846 			}
    847 		}
    848 
    849 	}
    850 
    851 
    852 
    853 	/*
    854 void CDsa::ClipCopy(TUint8* aTarget,
    855  					const TUint8* aSource,
    856  					const TRect& aUpdateRect,
    857  					const TRect& aSourceRect) const
    858  		{
    859  		const TDsa dsa(*this);
    860  		switch(iSourceBpp)
    861  			{
    862  			case 1:
    863  				::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
    864  				break;
    865  			case 2:
    866  				::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
    867  				break;
    868  			case 4:
    869  				::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
    870  				break;
    871  			}
    872  		}
    873 
    874 
    875 */
    876 
    877 
    878 
    879 void CDsa::Wipe() //dont call in drawing
    880 	{
    881 	if(IsDsaAvailable())
    882 		Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight);
    883 	}
    884 
    885 void CDsa::SetCopyFunction()
    886 	{
    887 	//calculate offset to correct function in iCFTable according to given parameters
    888 	TInt function = 0;
    889 	const TInt KCopyFunctions = 4;
    890 	const TInt KOffsetToNative = 0;
    891 	const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions;
    892 	const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
    893 	const TInt KOffsetTo90Functions = 1;
    894 	const TInt KOffsetTo180Functions = 2;
    895 
    896 	if(iSourceMode == DisplayMode())
    897 		function = KOffsetToNative; 		//0
    898 	else if(iSourceMode == EColor256)
    899 		function = KOffsetTo256;			//4
    900 	else
    901 		function = KOffsetToOtherModes; 	//8
    902 
    903 	if(iStateFlags & EOrientation90)
    904 		function += KOffsetTo90Functions; 	// + 1
    905 	if(iStateFlags & EOrientation180)
    906 		function += KOffsetTo180Functions; 	//+ 2
    907 
    908 	iCopyFunction = iCFTable[function];
    909 
    910 	Wipe();
    911 	}
    912 
    913 inline void Rotate(TRect& aRect)
    914 	{
    915 	const TInt dx = aRect.iBr.iX - aRect.iTl.iX;
    916 	const TInt dy = aRect.iBr.iY - aRect.iTl.iY;
    917 
    918 	aRect.iBr.iX = aRect.iTl.iX + dy;
    919 	aRect.iBr.iY = aRect.iTl.iY + dx;
    920 
    921 	const TInt tmp = aRect.iTl.iX;
    922 	aRect.iTl.iX = aRect.iTl.iY;
    923 	aRect.iTl.iY = tmp;
    924 	}
    925 
    926 /*
    927 int bar = 0;
    928 */
    929 /*
    930 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
    931 	{
    932 
    933 	if(iStateFlags & EOrientationChanged)
    934 		{
    935 		iStateFlags &= ~EOrientationFlags;
    936 		iStateFlags |= iNewFlags;
    937 		SetCopyFunction();
    938 		iStateFlags &= ~EOrientationChanged;
    939 	    EpocSdlEnv::WaitDeviceChange();
    940 	    return EFalse; //skip this frame as data is may be changed
    941 		}
    942 
    943 	if(iTargetAddr == NULL)
    944 		{
    945 		iTargetAddr = LockHwSurface();
    946 		}
    947 
    948 	TUint8* target = iTargetAddr;
    949 	if(target == NULL)
    950 		return EFalse;
    951 
    952 
    953 	TRect targetRect = TRect(TPoint(0, 0), SwSize());
    954 
    955 	TRect sourceRect = aRect;
    956 	TRect updateRect = aUpdateRect;
    957 
    958 //	TPoint move(0, 0);
    959 
    960 
    961 	if(iStateFlags & EOrientation90)
    962 		{
    963 		Rotate(sourceRect);
    964 		Rotate(updateRect);
    965 		}
    966 
    967 	if(iSourceMode != DisplayMode() ||  targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
    968 		{
    969 		sourceRect.Intersection(targetRect); //so source always smaller or equal than target
    970 		//updateRect.Intersection(targetRect);
    971 		ClipCopy(target, aBits, updateRect, sourceRect);
    972 		}
    973 	else
    974 		{
    975 		const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
    976 		Mem::Copy(target, aBits, byteCount);
    977 		}
    978 
    979 	return ETrue;
    980 	}
    981 	*/
    982 
    983 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
    984 	{
    985 
    986 	if(iStateFlags & EOrientationChanged)
    987 		{
    988 		iStateFlags &= ~EOrientationFlags;
    989 		iStateFlags |= iNewFlags;
    990 		SetCopyFunction();
    991 		iStateFlags &= ~EOrientationChanged;
    992 	    EpocSdlEnv::WaitDeviceChange();
    993 	    return EFalse; //skip this frame as data is may be changed
    994 		}
    995 
    996 	if(iTargetAddr == NULL)
    997 		{
    998 		iTargetAddr = LockHwSurface();
    999 		}
   1000 	TUint8* target = iTargetAddr;
   1001 	if(target == NULL)
   1002 		return EFalse;
   1003 
   1004 
   1005 	TRect targetRect = Rect();
   1006 	TRect sourceRect = aRect;
   1007 	TRect updateRect = aUpdateRect;
   1008 
   1009 	if(iStateFlags & EOrientation90)
   1010 		{
   1011 		Rotate(sourceRect);
   1012 		Rotate(updateRect);
   1013 		}
   1014 
   1015 	if(iSourceMode != DisplayMode() ||  targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
   1016 		{
   1017 		sourceRect.Intersection(targetRect); //so source always smaller or equal than target
   1018 		updateRect.Intersection(targetRect);
   1019 		ClipCopy(target, aBits, updateRect, sourceRect.iTl);
   1020 		}
   1021 	else
   1022 		{
   1023 		const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
   1024 		Mem::Copy(target, aBits, byteCount);
   1025 		}
   1026 
   1027 	return ETrue;
   1028 	}
   1029 void CDsa::UpdateSwSurface()
   1030 	{
   1031 	iTargetAddr = NULL;
   1032 	UnlockHwSurface();	//could be faster if does not use AO, but only check status before redraw, then no context switch needed
   1033 	}
   1034 
   1035 
   1036 void CDsa::Resume()
   1037 	{
   1038 	if(Stopped())
   1039 		Restart(RDirectScreenAccess::ETerminateRegion);
   1040 	}
   1041 
   1042 void CDsa::DoStop()
   1043 	{
   1044 	if(IsDsaAvailable())
   1045 		iStateFlags |= ESdlThreadExplicitStop;
   1046 	Stop();
   1047 	}
   1048 
   1049 void CDsa::Stop()
   1050 	{
   1051 	iStateFlags &= ~ERunning;
   1052 //	Cancel(); //can be called only from main!
   1053 	iDsa->Cancel();
   1054 	}
   1055 
   1056 void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
   1057 	{
   1058 //	iStateFlags |= EChangeNotify;
   1059 	Stop();
   1060 	}
   1061 
   1062 void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason)
   1063 	{
   1064 	if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart
   1065 		{
   1066 		TRAPD(err, RestartL());
   1067 		PANIC_IF_ERROR(err);
   1068 		}
   1069 	}
   1070 
   1071 void CDsa::SetBlitter(MBlitter* aBlitter)
   1072 	{
   1073 	iBlitter = aBlitter;
   1074 	}
   1075 
   1076 
   1077 TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const
   1078 	{
   1079 	TPoint pos = aPoint - iScreenRect.iTl;
   1080 	const TSize asz = iScreenRect.Size();
   1081 	if(iStateFlags & EOrientation180)
   1082 		{
   1083 		pos.iX = asz.iWidth - pos.iX;
   1084 		pos.iY = asz.iHeight - pos.iY;
   1085 		}
   1086 	if(iStateFlags & EOrientation90)
   1087 		{
   1088 		pos.iX = aPoint.iY;
   1089 		pos.iY = aPoint.iX;
   1090 		}
   1091 	pos.iX <<= 16;
   1092 	pos.iY <<= 16;
   1093 	pos.iX /= asz.iWidth;
   1094 	pos.iY /= asz.iHeight;
   1095 	pos.iX *= iSwSize.iWidth;
   1096 	pos.iY *= iSwSize.iHeight;
   1097 	pos.iX >>= 16;
   1098 	pos.iY >>= 16;
   1099 	return pos;
   1100 	}
   1101 
   1102 void CDsa::SetTargetRect()
   1103 	{
   1104 	iTargetRect = iScreenRect;
   1105 	if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio))
   1106 		{
   1107 		const TSize asz = iScreenRect.Size();
   1108 		const TSize sz = iSwSize;
   1109 
   1110 		TRect rect;
   1111 
   1112 		const TInt dh = (sz.iHeight << 16) / sz.iWidth;
   1113 
   1114 		if((asz.iWidth * dh ) >> 16 <= asz.iHeight)
   1115 			{
   1116 			rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16));
   1117 			}
   1118 		else
   1119 			{
   1120 			const TInt dw = (sz.iWidth << 16) / sz.iHeight;
   1121 	    	rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight));
   1122 			}
   1123 		rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1);
   1124 
   1125 		iTargetRect = rect;
   1126 		iTargetRect.Move(iScreenRect.iTl);
   1127 
   1128 		}
   1129 	if(!(iStateFlags & EResizeRequest))
   1130 		iSwSize = iScreenRect.Size();
   1131 //	iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth;
   1132 	}
   1133 
   1134 /*)
   1135 TBool CDsa::ChangeTrigger()
   1136 	{
   1137 	const TBool change = iStateFlags & EChangeNotify;
   1138 	iStateFlags &= ~EChangeNotify;
   1139 	return change;
   1140 	}
   1141 */
   1142 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1143 
   1144 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
   1145 	{
   1146 	TUint32* target = aTarget;
   1147 	const TUint32* endt = target + aBytes;
   1148 	const TUint8* source = aSource;
   1149 	while(target < endt)
   1150 		{
   1151 		*target++ = aDsa.iLut256[*source++];
   1152 		}
   1153 	}
   1154 
   1155 void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
   1156 	{
   1157 	const TUint32* target = aTarget;
   1158 	TUint32* endt = aTarget + aBytes;
   1159 	const TUint8* source = aSource;
   1160 	while(target < endt)
   1161 		{
   1162 		*(--endt) = aDsa.iLut256[*source++];
   1163 		}
   1164 	}
   1165 
   1166 void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
   1167 	{
   1168 	TUint32* target = aTarget;
   1169 	const TUint32* endt = target + aBytes;
   1170 	const TUint8* column = aSource;
   1171 
   1172 	while(target < endt)
   1173 		{
   1174 		*target++ = aDsa.iLut256[*column];
   1175 		column += aLineLen;
   1176 		}
   1177 	}
   1178 
   1179 void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
   1180 	{
   1181 	const TUint32* target = aTarget;
   1182 	TUint32* endt = aTarget + aBytes;
   1183 	const TUint8* column = aSource;
   1184 
   1185 	while(target < endt)
   1186 		{
   1187 		*(--endt) = aDsa.iLut256[*column];
   1188 		column += aLineLen;
   1189 		}
   1190 	}
   1191 
   1192 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
   1193 	{
   1194 	const TUint32* src = reinterpret_cast<const TUint32*>(aSource);
   1195 	Mem::Copy(aTarget, src, aBytes << 2);
   1196 	}
   1197 
   1198 void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
   1199 	{
   1200 	TUint32* target = aTarget;
   1201 	const TUint32* endt = target + aBytes;
   1202 	const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
   1203 
   1204 	while(target < endt)
   1205 		{
   1206 		*target++ = *column;
   1207 		column += aLineLen;
   1208 		}
   1209 	}
   1210 
   1211 void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
   1212 	{
   1213 	const TUint32* target = aTarget;
   1214 	TUint32* endt = aTarget + aBytes;
   1215 	const TUint32* source = reinterpret_cast<const TUint32*>(aSource);
   1216 	while(target < endt)
   1217 		{
   1218 		*(--endt) = *source++;
   1219 		}
   1220 	}
   1221 
   1222 
   1223 void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
   1224 	{
   1225 	const TUint32* target = aTarget;
   1226 	TUint32* endt = aTarget + aBytes;
   1227 	const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
   1228 
   1229 	while(target < endt)
   1230 		{
   1231 		*(--endt) = *column;
   1232 		column += aLineLen;
   1233 		}
   1234 	}
   1235 
   1236 /*
   1237 
   1238 LOCAL_C TRgb rgb16MA(TInt aValue)
   1239 	{
   1240 	return TRgb::Color16MA(aValue);
   1241 	}
   1242 */
   1243 NONSHARABLE_CLASS(MRgbCopy)
   1244 	{
   1245 	public:
   1246 	virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0;
   1247 	virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0;
   1248 	};
   1249 
   1250 template <class T>
   1251 NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
   1252 	{
   1253 	public:
   1254 	TRgbCopy(TDisplayMode aMode);
   1255 	void* operator new(TUint aBytes, TAny* aMem);
   1256 	void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed);
   1257 	void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed);
   1258 	static TUint32 Gray256(const TUint8& aPixel);
   1259 	static TUint32 Color256(const TUint8& aPixel);
   1260 	static TUint32 Color4K(const TUint16& aPixel);
   1261 	static TUint32 Color64K(const TUint16& aPixel);
   1262 	static TUint32 Color16M(const TUint32& aPixel);
   1263 	static TUint32 Color16MU(const TUint32& aPixel);
   1264 	static TUint32 Color16MA(const TUint32& aPixel);
   1265 	private:
   1266 		typedef TUint32 (*TRgbFunc) (const T& aValue);
   1267 		TRgbFunc iFunc;
   1268 	};
   1269 
   1270 
   1271 template <class T>
   1272 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
   1273 	{
   1274 	return aMem;
   1275 	}
   1276 
   1277 template <class T>
   1278 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
   1279 	{
   1280 	switch(aMode)
   1281 		{
   1282 		case EGray256 : iFunc = (TRgbFunc) Gray256; break;
   1283 		case EColor256 : iFunc =  (TRgbFunc) Color256; break;
   1284 		case EColor4K : iFunc =  (TRgbFunc) Color4K; break;
   1285 		case EColor64K : iFunc =  (TRgbFunc) Color64K; break;
   1286 		case EColor16M : iFunc =  (TRgbFunc) Color16M; break;
   1287 		case EColor16MU : iFunc =  (TRgbFunc) Color16MU; break;
   1288 		case EColor16MA : iFunc =  (TRgbFunc) Color16MA; break;
   1289 		default:
   1290 			PANIC(KErrNotSupported);
   1291 		}
   1292 	}
   1293 
   1294 template <class T>
   1295 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed)
   1296 	{
   1297 	const T* source = reinterpret_cast<const T*>(aSource);
   1298 	TUint32* target = aTarget;
   1299 	TUint32* endt = target + aBytes;
   1300 
   1301 	if(aReversed)
   1302 		{
   1303 		while(target < endt)
   1304 			{
   1305 			const T value = *source++;
   1306 			*(--endt) = iFunc(value);//iFunc(value).Value();
   1307 			}
   1308 		}
   1309 	else
   1310 		{
   1311 		while(target < endt)
   1312 			{
   1313 			const T value = *source++;
   1314 			*target++ = iFunc(value);//iFunc(value).Value();
   1315 			}
   1316 		}
   1317 	}
   1318 
   1319 template <class T>
   1320 void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed)
   1321 	{
   1322 	const T* column = reinterpret_cast<const T*>(aSource);
   1323 	TUint32* target = aTarget;
   1324 	TUint32* endt = target + aBytes;
   1325 
   1326 	if(aReversed)
   1327 		{
   1328 		while(target < endt)
   1329 			{
   1330 			*(--endt) = iFunc(*column);
   1331 			column += aLineLen;
   1332 			}
   1333 		}
   1334 	else
   1335 		{
   1336 		while(target < endt)
   1337 			{
   1338 			*target++ = iFunc(*column);
   1339 			column += aLineLen;
   1340 			}
   1341 		}
   1342 	}
   1343 
   1344 template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
   1345 	{
   1346 	const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
   1347 	return px;
   1348 	}
   1349 
   1350 template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
   1351 	{
   1352 	return TRgb::Color256(aPixel).Value();
   1353 	}
   1354 
   1355 template <class T> TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
   1356 	{
   1357 	TUint32 col = (aPixel & 0xF00) << 12;
   1358 	col |= (aPixel & 0xF00) << 8;
   1359 
   1360 	col |= (aPixel & 0x0F0) << 8;
   1361 	col |= (aPixel & 0x0F0);
   1362 
   1363 	col |= (aPixel & 0x00F) << 4;
   1364 	col |= (aPixel & 0x00F);
   1365 
   1366 	return col;
   1367 	}
   1368 
   1369 template <class T> TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
   1370 	{
   1371 	TUint32 col = (aPixel & 0xF800)<< 8;
   1372 	col |= (aPixel & 0xE000) << 3;
   1373 
   1374 	col |= (aPixel & 0x07E0) << 5;
   1375 	col |= (aPixel & 0xC0) >> 1;
   1376 
   1377 	col |= (aPixel & 0x07E0) << 3;
   1378 	col |= (aPixel & 0x1C) >> 2;
   1379 
   1380 	return col;
   1381 	}
   1382 
   1383 template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
   1384 	{
   1385 	return TRgb::Color16M(aPixel).Value();
   1386 	}
   1387 
   1388 template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
   1389 	{
   1390 	return TRgb::Color16MU(aPixel).Value();
   1391 	}
   1392 
   1393 template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
   1394 	{
   1395 	return TRgb::Color16MA(aPixel).Value();
   1396 	}
   1397 
   1398 typedef TUint64 TStackMem;
   1399 
   1400 LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
   1401 	{
   1402 	if(aMode == EColor256 || aMode == EGray256)
   1403 		{
   1404 		return new (mem) TRgbCopy<TUint8>(aMode);
   1405 		}
   1406 	if(aMode == EColor4K || aMode == EColor64K)
   1407 		{
   1408 		return new (mem) TRgbCopy<TUint16>(aMode);
   1409 		}
   1410 	if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
   1411 		{
   1412 		return new (mem) TRgbCopy<TUint32>(aMode);
   1413 		}
   1414 	PANIC(KErrNotSupported);
   1415 	return NULL;
   1416 	}
   1417 
   1418 
   1419 void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
   1420 	{
   1421 	TStackMem mem = 0;
   1422 	GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue);
   1423 	}
   1424 
   1425 void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
   1426 	{
   1427 	TStackMem mem = 0;
   1428 	GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse);
   1429 	}
   1430 
   1431 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
   1432 	{
   1433 	TStackMem mem = 0;
   1434 	GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);
   1435 	}
   1436 
   1437 void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
   1438 	{
   1439 	TStackMem mem = 0;
   1440 	GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue);
   1441 	}
   1442 
   1443 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////7
   1444