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