SDL-1.2.14
[sdl_omap.git] / src / main / symbian / EKA2 / SDL_main.cpp
CommitLineData
e14743d1 1/*
2 SDL_Main.cpp
3 Symbian OS services for SDL
4
5 Markus Mertama
6*/
7
8
9#include "epoc_sdl.h"
10
11#include"sdlepocapi.h"
12#include <e32base.h>
13#include <estlib.h>
14#include <stdio.h>
15#include <badesca.h>
16
17#include "vectorbuffer.h"
18#include <w32std.h>
19#include <aknappui.h>
20#include <aknapp.h>
21#include "SDL_epocevents_c.h"
22#include "SDL_keysym.h"
23#include "dsa.h"
24
25
26#ifdef SYMBIANC
27#include <reent.h>
28#endif
29
30//Markus Mertama
31
32
33extern SDLKey* KeyMap();
34extern void ResetKeyMap();
35
36class CCurrentAppUi;
37
38//const TUid KSDLUid = { 0xF01F3D69 };
39
40NONSHARABLE_CLASS(EnvUtils)
41 {
42 public:
43 static void DisableKeyBlocking();
44 static TBool Rendezvous(RThread& aThread, TRequestStatus& aStatus);
45 };
46
47TInt Panic(TInt aErr, TInt aLine)
48 {
49 TBuf<64> b;
50 b.Format(_L("Main at %d"), aLine);
51 User::Panic(b, aErr);
52 return 0;
53 }
54
55
56NONSHARABLE_CLASS(CCurrentAppUi) : public CAknAppUi
57 {
58 public:
59 static CCurrentAppUi* Cast(CEikAppUi* aUi);
60 void DisableKeyBlocking();
61 };
62
63
64CCurrentAppUi* CCurrentAppUi::Cast(CEikAppUi* aUi)
65 {
66 return static_cast<CCurrentAppUi*>(aUi);
67 }
68
69void CCurrentAppUi::DisableKeyBlocking()
70 {
71 SetKeyBlockMode(ENoKeyBlock);
72 }
73
74
75class CEventQueue : public CBase, public MEventQueue
76 {
77 public:
78 static CEventQueue* NewL();
79 ~CEventQueue();
80 public:
81 TInt Append(const TWsEvent& aEvent);
82 const TWsEvent& Shift();
83 void Lock();
84 void Unlock();
85 TBool HasData();
86 private:
87 TVector<TWsEvent, 64> iVector;
88 RCriticalSection iCS;
89 };
90
91 CEventQueue* CEventQueue::NewL()
92 {
93 CEventQueue* q = new (ELeave) CEventQueue();
94 CleanupStack::PushL(q);
95 User::LeaveIfError(q->iCS.CreateLocal());
96 CleanupStack::Pop();
97 return q;
98 }
99
100CEventQueue::~CEventQueue()
101 {
102 iCS.Close();
103 }
104
105TInt CEventQueue::Append(const TWsEvent& aEvent)
106 {
107 iCS.Wait();
108 const TInt err = iVector.Append(aEvent);
109 iCS.Signal();
110 return err;
111 }
112
113
114TBool CEventQueue::HasData()
115 {
116 return iVector.Size() > 0;
117 }
118
119
120void CEventQueue::Lock()
121 {
122 iCS.Wait();
123 }
124
125void CEventQueue::Unlock()
126 {
127 iCS.Signal();
128 }
129
130const TWsEvent& CEventQueue::Shift()
131 {
132 const TWsEvent& event = iVector.Shift();
133 return event;
134 }
135
136
137TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem) :
138iOperation(aOperation), iItem(aItem), iThread(RThread().Id())
139 {
140 }
141
142class CEikonEnv;
143class CSdlAppServ;
144
145
146NONSHARABLE_CLASS(EpocSdlEnvData)
147 {
148 public:
149 void Free();
150 CEventQueue* iEventQueue;
151 TMainFunc iMain;
152 TInt iEpocEnvFlags;
153 int iArgc;
154 char** iArgv;
155 CDsa* iDsa;
156 CSdlAppServ* iAppSrv;
157 TThreadId iId;
158 CArrayFix<TSdlCleanupItem>* iCleanupItems;
159 CEikAppUi* iAppUi;
160 CSDL* iSdl;
161 };
162
163
164EpocSdlEnvData* gEpocEnv;
165
166#define MAINFUNC(x) EXPORT_C TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
167
168MAINFUNC(1)
169MAINFUNC(2)
170MAINFUNC(3)
171MAINFUNC(4)
172MAINFUNC(5)
173MAINFUNC(6)
174
175EXPORT_C TMainFunc::TMainFunc()
176 {
177 Mem::FillZ(iMainFunc, sizeof(iMainFunc));
178 }
179
180
181const void* TMainFunc::operator[](TInt aIndex) const
182 {
183 return iMainFunc[aIndex];
184 }
185
186
187NONSHARABLE_CLASS(CSdlAppServ) : public CActive
188 {
189 public:
190 enum
191 {
192 EAppSrvNoop = CDsa::ELastDsaRequest,
193 EAppSrvWindowWidth,
194 EAppSrvWindowHeight,
195 EAppSrvWindowDisplayMode,
196 EAppSrvWindowPointerCursorMode,
197 EAppSrvDsaStatus,
198 EAppSrvStopThread,
199 EAppSrvWaitDsa
200 };
201 CSdlAppServ();
202 void ConstructL();
203 ~CSdlAppServ();
204 TInt Request(TInt aService);
205 TInt RequestValue(TInt aService);
206 void Init();
207 void PanicMain(TInt aReason);
208 void PanicMain(const TDesC& aInfo, TInt aReason);
209 void SetObserver(MSDLObserver* aObserver);
210 TInt ObserverEvent(TInt aEvent, TInt aParam);
211 void SetParam(TInt aParam);
212 void HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread);
213 MSDLObserver* Observer();
214 private:
215 void RunL();
216 void DoCancel();
217 private:
218 const TThreadId iMainId;
219 RThread iAppThread;
220 TInt iService;
221 TInt iReturnValue;
222 RSemaphore iSema;
223 MSDLObserver* iObserver;
224 TRequestStatus* iStatusPtr;
225 };
226
227CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh), iMainId(RThread().Id())
228 {
229 }
230
231
232
233MSDLObserver* CSdlAppServ::Observer()
234 {
235 return iObserver;
236 }
237
238
239void CSdlAppServ::SetObserver(MSDLObserver* aObserver)
240 {
241 iObserver = aObserver;
242 }
243
244TInt CSdlAppServ::ObserverEvent(TInt aEvent, TInt aParam)
245 {
246 if(iObserver != NULL)
247 {
248 if(RThread().Id() == gEpocEnv->iId)
249 {
250 return iObserver->SdlThreadEvent(aEvent, aParam);
251 }
252 else if(RThread().Id() == iMainId)
253 {
254 return iObserver->SdlEvent(aEvent, aParam);
255 }
256 PANIC(KErrNotSupported);
257 }
258 return 0;
259 }
260
261void CSdlAppServ::PanicMain(TInt aReason)
262 {
263 iAppThread.Panic(RThread().Name(), aReason);
264 }
265
266void CSdlAppServ::PanicMain(const TDesC& aInfo, TInt aReason)
267 {
268 iAppThread.Panic(aInfo, aReason);
269 }
270
271void CSdlAppServ::ConstructL()
272 {
273 CActiveScheduler::Add(this);
274 User::LeaveIfError(iSema.CreateLocal(1));
275 iStatus = KRequestPending;
276 iStatusPtr = &iStatus;
277 SetActive();
278 }
279
280 CSdlAppServ::~CSdlAppServ()
281 {
282 Cancel();
283 if(iSema.Handle() != NULL)
284 iSema.Signal();
285 iSema.Close();
286 iAppThread.Close();
287 }
288
289TInt CSdlAppServ::Request(TInt aService)
290 {
291 if(RThread().Id() != iAppThread.Id())
292 {
293 iSema.Wait();
294 iService = aService;
295 iAppThread.RequestComplete(iStatusPtr, KErrNone);
296 return KErrNone;
297 }
298 return KErrBadHandle;
299 }
300
301TInt CSdlAppServ::RequestValue(TInt aService)
302 {
303 Request(aService);
304 Request(EAppSrvNoop);
305 return iReturnValue;
306 }
307
308void CSdlAppServ::Init()
309 {
310 PANIC_IF_ERROR(iAppThread.Open(iMainId));
311 }
312
313void CSdlAppServ::SetParam(TInt aParam)
314 {
315 iReturnValue = aParam;
316 }
317
318void CSdlAppServ::HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread)
319 {
320 if(iObserver != NULL && aMainThread)
321 {
322 switch(aService)
323 {
324 case MSDLObserver::EEventScreenSizeChanged:
325 if(aReturnValue == MSDLObserver::EScreenSizeChangedDefaultPalette)
326 EpocSdlEnv::LockPalette(EFalse);
327 break;
328 }
329 }
330 if(!aMainThread && aService == MSDLObserver::EEventSuspend)
331 {
332 if(iObserver == NULL ||
333 (gEpocEnv->iDsa->Stopped() && aReturnValue != MSDLObserver::ESuspendNoSuspend))
334 {
335 EpocSdlEnv::Suspend();
336 }
337 }
338 }
339
340void CSdlAppServ::RunL()
341 {
342 if(iStatus == KErrNone)
343 {
344 switch(iService)
345 {
346 case CSdlAppServ::EAppSrvWaitDsa:
347 EpocSdlEnv::SetWaitDsa();
348 iReturnValue = EpocSdlEnv::IsDsaAvailable();
349 // }
350 // gEpocEnv->iDsa->Stop();
351 // gEpocEnv->iDsa->RestartL();
352 break;
353 case CSdlAppServ::EAppSrvStopThread:
354 gEpocEnv->iDsa->SetSuspend();
355 break;
356 case EpocSdlEnv::EDisableKeyBlocking:
357 EnvUtils::DisableKeyBlocking();
358 break;
359
360 case EAppSrvWindowPointerCursorMode:
361 iReturnValue = gEpocEnv->iDsa != NULL ?
362 gEpocEnv->iDsa->Session().PointerCursorMode() : KErrNotReady;
363 break;
364 case EAppSrvDsaStatus:
365 gEpocEnv->iDsa->Stop();
366 iReturnValue = KErrNone;
367 break;
368 case CDsa::ERequestUpdate:
369 gEpocEnv->iDsa->UnlockHWSurfaceRequestComplete();
370 break;
371 case EAppSrvNoop:
372 break;
373 case MSDLObserver::EEventResume:
374 case MSDLObserver::EEventSuspend:
375 case MSDLObserver::EEventScreenSizeChanged:
376 case MSDLObserver::EEventWindowReserved:
377 case MSDLObserver::EEventKeyMapInit:
378 case MSDLObserver::EEventWindowNotAvailable:
379 case MSDLObserver::EEventMainExit:
380 iReturnValue = ObserverEvent(iService, iReturnValue);
381 HandleObserverValue(iService, iReturnValue, ETrue);
382 break;
383 default:
384 PANIC(KErrNotSupported);
385 }
386 iStatus = KRequestPending;
387 iStatusPtr = &iStatus;
388 SetActive();
389 }
390 iSema.Signal();
391 }
392
393void CSdlAppServ::DoCancel()
394 {
395 iSema.Wait();
396 TRequestStatus* s = &iStatus;
397 iAppThread.RequestComplete(s, KErrCancel);
398 }
399
400
401
402MEventQueue& EpocSdlEnv::EventQueue()
403 {
404 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
405 return *gEpocEnv->iEventQueue;
406 }
407
408
409TBool EpocSdlEnv::Flags(TInt aFlag)
410 {
411 const TInt flag = gEpocEnv->iEpocEnvFlags & aFlag;
412 return flag == aFlag;
413 }
414
415TInt EpocSdlEnv::Argc()
416 {
417 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
418 return gEpocEnv->iArgc;
419 }
420
421
422char** EpocSdlEnv::Argv()
423 {
424 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
425 return gEpocEnv->iArgv;
426 }
427
428
429TBool EpocSdlEnv::IsDsaAvailable()
430 {
431 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
432 return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
433 }
434
435
436void EpocSdlEnv::WaitDsaAvailable()
437 {
438 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0);
439 gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread);
440 if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
441 {
442 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0);
443 }
444 }
445
446void EpocSdlEnv::Suspend()
447 {
448 if(gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
449 {
450 // gEpocEnv->iDsa->ReleaseStop();
451 gEpocEnv->iDsa->SetSuspend();
452 RThread().Suspend();
453 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0);
454 }
455 }
456
457void EpocSdlEnv::SetWaitDsa()
458 {
459 if(!IsDsaAvailable())
460 {
461 RThread th;
462 th.Open(gEpocEnv->iId);
463 th.Suspend();
464 th.Close();
465 gEpocEnv->iDsa->SetSuspend();
466 }
467 }
468
469void EpocSdlEnv::Resume()
470 {
471 gEpocEnv->iDsa->Resume();
472 RThread th;
473 th.Open(gEpocEnv->iId);
474 th.Resume();
475 th.Close();
476
477 const TInt value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, 0);
478 gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue);
479 }
480
481
482TInt EpocSdlEnv::AllocSwSurface(const TSize& aSize, TDisplayMode aMode)
483 {
484 return gEpocEnv->iDsa->AllocSurface(EFalse, aSize, aMode);
485 }
486
487TInt EpocSdlEnv::AllocHwSurface(const TSize& aSize, TDisplayMode aMode)
488 {
489 return gEpocEnv->iDsa->AllocSurface(ETrue, aSize, aMode);
490 }
491
492
493void EpocSdlEnv::UnlockHwSurface()
494 {
495 gEpocEnv->iDsa->UnlockHwSurface();
496 }
497
498TUint8* EpocSdlEnv::LockHwSurface()
499 {
500 return gEpocEnv->iDsa->LockHwSurface();
501 }
502
503
504void EpocSdlEnv::UpdateSwSurface()
505 {
506 gEpocEnv->iDsa->UpdateSwSurface();
507 }
508
509TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
510 {
511 return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
512 }
513
514void EpocSdlEnv::Request(TInt aService)
515 {
516 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
517 gEpocEnv->iAppSrv->Request(aService);
518 }
519
520
521TSize EpocSdlEnv::WindowSize(const TSize& aRequestedSize)
522 {
523 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
524 if(EpocSdlEnv::Flags(CSDL::EAllowImageResize) && gEpocEnv->iDsa->WindowSize() != aRequestedSize)
525 {
526 TRAP_IGNORE(gEpocEnv->iDsa->CreateZoomerL(aRequestedSize));
527 }
528 return gEpocEnv->iDsa->WindowSize();
529 }
530
531 TSize EpocSdlEnv::WindowSize()
532 {
533 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
534 return gEpocEnv->iDsa->WindowSize();
535 }
536
537TDisplayMode EpocSdlEnv::DisplayMode()
538 {
539 return gEpocEnv->iDsa->DisplayMode();
540 }
541
542TPointerCursorMode EpocSdlEnv::PointerMode()
543 {
544 return static_cast<TPointerCursorMode>
545 (gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode));
546 }
547
548TInt EpocSdlEnv::SetPalette(TInt aFirstcolor, TInt aColorCount, TUint32* aPalette)
549 {
550 return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
551 }
552
553void EpocSdlEnv::PanicMain(TInt aErr)
554 {
555 gEpocEnv->iAppSrv->PanicMain(aErr);
556 }
557
558
559TInt EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
560 {
561 TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
562 return err;
563 }
564
565void EpocSdlEnv::RemoveCleanupItem(TAny* aItem)
566 {
567 for(TInt i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
568 {
569 if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
570 gEpocEnv->iCleanupItems->Delete(i);
571 }
572 }
573
574void EpocSdlEnv::CleanupItems()
575 {
576 const TThreadId id = RThread().Id();
577 TInt last = gEpocEnv->iCleanupItems->Count() - 1;
578 TInt i;
579 for(i = last; i >= 0 ; i--)
580 {
581 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
582 if(item.iThread == id)
583 {
584 item.iThread = TThreadId(0);
585 item.iOperation(item.iItem);
586 }
587 }
588 last = gEpocEnv->iCleanupItems->Count() - 1;
589 for(i = last; i >= 0 ; i--)
590 {
591 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
592 if(item.iThread == TThreadId(0))
593 {
594 gEpocEnv->iCleanupItems->Delete(i);
595 }
596 }
597 }
598
599void EpocSdlEnv::FreeSurface()
600 {
601 Request(CSdlAppServ::EAppSrvDsaStatus);
602 gEpocEnv->iDsa->Free();
603 }
604
605void EpocSdlEnv::LockPalette(TBool aLock)
606 {
607 gEpocEnv->iDsa->LockPalette(aLock);
608 }
609
610void EpocSdlEnv::ObserverEvent(TInt aService, TInt aParam)
611 {
612 const TBool sdlThread = RThread().Id() == gEpocEnv->iId;
613 const TInt valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam);
614 gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread);
615 if(sdlThread)
616 {
617 gEpocEnv->iAppSrv->SetParam(aParam);
618 const TInt valuet = gEpocEnv->iAppSrv->RequestValue(aService);
619 gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse);
620 }
621 }
622
623
624TPoint EpocSdlEnv::WindowCoordinates(const TPoint& aPoint)
625 {
626 return gEpocEnv->iDsa->WindowCoordinates(aPoint);
627 }
628
629void EpocSdlEnv::PanicMain(const TDesC& aInfo, TInt aErr)
630 {
631 gEpocEnv->iAppSrv->PanicMain(aInfo, aErr);
632 }
633//Dsa is a low priority ao, it has to wait if its pending event, but ws
634//event has been prioritized before it
635//this is not called from app thread!
636void EpocSdlEnv::WaitDeviceChange()
637 {
638 LockPalette(ETrue);
639 gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa);
640 const TSize sz = WindowSize();
641 const TInt param = reinterpret_cast<TInt>(&sz);
642 ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param);
643
644 // RThread().Suspend();
645 }
646
647LOCAL_C TBool CheckSdl()
648 {
649 TInt isExit = ETrue;
650 RThread sdl;
651 if(sdl.Open(gEpocEnv->iId) == KErrNone)
652 {
653 if(sdl.ExitType() == EExitPending)
654 {
655 isExit = EFalse;
656 }
657 sdl.Close();
658 }
659 return isExit;
660 }
661
662void EpocSdlEnvData::Free()
663 {
664 if(RThread().Id() == gEpocEnv->iId)
665 {
666 iDsa->Free();
667 return;
668 }
669
670 __ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrNotReady));
671
672 for(TInt i = 0; i < iArgc; i++)
673 User::Free( iArgv[i] );
674
675 User::Free(iArgv);
676
677
678 delete iEventQueue;
679
680 if(iDsa != NULL)
681 iDsa->Free();
682
683 delete iDsa;
684 delete iAppSrv;
685 }
686
687_LIT(KSDLMain, "SDLMain");
688
689LOCAL_C int MainL()
690 {
691 gEpocEnv->iCleanupItems = new (ELeave) CArrayFixFlat<TSdlCleanupItem>(8);
692
693 char** envp=0;
694 /* !! process exits here if there is "exit()" in main! */
695 int ret = 0;
696 for(TInt i = 0; i < 6; i++)
697 {
698 void* f = (void*) gEpocEnv->iMain[i];
699 if(f != NULL)
700 {
701 switch(i)
702 {
703 case 0:
704 ret = ((mainfunc1)f)();
705 return ret;
706 case 3:
707 ((mainfunc1)f)();
708 return ret;
709 case 1:
710 ret = ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
711 return ret;
712 case 4:
713 ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
714 return ret;
715 case 2:
716 ret = ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
717 return ret;
718 case 5:
719 ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
720 return ret;
721 }
722 }
723 }
724 PANIC(KErrNotFound);
725 return 0;
726 }
727
728LOCAL_C TInt DoMain(TAny* /*aParam*/)
729 {
730
731
732 CTrapCleanup* cleanup = CTrapCleanup::New();
733
734 TBool fbsconnected = EFalse;
735 if(RFbsSession::GetSession() == NULL)
736 {
737 PANIC_IF_ERROR(RFbsSession::Connect());
738 fbsconnected = ETrue;
739 }
740
741 gEpocEnv->iAppSrv->Init();
742
743#ifdef SYMBIANC
744 // Create stdlib
745 _REENT;
746#endif
747
748 // Call stdlib main
749 int ret = 0;
750
751 //completes waiting rendesvous
752 RThread::Rendezvous(KErrNone);
753
754 TRAPD(err, err = MainL());
755
756 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventMainExit, err);
757
758 // Free resources and return
759
760 EpocSdlEnv::CleanupItems();
761
762 gEpocEnv->iCleanupItems->Reset();
763 delete gEpocEnv->iCleanupItems;
764 gEpocEnv->iCleanupItems = NULL;
765
766 gEpocEnv->Free(); //free up in thread resources
767
768#ifdef SYMBIANC
769 _cleanup(); //this is normally called at exit, I call it here
770#endif
771
772 if(fbsconnected)
773 RFbsSession::Disconnect();
774
775#ifdef SYMBIANC
776 CloseSTDLIB();
777#endif
778
779 // delete as;
780 delete cleanup;
781
782 return err == KErrNone ? ret : err;;
783 }
784
785
786
787EXPORT_C CSDL::~CSDL()
788 {
789 gEpocEnv->Free();
790 User::Free(gEpocEnv);
791 gEpocEnv->iSdl = NULL;
792 }
793
794EXPORT_C CSDL* CSDL::NewL(TInt aFlags)
795 {
796 __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists));
797 gEpocEnv = (EpocSdlEnvData*) User::AllocL(sizeof(EpocSdlEnvData));
798 Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData));
799
800 gEpocEnv->iEpocEnvFlags = aFlags;
801 gEpocEnv->iEventQueue = CEventQueue::NewL();
802
803 gEpocEnv->iAppSrv = new (ELeave) CSdlAppServ();
804 gEpocEnv->iAppSrv->ConstructL();
805
806 CSDL* sdl = new (ELeave) CSDL();
807
808 gEpocEnv->iSdl = sdl;
809
810 return sdl;
811 }
812
813 /*
814EXPORT_C void CSDL::ReInitL(TFlags aFlags)
815 {
816 const TFlags prevFlags = gEpocEnv->iEpocEnvFlags;
817 gEpocEnv->iEpocEnvFlags = aFlags;
818 TInt err = KErrNone;
819 if(((prevFlags & EDrawModeDSB) != (aFlags & EDrawModeDSB)) && gEpocEnv->iDsa)
820 {
821 delete gEpocEnv->iDsa;
822 gEpocEnv->iDsa = NULL;
823 gEpocEnv->iDsa = CDsa::RecreateL(EpocSdlEnv::Flags(CSDL::EDrawModeDSB));
824 }
825 }
826 */
827
828
829EXPORT_C void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice)
830 {
831 if(gEpocEnv->iDsa == NULL)
832 gEpocEnv->iDsa = CDsa::CreateL(aSession);
833 gEpocEnv->iDsa->ConstructL(aWindow, aDevice);
834 }
835
836
837EXPORT_C TThreadId CSDL::CallMainL(const TMainFunc& aFunc, TRequestStatus* const aStatus, const CDesC8Array* const aArg, TInt aFlags, TInt aStackSize)
838 {
839 ASSERT(gEpocEnv != NULL);
840 gEpocEnv->iMain = aFunc;
841 const TBool args = aArg != NULL;
842
843 gEpocEnv->iArgc = aArg->Count() + 1;
844 gEpocEnv->iArgv = (char**) User::AllocL(sizeof(char*) * (gEpocEnv->iArgc + 1));
845
846 TInt k = 0;
847 const TFileName processName = RProcess().FileName();
848 const TInt len = processName.Length();
849 gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1);
850 Mem::Copy(gEpocEnv->iArgv[k], processName.Ptr(), len);
851 gEpocEnv->iArgv[k][len] = 0;
852
853 for(TInt i = 0; args && (i < aArg->Count()); i++)
854 {
855 k++;
856 const TInt len = aArg->MdcaPoint(i).Length();
857 gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1);
858 Mem::Copy(gEpocEnv->iArgv[k], aArg->MdcaPoint(i).Ptr(), len);
859 gEpocEnv->iArgv[k][len] = 0;
860 }
861
862 gEpocEnv->iArgv[gEpocEnv->iArgc] = NULL;
863
864 RThread thread;
865 User::LeaveIfError(thread.Create(KSDLMain, DoMain, aStackSize, NULL, NULL));
866
867 if(aStatus != NULL)
868 {
869 thread.Logon(*aStatus);
870 }
871
872 gEpocEnv->iId = thread.Id();
873 thread.SetPriority(EPriorityLess);
874 if((aFlags & CSDL::ERequestResume) == 0)
875 {
876 thread.Resume();
877 }
878 thread.Close();
879 return gEpocEnv->iId;
880 }
881
882EXPORT_C TInt CSDL::AppendWsEvent(const TWsEvent& aEvent)
883 {
884 return EpocSdlEnv::EventQueue().Append(aEvent);
885 }
886
887EXPORT_C void CSDL::SDLPanic(const TDesC& aInfo, TInt aErr)
888 {
889 EpocSdlEnv::PanicMain(aInfo, aErr);
890 }
891
892EXPORT_C TInt CSDL::GetSDLCode(TInt aScanCode)
893 {
894 if(aScanCode < 0)
895 return MAX_SCANCODE;
896 if(aScanCode >= MAX_SCANCODE)
897 return -1;
898 return KeyMap()[aScanCode];
899 }
900
901EXPORT_C TInt CSDL::SDLCodesCount() const
902 {
903 return MAX_SCANCODE;
904 }
905
906EXPORT_C void CSDL::ResetSDLCodes()
907 {
908 ResetKeyMap();
909 }
910
911EXPORT_C void CSDL::SetOrientation(TOrientationMode aMode)
912 {
913 gEpocEnv->iDsa->SetOrientation(aMode);
914 }
915
916EXPORT_C TInt CSDL::SetSDLCode(TInt aScanCode, TInt aSDLCode)
917 {
918 const TInt current = GetSDLCode(aScanCode);
919 if(aScanCode >= 0 && aScanCode < MAX_SCANCODE)
920 KeyMap()[aScanCode] = static_cast<SDLKey>(aSDLCode);
921 return current;
922 }
923
924
925EXPORT_C MSDLObserver* CSDL::Observer()
926 {
927 return gEpocEnv->iAppSrv->Observer();
928 }
929
930EXPORT_C void CSDL::SetObserver(MSDLObserver* aObserver)
931 {
932 gEpocEnv->iAppSrv->SetObserver(aObserver);
933 }
934
935EXPORT_C void CSDL::Resume()
936 {
937 EpocSdlEnv::Resume();
938 }
939
940EXPORT_C void CSDL::Suspend()
941 {
942 gEpocEnv->iDsa->DoStop();
943 }
944
945EXPORT_C CSDL::CSDL()
946 {
947 }
948
949EXPORT_C void CSDL::DisableKeyBlocking(CAknAppUi& aAppUi) const
950 {
951 gEpocEnv->iAppUi = &aAppUi;
952 EnvUtils::DisableKeyBlocking();
953 }
954
955EXPORT_C TInt CSDL::SetBlitter(MBlitter* aBlitter)
956 {
957 if(gEpocEnv && gEpocEnv->iDsa)
958 {
959 gEpocEnv->iDsa->SetBlitter(aBlitter);
960 return KErrNone;
961 }
962 return KErrNotReady;
963 }
964
965
966EXPORT_C TInt CSDL::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
967 {
968 if(gEpocEnv && gEpocEnv->iDsa)
969 {
970 return gEpocEnv->iDsa->AppendOverlay(aOverlay, aPriority);
971 }
972 return KErrNotReady;
973 }
974
975EXPORT_C TInt CSDL::RemoveOverlay(MOverlay& aOverlay)
976 {
977 if(gEpocEnv && gEpocEnv->iDsa)
978 {
979 return gEpocEnv->iDsa->RemoveOverlay(aOverlay);
980 }
981 return KErrNotReady;
982 }
983
984EXPORT_C TInt CSDL::RedrawRequest()
985 {
986 if(gEpocEnv && gEpocEnv->iDsa)
987 {
988 return gEpocEnv->iDsa->RedrawRequest();
989 }
990 return KErrNotReady;
991 }
992
993/*
994EXPORT_C CSDL* CSDL::Current()
995 {
996 return gEpocEnv != NULL ? gEpocEnv->iSdl : NULL;
997 }
998
999
1000EXPORT_C TInt CSDL::SetVolume(TInt aVolume)
1001 {
1002 return EpocSdlEnv::SetVolume(aVolume);
1003 }
1004
1005EXPORT_C TInt CSDL::Volume() const
1006 {
1007 return EpocSdlEnv::Volume();
1008 }
1009
1010EXPORT_C TInt CSDL::MaxVolume() const
1011 {
1012 return EpocSdlEnv::MaxVolume();
1013 }
1014*/
1015
1016void EnvUtils::DisableKeyBlocking()
1017 {
1018 if(gEpocEnv->iAppUi != NULL)
1019 return CCurrentAppUi::Cast(gEpocEnv->iAppUi)->DisableKeyBlocking();
1020 }
1021
1022TBool EnvUtils::Rendezvous(RThread& aThread, TRequestStatus& aStatus)
1023 {
1024 if(gEpocEnv->iId != TThreadId(0) &&
1025 aThread.Open(gEpocEnv->iId) &&
1026 aThread.ExitType() == EExitPending)
1027 {
1028 aThread.Rendezvous(aStatus);
1029 return ETrue;
1030 }
1031 return EFalse;
1032 }
1033
1034
1035