1 /*
2     SDL - Simple DirectMedia Layer
3 
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Lesser General Public
6     License as published by the Free Software Foundation; either
7     version 2.1 of the License, or (at your option) any later version.
8 
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     Lesser General Public License for more details.
13 
14     You should have received a copy of the GNU Lesser General Public
15     License along with this library; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 
18 
19 */
20 
21 #include"sdlenvdata.h"
22 #include"dsa.h"
23 #include"appsrv.h"
24 
25 class CCurrentAppUi;
26 class CEikonEnv;
27 
28 extern void ContainerWindowChanged();
29 extern void PrepareContainerWindowChanged();
30 
31 extern TInt DoMain(TAny* /*aParam*/);
32 
33 EpocSdlEnvData* gEpocEnv;
34 
TSdlCleanupItem(TSdlCleanupOperation aOperation,TAny * aItem,TBool aThreadCleanup)35 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem, TBool aThreadCleanup) :
36 iOperation(aOperation), iItem(aItem), iThread(aThreadCleanup ? RThread().Id() : gEpocEnv->iId)
37     {
38     }
39 
IsOwnThreaded()40 TBool EnvUtils::IsOwnThreaded()
41     {
42     return gEpocEnv->iEpocEnvFlags & CSDL::EOwnThread;
43     }
44 
EventQueue()45 MEventQueue& EpocSdlEnv::EventQueue()
46     {
47     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
48     return *gEpocEnv->iEventQueue;
49     }
50 
51 
Flags(TInt aFlag)52 TBool EpocSdlEnv::Flags(TInt aFlag)
53     {
54 	const TInt flag = gEpocEnv->iEpocEnvFlags & aFlag;
55 	return flag == aFlag;
56     }
57 
Argc()58 TInt EpocSdlEnv::Argc()
59     {
60     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
61     return gEpocEnv->iArgc;
62     }
63 
64 
Argv()65 char** EpocSdlEnv::Argv()
66     {
67     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
68     return gEpocEnv->iArgv;
69     }
70 
71 
IsDsaAvailable()72 TBool EpocSdlEnv::IsDsaAvailable()
73     {
74     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
75     return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
76     }
77 
PostUpdate()78 void EpocSdlEnv::PostUpdate()
79     {
80     while(EnvUtils::RunSingleThread()){}
81     }
82 
WaitDsaAvailable()83 void EpocSdlEnv::WaitDsaAvailable()
84 	{
85 	gEpocEnv->iEpocEnvFlags |= EpocSdlEnvData::EWaitDsa;
86 	EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0);
87 	if(gEpocEnv->iEpocEnvFlags & EpocSdlEnvData::EWaitDsa)
88 	    EpocSdlEnv::DoSuspend(ETrue);
89 	//gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread);
90 	/*if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
91 		{
92 		EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0);
93 		}
94 	*/
95 	}
96 
97 
ResumeDsa()98 void EpocSdlEnv::ResumeDsa()
99     {
100     if(gEpocEnv->iEpocEnvFlags & EpocSdlEnvData::EWaitDsa)
101         EpocSdlEnv::DoResume(ETrue);
102     gEpocEnv->iEpocEnvFlags &= ~EpocSdlEnvData::EWaitDsa;
103     }
104 
105 
IsSuspend()106 TBool EpocSdlEnv::IsSuspend()
107     {
108     return gEpocEnv->iEpocEnvFlags & EpocSdlEnvData::ESuspend;
109     }
110 
DoSuspend(TBool aInternal)111 void EpocSdlEnv::DoSuspend(TBool aInternal)
112 	{
113 	EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, aInternal);
114 	if(EnvUtils::IsOwnThreaded())
115         {
116         RThread thread;
117         User::LeaveIfError(thread.Open(gEpocEnv->iId));
118         thread.Suspend();
119         }
120 
121 	gEpocEnv->iEpocEnvFlags |= EpocSdlEnvData::ESuspend;
122 
123 
124 	 for(TInt i = gEpocEnv->iChildThreads->Count() - 1; i >= 0; i--)
125 	    {
126 	    RThread th;
127         if(th.Open(gEpocEnv->iChildThreads->At(i)) == KErrNone)
128             {
129             const TExitType reason = th.ExitType();
130             if(reason != EExitPending)
131                 {
132                 gEpocEnv->iChildThreads->Delete(i);
133                 }
134             else
135                 {
136                 th.Suspend();
137                 }
138             th.Close();
139             }
140 	    }
141 
142     EpocSdlEnv::DisableDraw();
143 
144 	/*if(gEpocEnv->iDsa != NULL && (gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop)))
145 		{
146 		gEpocEnv->iDsa->SetSuspend();
147 		if(EnvUtils::IsOwnThreaded())
148 			{
149 			RThread().Suspend();
150 			EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0);
151 			}
152 		}
153 	*/
154 	}
155 
156 /*
157 void EpocSdlEnv::SetWaitDsa()
158 	{
159 	if(!IsDsaAvailable())
160 		{
161 		if(EnvUtils::IsOwnThreaded())
162 			{
163 			RThread th;
164 			th.Open(gEpocEnv->iId);
165 			th.Suspend();
166 			th.Close();
167 			}
168 		if(gEpocEnv->iDsa != NULL)
169 			gEpocEnv->iDsa->SetSuspend();
170 		}
171 	}
172 */
173 
DoResume(TBool aInternal,TBool aRendezvous)174 void EpocSdlEnv::DoResume(TBool aInternal, TBool aRendezvous)
175 	{
176 	if(EnvUtils::IsOwnThreaded())
177         {
178         RThread thread;
179         User::LeaveIfError(thread.Open(gEpocEnv->iId));
180         if(aRendezvous)
181             {
182             TRequestStatus status;
183             thread.Rendezvous(status);
184 
185         #ifdef __WINS__
186             thread.SetPriority(EPriorityNormal);
187         #endif
188             thread.Resume();
189             User::WaitForRequest(status);
190             }
191         else
192             {
193             thread.Resume();
194             }
195         gEpocEnv->iEpocEnvFlags &= ~EpocSdlEnvData::ESuspend;
196         thread.Close();
197         }
198     else
199         {
200         if(aRendezvous && !gEpocEnv->iCaller->IsActive())
201             gEpocEnv->iCaller->Start(TCallBack(DoMain));
202         else
203             gEpocEnv->iEpocEnvFlags &= ~EpocSdlEnvData::ESuspend;
204         }
205 
206 	if(gEpocEnv->iChildThreads != NULL)
207 	    {
208         for(TInt i = gEpocEnv->iChildThreads->Count() - 1; i >= 0; i--)
209                 {
210                 RThread th;
211                 if(th.Open(gEpocEnv->iChildThreads->At(i)) == KErrNone)
212                     {
213                     if(th.ExitType() != EExitPending)
214                         {
215                         gEpocEnv->iChildThreads->Delete(i);
216                         }
217                     else
218                         {
219                         th.Resume();
220                         }
221                     th.Close();
222                     }
223                 }
224 	    }
225 
226 	if(!aRendezvous)
227 	    EpocSdlEnv::EnableDraw();
228 
229 
230     const TInt value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, aInternal);
231     gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue);
232 
233 	}
234 
235 
AllocSwSurface(const TSize & aSize,TDisplayMode aMode)236 TInt EpocSdlEnv::AllocSwSurface(const TSize& aSize, TDisplayMode aMode)
237 	{
238 	return gEpocEnv->iDsa->AllocSurface(EFalse, aSize, aMode);
239 	}
240 
AllocHwSurface(const TSize & aSize,TDisplayMode aMode)241 TInt EpocSdlEnv::AllocHwSurface(const TSize& aSize, TDisplayMode aMode)
242 	{
243 	return gEpocEnv->iDsa->AllocSurface(ETrue, aSize, aMode);
244 	}
245 
246 
UnlockHwSurface()247 void EpocSdlEnv::UnlockHwSurface()
248 	{
249 	gEpocEnv->iDsa->UnlockHwSurface();
250 	}
251 
LockHwSurface()252 TUint8* EpocSdlEnv::LockHwSurface()
253 	{
254 	return gEpocEnv->iDsa->LockHwSurface();
255 	}
256 
257 
UpdateSwSurface()258 void EpocSdlEnv::UpdateSwSurface()
259 	{
260 	gEpocEnv->iDsa->UpdateSurface();
261 	}
262 
UpdateHwSurface()263 void EpocSdlEnv::UpdateHwSurface()
264     {
265     if(gEpocEnv->iDsa->IsHwScreenSurface())
266         gEpocEnv->iDsa->UpdateSurface();
267     }
268 
AddUpdateRect(TUint8 * aAddress,const TRect & aUpdateRect,const TRect & aRect)269 TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
270 	{
271 	return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
272 	}
273 
Request(TInt aService)274 void EpocSdlEnv::Request(TInt aService)
275     {
276     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
277     gEpocEnv->iAppSrv->Request(aService);
278     }
279 
280 
CreateZoomer(const TSize & aRequestedSize)281 void EpocSdlEnv::CreateZoomer(const TSize& aRequestedSize)
282     {
283     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
284     if(gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->WindowSize() != aRequestedSize)
285     	{
286     	TRAP_IGNORE(gEpocEnv->iDsa->CreateZoomerL(aRequestedSize));
287     	}
288     }
289 
290 
ScreenSize()291 TSize EpocSdlEnv::ScreenSize()
292     {
293     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
294     return gEpocEnv->iDsa == NULL ? TSize(0, 0) : gEpocEnv->iDsa->ScreenRect().Size();
295     }
296 
WindowSize()297 TSize EpocSdlEnv::WindowSize()
298     {
299     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
300     return gEpocEnv->iDsa == NULL ? TSize(0, 0) : gEpocEnv->iDsa->WindowSize();
301     }
302 
DisplayMode()303 TDisplayMode EpocSdlEnv::DisplayMode()
304     {
305     return gEpocEnv->iDsa == NULL ? ENone : gEpocEnv->iDsa->DisplayMode();
306     }
307 
PointerMode()308 TPointerCursorMode EpocSdlEnv::PointerMode()
309     {
310     return static_cast<TPointerCursorMode>
311     (gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode));
312     }
313 
314 
SetAppOrientation(CSDL::TAppOrientation aOrientation)315 TInt EpocSdlEnv::SetAppOrientation(CSDL::TAppOrientation aOrientation)
316     {
317     gEpocEnv->iAppSrv->SetParam(aOrientation);
318     return static_cast<CSDL::TAppOrientation>
319         (gEpocEnv->iAppSrv->RequestValue(EpocSdlEnv::ESetAppOrientation));
320     }
321 
SetPalette(TInt aFirstcolor,TInt aColorCount,TUint32 * aPalette)322 TInt EpocSdlEnv::SetPalette(TInt aFirstcolor, TInt aColorCount, TUint32* aPalette)
323 	{
324 	return 	gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
325 	}
326 
PanicMain(TInt aErr)327 void EpocSdlEnv::PanicMain(TInt aErr)
328     {
329     gEpocEnv->iAppSrv->PanicMain(aErr);
330     }
331 
332 
AppendCleanupItem(const TSdlCleanupItem & aItem)333 TInt EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
334     {
335     TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
336     return err;
337     }
338 
RemoveCleanupItem(TAny * aItem)339 void EpocSdlEnv::RemoveCleanupItem(TAny* aItem)
340     {
341     for(TInt i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
342         {
343         if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
344             gEpocEnv->iCleanupItems->Delete(i);
345         }
346     }
347 
CleanupItems()348 void EpocSdlEnv::CleanupItems()
349 	{
350 	const TThreadId id = RThread().Id();
351 	TInt last = gEpocEnv->iCleanupItems->Count() - 1;
352 	TInt i;
353 	for(i = last; i >= 0 ; i--)
354         {
355         TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
356         if(item.iThread == id)
357         	{
358         	item.iThread = TThreadId(0);
359         	item.iOperation(item.iItem);
360         	}
361         }
362     last = gEpocEnv->iCleanupItems->Count() - 1;
363 	for(i = last; i >= 0 ; i--)
364         {
365         TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
366         if(item.iThread == TThreadId(0))
367         	{
368         	gEpocEnv->iCleanupItems->Delete(i);
369         	}
370         }
371 	}
372 
FreeSurface()373 void EpocSdlEnv::FreeSurface()
374 	{
375 	Request(CSdlAppServ::EAppSrvDsaStatus);
376 	if(gEpocEnv->iDsa != NULL)
377 	    {
378 	    if(gEpocEnv->iDsa->IsHwScreenSurface())
379 	        {
380 	        gEpocEnv->iDsa->SetUpdating(EFalse);
381 	        }
382 	    __ASSERT_ALWAYS(!gEpocEnv->iDsa->IsUpdating(), PANIC(KErrNotReady));
383 	    gEpocEnv->iDsa->Free();
384 	    }
385 	}
386 
LockPalette(TBool aLock)387 void EpocSdlEnv::LockPalette(TBool aLock)
388 	{
389 	gEpocEnv->iDsa->LockPalette(aLock);
390 	}
391 
ObserverEvent(TInt aService,TInt aParam)392 void EpocSdlEnv::ObserverEvent(TInt aService, TInt aParam)
393 	{
394 	const TBool sdlThread = RThread().Id() == gEpocEnv->iId;
395 	const TInt valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam);
396 	gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread);
397 	if(sdlThread && EnvUtils::IsOwnThreaded())
398 		{
399 		gEpocEnv->iAppSrv->SetParam(aParam);
400 		const TInt valuet = gEpocEnv->iAppSrv->RequestValue(aService);
401 		gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse);
402 		}
403 	}
404 
405 
WindowCoordinates(const TPoint & aPoint)406 TPoint EpocSdlEnv::WindowCoordinates(const TPoint& aPoint)
407     {
408     return gEpocEnv->iDsa == NULL  ? aPoint :
409     	gEpocEnv->iDsa->WindowCoordinates(aPoint);
410     }
411 
PanicMain(const TDesC & aInfo,TInt aErr)412 void EpocSdlEnv::PanicMain(const TDesC& aInfo, TInt aErr)
413     {
414     gEpocEnv->iAppSrv->PanicMain(aInfo, aErr);
415     }
416 /*
417 void EpocSdlEnv::ScreenSizeChanged()
418     {
419  //   gEpocEnv->iDsa->WaitDeviceChange(EFalse);
420     }
421 */
422 
423 //Dsa is a low priority ao, it has to wait if its pending event, but ws
424 //event has been prioritized before it
425 //this is not called from app thread!
426 /*
427 void EpocSdlEnv::WaitDeviceChange()
428     {
429   	LockPalette(ETrue);
430 
431   	if(EnvUtils::IsOwnThreaded())
432   	    gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa);
433 
434 
435     static TSize ssz = TSize(-1, -1);
436     const TSize sz = WindowSize();
437     if(sz != ssz)
438         {
439         DisableDraw();
440         const TInt param = reinterpret_cast<TInt>(&sz);
441         ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param);
442 
443         }
444 
445     ContainerWindowChanged();
446 
447     LockPalette(EFalse);
448     }
449 */
450 
ScreenSizeChanged()451 void EpocSdlEnv::ScreenSizeChanged()
452     {
453     LockPalette(ETrue);
454     DisableDraw();
455     const TSize sz = WindowSize();
456     const TInt param = reinterpret_cast<TInt>(&sz);
457     ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param);
458     LockPalette(EFalse);
459     ContainerWindowChanged();
460     }
461 
462 /*
463 void EpocSdlEnv::WaitDeviceChange()
464     {
465     LockPalette(ETrue);
466 
467     if(EnvUtils::IsOwnThreaded())
468         gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa);
469 
470 
471     static TSize ssz = TSize(-1, -1);
472     const TSize sz = WindowSize();
473     if(sz != ssz)
474         {
475         DisableDraw();
476         const TInt param = reinterpret_cast<TInt>(&sz);
477         ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param);
478 
479         }
480 
481     ContainerWindowChanged();
482 
483     LockPalette(EFalse);
484     }
485 */
486 /*
487  * This function try to find best fit if screen content does not fit in screen
488  */
AutoOrientation(const TSize & aSize)489 TBool EpocSdlEnv::AutoOrientation(const TSize& aSize)
490     {
491     const CSDL::TAppOrientation mode = gEpocEnv->iAppOrientation;
492 
493     const TSize screenSize = gEpocEnv->iDsa->ScreenRect().Size();
494 
495     if(mode == CSDL::EDefaultAppOrientation &&
496             gEpocEnv->iDsa &&
497             screenSize.iWidth != screenSize.iHeight)
498         {
499         CSDL::TAppOrientation dir = CSDL::EPortraitAppOrientation;
500 
501         const TBool landscape = screenSize.iWidth > screenSize.iHeight;
502 
503         //First we check if it windows entrily inside either of orientations
504         if(!EpocSdlEnv::Flags(CSDL::EImageResizeZoomOut) ||
505                 (screenSize.iWidth == aSize.iWidth && screenSize.iHeight == aSize.iHeight))
506             {
507             if(screenSize.iWidth <= aSize.iWidth && screenSize.iHeight <= aSize.iHeight)
508                 {
509                 if(landscape)
510                     dir = CSDL::ELandscapeAppOrientation;
511                 return KErrNone == EpocSdlEnv::SetAppOrientation(dir);
512                 }
513             else if(screenSize.iWidth <= aSize.iHeight && screenSize.iHeight <= aSize.iWidth)
514                 {
515                 if(!landscape)
516                     dir = CSDL::ELandscapeAppOrientation;
517                 return KErrNone == EpocSdlEnv::SetAppOrientation(dir);
518                 }
519             }
520         //Then try to find more suitable dimensions
521         const TRect rect1 = CDsa::CalcResizeRect(screenSize, aSize);
522         const TRect rect2 = CDsa::CalcResizeRect(TSize(screenSize.iHeight, screenSize.iWidth), aSize);
523 
524         const TInt area1 = rect1.Size().iWidth * rect1.Size().iHeight;
525         const TInt area2 = rect2.Size().iWidth * rect2.Size().iHeight;
526 
527         //then better fit is the bigger intersection area
528         if(area1 > area2)
529             {
530             //current is better
531             if(landscape)
532                 dir = CSDL::ELandscapeAppOrientation;
533             }
534         else if(area1 < area2)
535             {
536             //we have to turn the screen
537             if(!landscape)
538                 dir = CSDL::ELandscapeAppOrientation;
539             }
540         else
541             {
542             return EFalse;
543             }
544         return KErrNone == EpocSdlEnv::SetAppOrientation(dir);
545         }
546     return EFalse;
547     }
548 
CheckSdl()549 LOCAL_C TBool CheckSdl()
550     {
551     TInt isExit = ETrue;
552     RThread sdl;
553     if(sdl.Open(gEpocEnv->iId) == KErrNone)
554         {
555         if(sdl.ExitType() == EExitPending)
556             {
557             isExit = EFalse;
558             }
559         sdl.Close();
560         }
561     return isExit;
562     }
563 
Free()564 void EpocSdlEnvData::Free()
565     {
566    	if(RThread().Id() == gEpocEnv->iId)
567     	{
568     	if(iDsa != NULL)
569     	    {
570     	    __ASSERT_ALWAYS(!iDsa->IsUpdating(), PANIC(KErrNotReady));
571     		iDsa->Free();
572     	    }
573     	return;
574     	}
575 
576    	__ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrInUse));
577     }
578 
Delete()579  void EpocSdlEnvData::Delete()
580     {
581 
582  	for(TInt i = 0; i <= iArgc; i++)
583     	{
584     	if(iArgv != NULL)
585     		User::Free( iArgv[i] );
586     	}
587 
588     User::Free(iArgv);
589 
590     iArgv = NULL;
591     iArgc = 0;
592 
593     delete iEventQueue;
594 
595     if(iDsa != NULL)
596         {
597         __ASSERT_ALWAYS(!gEpocEnv->iDsa->IsUpdating(), PANIC(KErrNotReady));
598     	iDsa->Free();
599         }
600 
601 	delete iDsa;
602 	delete iAppSrv;
603 
604    	delete gEpocEnv->iCaller;
605     }
606 
ApplyGlesDsa()607 TInt EpocSdlEnv::ApplyGlesDsa()
608  	{
609  	CDsa* dsa = NULL;
610  	TRAPD(err, dsa = gEpocEnv->iDsa->CreateGlesDsaL());
611  	gEpocEnv->iDsa = dsa;
612  	return err;
613  	}
614 
Window()615  RWindow* EpocSdlEnv::Window()
616  	{
617  	return gEpocEnv == NULL ? NULL : (gEpocEnv->iDsa == NULL ? NULL : gEpocEnv->iDsa->Window());
618  	}
619 
SetOrientation(CSDL::TOrientationMode aOrientation)620 void EpocSdlEnv::SetOrientation(CSDL::TOrientationMode aOrientation)
621  	{
622  	gEpocEnv->iDsa->SetOrientation(aOrientation);
623  	}
624 
StackSize()625 TInt EpocSdlEnv::StackSize()
626     {
627     return gEpocEnv->iStackSize;
628     }
629 
IsVideoThread()630 TBool EpocSdlEnv::IsVideoThread()
631     {
632     return RThread().Id() == gEpocEnv->iDsa->OwnerThread();
633     }
634 
EnableDraw()635 void EpocSdlEnv::EnableDraw()
636     {
637     if(gEpocEnv->iDsa)
638         gEpocEnv->iDsa->DisableDraw(EFalse);
639     }
640 
641 
DisableDraw()642 void EpocSdlEnv::DisableDraw()
643     {
644     if(gEpocEnv->iDsa)
645         gEpocEnv->iDsa->DisableDraw(ETrue);
646     }
647 
BgColor()648 TUint32 EpocSdlEnv::BgColor()
649     {
650     return gEpocEnv->iColor;
651     }
652 /*
653 const CFbsBitmap** EpocSdlEnv::BitGdiCanvas()
654     {
655     return gEpocEnv->iBitGdiCanvas;
656     }
657 */
658 
AppendThread(TInt aThreadId)659 void EpocSdlEnv::AppendThread(TInt aThreadId)
660     {
661     TRAPD(err, gEpocEnv->iChildThreads->AppendL(aThreadId));
662     PANIC_IF_ERROR(err);
663     }
664 
RemoveThread(TInt aThreadId)665 void EpocSdlEnv::RemoveThread(TInt aThreadId)
666     {
667     for(TInt i = gEpocEnv->iChildThreads->Count() - 1; i >= 0; i--)
668         {
669         if(gEpocEnv->iChildThreads->At(i) == aThreadId)
670             {
671             gEpocEnv->iChildThreads->Delete(i);
672             }
673         else
674             {
675             RThread th;
676             if(th.Open(gEpocEnv->iChildThreads->At(i)) == KErrNone)
677                 {
678                 if(th.ExitType() != EExitPending)
679                     {
680                     gEpocEnv->iChildThreads->Delete (i);
681                     }
682                 th.Close();
683                 }
684             }
685         }
686     }
687 
688