Mercurial > sdl-ios-xcode
annotate src/video/symbian/EKA2/dsa.cpp @ 4170:092c0bc69155 SDL-1.2
Fixed bug #618
Description From Tim Angus 2008-08-30 12:23:56 (-) [reply]
As we all know SDL 1.2 doesn't handle dead keys well since one key press
potentially equals two (or more) characters. For example, on many layouts,
keying <backquote>,<space> results in <no character>,<backquote><space>. Since
the unicode member of the SDL_keysym struct only has room for one character,
only one can be returned.
On Linux, the first character is returned. On Windows however, unless the exact
number of characters generated by the keypress is 1, nothing is returned. The
following patch addresses this inconsistency.
Updated patch which includes a further fix to the handling of the numpad when
numlock is on. This further fix is courtesy Amanieu d'Antras.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 13 Apr 2009 08:42:09 +0000 |
parents | ce8046809062 |
children |
rev | line source |
---|---|
3975 | 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> | |
4004
ce8046809062
Minor updates to the Symbian/S60 port, plus project files that weren't
Ryan C. Gordon <icculus@icculus.org>
parents:
3975
diff
changeset
|
15 NONSHARABLE_CLASS(CBitmapSurface) : public T |
3975 | 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) : | |
4004
ce8046809062
Minor updates to the Symbian/S60 port, plus project files that weren't
Ryan C. Gordon <icculus@icculus.org>
parents:
3975
diff
changeset
|
833 iStateFlags(0), |
ce8046809062
Minor updates to the Symbian/S60 port, plus project files that weren't
Ryan C. Gordon <icculus@icculus.org>
parents:
3975
diff
changeset
|
834 iSession(aSession) |
ce8046809062
Minor updates to the Symbian/S60 port, plus project files that weren't
Ryan C. Gordon <icculus@icculus.org>
parents:
3975
diff
changeset
|
835 |
3975 | 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 |