Handle volume up/down keys.
[SDL.s60v3.git] / src / main / symbian / SDL_main.cpp
blobb61d17183509f2f589572feb19a7c2ae55b02ddd
1 extern "C" {
2 #include "SDL_events_c.h"
4 #include <queue>
5 #include "epoc_sdl.h"
6 #include "sdlepocapi.h"
7 #include <e32base.h>
8 #include <estlib.h>
9 #include <stdio.h>
10 #include <badesca.h>
11 #include <w32std.h>
12 #include <aknappui.h>
13 #include <aknapp.h>
14 #include "SDL_epocevents_c.h"
15 #include "SDL_keysym.h"
16 #include "dsa.h"
17 #include "SDL_loadso.h"
18 #include <remconcoreapitargetobserver.h>
19 #include <remconinterfaceselector.h>
20 #include <remconcoreapitarget.h>
22 extern SDLKey* KeyMap();
23 extern void ResetKeyMap();
25 class CCurrentAppUi;
26 class CEikonEnv;
27 class CSdlAppServ;
28 class CEventQueue;
30 NONSHARABLE_CLASS(EpocSdlEnvData)
32 public:
33 void Free();
34 void Delete();
35 CEventQueue* iEventQueue;
36 TMainFunc iMain;
37 int iEpocEnvFlags;
38 int iArgc;
39 char** iArgv;
40 CDsa* iDsa;
41 CSdlAppServ* iAppSrv;
42 TThreadId iId;
43 CArrayFix<TSdlCleanupItem>* iCleanupItems;
44 CSDL* iSdl;
45 TRequestStatus* iCallerStatus;
46 bool iWaitingForOrientationChange;
48 TSize iSize;
49 TDisplayMode iMode;
52 EpocSdlEnvData* gEpocEnv;
54 NONSHARABLE_CLASS(EnvUtils)
56 public:
57 static inline TBool IsOwnThreaded();
58 static TBool Rendezvous(RThread& aThread, TRequestStatus& aStatus);
59 static void RunSingleThread();
62 inline TBool EnvUtils::IsOwnThreaded()
64 return gEpocEnv->iEpocEnvFlags & CSDL::EOwnThread;
67 void EnvUtils::RunSingleThread()
69 if(!EnvUtils::IsOwnThreaded())
71 int count = RThread().RequestCount();
72 if(count > 0)
74 int err;
75 if(CActiveScheduler::RunIfReady(err, CActive::EPriorityIdle))
77 CActiveScheduler::Current()->WaitForAnyRequest();
83 int Panic(int aErr, int aLine)
85 TBuf<64> b;
86 b.Format(_L("Main at %d"), aLine);
87 User::Panic(b, aErr);
88 return 0;
92 class CEventQueue : public CBase, public MEventQueue
94 public:
95 void ConstructL();
96 ~CEventQueue();
97 int Append(const TWsEvent& aEvent);
98 const TWsEvent Shift();
99 void Lock();
100 void Unlock();
101 TBool HasData();
103 private:
104 std::queue<TWsEvent> m_queue;
105 RCriticalSection iCS;
108 void CEventQueue::ConstructL()
110 if(EnvUtils::IsOwnThreaded())
111 User::LeaveIfError(iCS.CreateLocal());
114 CEventQueue::~CEventQueue()
116 iCS.Close();
119 int CEventQueue::Append(const TWsEvent& aEvent)
121 Lock();
122 m_queue.push(aEvent);
123 Unlock();
124 return 0;
128 TBool CEventQueue::HasData()
130 EnvUtils::RunSingleThread();
131 return !m_queue.empty();
134 void CEventQueue::Lock()
136 if(EnvUtils::IsOwnThreaded())
137 iCS.Wait();
140 void CEventQueue::Unlock()
142 if(EnvUtils::IsOwnThreaded())
143 iCS.Signal();
146 const TWsEvent CEventQueue::Shift()
148 const TWsEvent event = m_queue.front();
149 m_queue.pop();
150 return event;
154 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem) :
155 iOperation(aOperation), iItem(aItem), iThread(RThread().Id())
158 #define MAINFUNC(x) EXPORT_C TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
160 MAINFUNC(1)
161 MAINFUNC(2)
162 MAINFUNC(3)
163 MAINFUNC(4)
164 MAINFUNC(5)
165 MAINFUNC(6)
167 EXPORT_C TMainFunc::TMainFunc()
169 Mem::FillZ(iMainFunc, sizeof(iMainFunc));
173 const void* TMainFunc::operator[](int aIndex) const
175 return iMainFunc[aIndex];
179 NONSHARABLE_CLASS(CSdlAppServ) : public CActive
181 public:
182 enum
184 EAppSrvNoop = CDsa::ELastDsaRequest,
185 EAppSrvWindowWidth,
186 EAppSrvWindowHeight,
187 EAppSrvWindowDisplayMode,
188 EAppSrvWindowPointerCursorMode,
189 EAppSrvDsaStatus,
190 EAppSrvStopThread,
191 EAppSrvWaitDsa
193 CSdlAppServ();
194 void ConstructL();
195 ~CSdlAppServ();
196 int Request(int aService);
197 int RequestValue(int aService);
198 void Init();
199 void PanicMain(int aReason);
200 void PanicMain(const TDesC& aInfo, int aReason);
201 void SetObserver(MSDLObserver* aObserver);
202 int ObserverEvent(int aEvent, int aParam);
203 void SetParam(int aParam);
204 void HandleObserverValue(int aService, int aReturnValue, TBool aMainThread);
205 MSDLObserver* Observer();
207 private:
208 void RunL();
209 void DoCancel();
210 const TThreadId iMainId;
211 RThread iAppThread;
212 int iService;
213 int iReturnValue;
214 RSemaphore iSema;
215 MSDLObserver* iObserver;
216 TRequestStatus* iStatusPtr;
219 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh), iMainId(RThread().Id()), iObserver( NULL )
223 MSDLObserver* CSdlAppServ::Observer()
225 return iObserver;
228 void CSdlAppServ::SetObserver(MSDLObserver* aObserver)
230 iObserver = aObserver;
233 int CSdlAppServ::ObserverEvent(int aEvent, int aParam)
235 if(iObserver != NULL)
237 if(RThread().Id() == gEpocEnv->iId && EnvUtils::IsOwnThreaded())
239 return iObserver->SdlThreadEvent(aEvent, aParam);
241 else if(RThread().Id() == iMainId)
243 return iObserver->SdlEvent(aEvent, aParam);
245 PANIC(KErrNotSupported);
247 return 0;
250 void CSdlAppServ::PanicMain(int aReason)
252 iAppThread.Panic(RThread().Name(), aReason);
255 void CSdlAppServ::PanicMain(const TDesC& aInfo, int aReason)
257 iAppThread.Panic(aInfo, aReason);
260 void CSdlAppServ::ConstructL()
262 CActiveScheduler::Add(this);
263 if(EnvUtils::IsOwnThreaded())
264 User::LeaveIfError(iSema.CreateLocal(1));
265 iStatus = KRequestPending;
266 iStatusPtr = &iStatus;
267 SetActive();
270 CSdlAppServ::~CSdlAppServ()
272 Cancel();
273 if(iSema.Handle() != NULL)
274 iSema.Signal();
275 iSema.Close();
276 iAppThread.Close();
279 int CSdlAppServ::Request(int aService)
281 if(EnvUtils::IsOwnThreaded())
283 if(RThread().Id() == iAppThread.Id())
284 return KErrBadHandle;
285 iSema.Wait();
287 EnvUtils::RunSingleThread();
288 iService = aService;
289 iAppThread.RequestComplete(iStatusPtr, KErrNone);
290 return KErrNone;
293 int CSdlAppServ::RequestValue(int aService)
295 Request(aService);
296 Request(EAppSrvNoop);
297 return iReturnValue;
300 void CSdlAppServ::Init()
302 PANIC_IF_ERROR(iAppThread.Open(iMainId));
305 void CSdlAppServ::SetParam(int aParam)
307 iReturnValue = aParam;
310 void CSdlAppServ::HandleObserverValue(int aService, int aReturnValue, TBool aMainThread)
312 if(!aMainThread && aService == MSDLObserver::EEventSuspend)
314 if(iObserver == NULL || (gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->Stopped() && aReturnValue != MSDLObserver::ESuspendNoSuspend))
316 EpocSdlEnv::Suspend();
321 void CSdlAppServ::RunL()
323 if(iStatus == KErrNone)
325 switch(iService)
327 case CSdlAppServ::EAppSrvWaitDsa:
328 EpocSdlEnv::SetWaitDsa();
329 iReturnValue = EpocSdlEnv::IsDsaAvailable();
330 break;
332 case CSdlAppServ::EAppSrvStopThread:
333 if(gEpocEnv->iDsa != NULL)
334 gEpocEnv->iDsa->SetSuspend();
335 break;
337 case EAppSrvWindowPointerCursorMode:
338 iReturnValue = gEpocEnv->iDsa != NULL ? gEpocEnv->iDsa->Session().PointerCursorMode() : KErrNotReady;
339 break;
341 case EAppSrvDsaStatus:
342 if(gEpocEnv->iDsa != NULL)
343 gEpocEnv->iDsa->Stop();
344 iReturnValue = KErrNone;
345 break;
347 case EAppSrvNoop:
348 break;
350 case MSDLObserver::EEventResume:
351 case MSDLObserver::EEventSuspend:
352 case MSDLObserver::EEventWindowReserved:
353 case MSDLObserver::EEventKeyMapInit:
354 case MSDLObserver::EEventWindowNotAvailable:
355 case MSDLObserver::EEventMainExit:
356 iReturnValue = ObserverEvent(iService, iReturnValue);
357 HandleObserverValue(iService, iReturnValue, ETrue);
358 break;
360 default:
361 PANIC(KErrNotSupported);
362 break;
365 iStatus = KRequestPending;
366 iStatusPtr = &iStatus;
367 SetActive();
370 if(EnvUtils::IsOwnThreaded())
371 iSema.Signal();
374 void CSdlAppServ::DoCancel()
376 if(EnvUtils::IsOwnThreaded())
377 iSema.Wait();
378 TRequestStatus* s = &iStatus;
379 iAppThread.RequestComplete(s, KErrCancel);
382 MEventQueue& EpocSdlEnv::EventQueue()
384 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
385 return *gEpocEnv->iEventQueue;
389 TBool EpocSdlEnv::Flags(int aFlag)
391 const int flag = gEpocEnv->iEpocEnvFlags & aFlag;
392 return flag == aFlag;
395 int EpocSdlEnv::Argc()
397 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
398 return gEpocEnv->iArgc;
401 char** EpocSdlEnv::Argv()
403 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
404 return gEpocEnv->iArgv;
407 TBool EpocSdlEnv::IsDsaAvailable()
409 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
410 return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
413 void EpocSdlEnv::WaitDsaAvailable()
415 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0);
416 gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread);
417 if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
419 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0);
423 void EpocSdlEnv::Suspend()
425 if(gEpocEnv->iDsa != NULL && (gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop)))
427 gEpocEnv->iDsa->SetSuspend();
428 if(EnvUtils::IsOwnThreaded())
430 RThread().Suspend();
431 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0);
436 void EpocSdlEnv::SetWaitDsa()
438 if(!IsDsaAvailable())
440 if(EnvUtils::IsOwnThreaded())
442 RThread th;
443 th.Open(gEpocEnv->iId);
444 th.Suspend();
445 th.Close();
447 if(gEpocEnv->iDsa != NULL)
448 gEpocEnv->iDsa->SetSuspend();
452 void EpocSdlEnv::Resume()
454 if(gEpocEnv->iDsa != NULL)
456 gEpocEnv->iDsa->Resume();
458 if(EnvUtils::IsOwnThreaded())
460 RThread th;
461 th.Open(gEpocEnv->iId);
462 th.Resume();
463 th.Close();
465 const int value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, 0);
466 gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue);
469 int EpocSdlEnv::AllocSurface(const TSize& aSize, TDisplayMode aMode)
471 return gEpocEnv->iDsa->AllocSurface(aSize, aMode);
474 void EpocSdlEnv::UnlockHwSurface()
476 gEpocEnv->iDsa->UnlockHwSurface();
479 TUint8* EpocSdlEnv::LockHwSurface()
481 return gEpocEnv->iDsa->LockHwSurface();
484 void EpocSdlEnv::UpdateSwSurface()
486 gEpocEnv->iDsa->UpdateSwSurface();
489 TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
491 return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
494 void EpocSdlEnv::Request(int aService)
496 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
497 gEpocEnv->iAppSrv->Request(aService);
500 TDisplayMode EpocSdlEnv::DisplayMode()
502 return gEpocEnv->iDsa == NULL ? ENone : gEpocEnv->iDsa->DisplayMode();
505 TPointerCursorMode EpocSdlEnv::PointerMode()
507 return static_cast<TPointerCursorMode>(gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode));
510 int EpocSdlEnv::SetPalette(int aFirstcolor, int aColorCount, TUint32* aPalette)
512 return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
515 void EpocSdlEnv::PanicMain(int aErr)
517 gEpocEnv->iAppSrv->PanicMain(aErr);
521 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
523 TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
524 return err;
527 void EpocSdlEnv::RemoveCleanupItem(TAny* aItem)
529 for(int i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
531 if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
532 gEpocEnv->iCleanupItems->Delete(i);
536 void EpocSdlEnv::CleanupItems()
538 const TThreadId id = RThread().Id();
539 int last = gEpocEnv->iCleanupItems->Count() - 1;
540 int i;
542 for(i = last; i >= 0 ; i--)
544 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
545 if(item.iThread == id)
547 item.iThread = TThreadId(0);
548 item.iOperation(item.iItem);
552 last = gEpocEnv->iCleanupItems->Count() - 1;
554 for(i = last; i >= 0 ; i--)
556 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
557 if(item.iThread == TThreadId(0))
559 gEpocEnv->iCleanupItems->Delete(i);
564 void EpocSdlEnv::FreeSurface()
566 Request(CSdlAppServ::EAppSrvDsaStatus);
567 if(gEpocEnv->iDsa != NULL)
568 gEpocEnv->iDsa->Free();
571 void EpocSdlEnv::ObserverEvent(int aService, int aParam)
573 const TBool sdlThread = RThread().Id() == gEpocEnv->iId;
574 const int valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam);
575 gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread);
576 if(sdlThread)
578 gEpocEnv->iAppSrv->SetParam(aParam);
579 const int valuet = gEpocEnv->iAppSrv->RequestValue(aService);
580 gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse);
584 void EpocSdlEnv::PanicMain(const TDesC& aInfo, int aErr)
586 gEpocEnv->iAppSrv->PanicMain(aInfo, aErr);
589 //Dsa is a low priority ao, it has to wait if its pending event, but ws
590 //event has been prioritized before it
591 //this is not called from app thread!
592 void EpocSdlEnv::WaitDeviceChange()
594 gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa);
597 LOCAL_C TBool CheckSdl()
599 int isExit = ETrue;
600 RThread sdl;
601 if(sdl.Open(gEpocEnv->iId) == KErrNone)
603 if(sdl.ExitType() == EExitPending)
605 isExit = EFalse;
607 sdl.Close();
609 return isExit;
612 void EpocSdlEnvData::Free()
614 if(RThread().Id() == gEpocEnv->iId)
616 if(iDsa != NULL)
617 iDsa->Free();
618 return;
621 __ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrNotReady));
624 void EpocSdlEnvData::Delete()
626 for(int i = 0; i <= iArgc; i++)
628 if(iArgv != NULL)
629 delete[] iArgv[i];
632 delete[] iArgv;
634 iArgv = NULL;
635 iArgc = 0;
637 delete iEventQueue;
639 if(iDsa != NULL)
640 iDsa->Free();
642 delete iDsa;
643 delete iAppSrv;
646 _LIT(KSDLMain, "SDLMain");
648 LOCAL_C int MainL()
650 gEpocEnv->iCleanupItems = new (ELeave) CArrayFixFlat<TSdlCleanupItem>(8);
652 char** envp=0;
653 /* !! process exits here if there is "exit()" in main! */
654 int ret = 0;
655 for(int i = 0; i < 6; i++)
657 void* f = (void*) gEpocEnv->iMain[i];
658 if(f != NULL)
660 switch(i)
662 case 0:
663 ret = ((mainfunc1)f)();
664 return ret;
666 case 3:
667 ((mainfunc1)f)();
668 return ret;
670 case 1:
671 ret = ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
672 return ret;
674 case 4:
675 ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
676 return ret;
678 case 2:
679 ret = ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
680 return ret;
682 case 5:
683 ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
684 return ret;
688 PANIC(KErrNotFound);
689 return 0;
692 LOCAL_C int DoMain(TAny* /*aParam*/)
694 TBool fbsconnected = EFalse;
695 CTrapCleanup* cleanup = NULL;
697 if(EnvUtils::IsOwnThreaded())
699 cleanup = CTrapCleanup::New();
701 if(RFbsSession::GetSession() == NULL)
703 PANIC_IF_ERROR(RFbsSession::Connect());
704 fbsconnected = ETrue;
707 gEpocEnv->iAppSrv->Init();
709 // Call stdlib main
710 int ret = 0;
711 if(EnvUtils::IsOwnThreaded())
713 //completes waiting rendesvous
714 RThread::Rendezvous(KErrNone);
717 TRAPD(err, err = MainL());
719 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventMainExit, err);
721 // Free resources and return
722 EpocSdlEnv::CleanupItems();
724 gEpocEnv->iCleanupItems->Reset();
725 delete gEpocEnv->iCleanupItems;
726 gEpocEnv->iCleanupItems = NULL;
728 gEpocEnv->Free(); //free up in thread resources
730 if(fbsconnected)
731 RFbsSession::Disconnect();
733 delete cleanup;
735 if(gEpocEnv->iCallerStatus != NULL)
737 User::RequestComplete(gEpocEnv->iCallerStatus, err);
738 return 0;
740 else
742 return err == KErrNone ? ret : err;
746 EXPORT_C CSDL::~CSDL()
748 gEpocEnv->Free();
749 gEpocEnv->Delete();
751 delete gEpocEnv;
752 gEpocEnv = NULL;
755 EXPORT_C CSDL* CSDL::NewL(int aFlags)
757 __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists));
758 gEpocEnv = new EpocSdlEnvData;
759 Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData));
761 gEpocEnv->iEpocEnvFlags = aFlags;
762 gEpocEnv->iEventQueue = new (ELeave) CEventQueue();
763 gEpocEnv->iAppSrv = new (ELeave) CSdlAppServ();
765 CSDL* sdl = new (ELeave) CSDL();
767 gEpocEnv->iSdl = sdl;
769 return sdl;
772 EXPORT_C void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice)
774 if(gEpocEnv->iDsa == NULL)
775 gEpocEnv->iDsa = CDsa::CreateL(aSession);
776 gEpocEnv->iDsa->ConstructL(aWindow, aDevice);
779 int EpocSdlEnv::ApplyGlesDsa()
781 CDsa* dsa = NULL;
782 TRAPD(err, dsa = gEpocEnv->iDsa->CreateGlesDsaL());
783 gEpocEnv->iDsa = dsa;
784 return err;
787 RWindow* EpocSdlEnv::Window()
789 return gEpocEnv->iDsa->Window();
792 void EpocSdlEnv::UpdateWholeScreen(bool val)
794 gEpocEnv->iDsa->m_updateWholeScreen = val;
797 bool EpocSdlEnv::GetUpdateWholeScreen()
799 return gEpocEnv->iDsa->m_updateWholeScreen;
802 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation, const TSize& aSize, TDisplayMode aMode)
804 gEpocEnv->iWaitingForOrientationChange = true;
805 gEpocEnv->iSize = aSize;
806 gEpocEnv->iMode = aMode;
808 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation));
811 EXPORT_C TThreadId CSDL::CallMainL(const TMainFunc& aFunc, TRequestStatus* const aStatus, const CDesC8Array* const aArg, int aStackSize)
813 ASSERT(gEpocEnv != NULL);
814 gEpocEnv->iMain = aFunc;
815 const TBool args = aArg != NULL;
817 if(gEpocEnv->iArgv != NULL)
818 User::Leave(KErrAlreadyExists);
820 gEpocEnv->iArgc = args ? aArg->Count() + 1 : 0;
821 gEpocEnv->iArgv = new char*[gEpocEnv->iArgc + 2];
823 int k = 0;
824 const TFileName processName = RProcess().FileName();
825 const int len = processName.Length();
826 gEpocEnv->iArgv[k] = new char[len + 1];
827 Mem::Copy(gEpocEnv->iArgv[k], processName.Ptr(), len);
828 gEpocEnv->iArgv[k][len] = 0;
830 for(int i = 0; args && (i < aArg->Count()); i++)
832 k++;
833 const int len = aArg->MdcaPoint(i).Length();
834 gEpocEnv->iArgv[k] = new char[len + 1];
835 Mem::Copy(gEpocEnv->iArgv[k], aArg->MdcaPoint(i).Ptr(), len);
836 gEpocEnv->iArgv[k][len] = 0;
839 gEpocEnv->iArgv[k + 1] = NULL;
841 gEpocEnv->iEventQueue->ConstructL();
842 gEpocEnv->iAppSrv->ConstructL();
844 // for handling volume up/down keys
845 CRemConInterfaceSelector *iSelector = CRemConInterfaceSelector::NewL();
846 CRemConCoreApiTarget::NewL( *iSelector, *this );
847 iSelector->OpenTargetL();
849 if(EnvUtils::IsOwnThreaded())
851 RThread thread;
852 User::LeaveIfError(thread.Create(KSDLMain, DoMain, aStackSize, NULL, NULL));
854 if(aStatus != NULL)
856 thread.Logon(*aStatus);
859 gEpocEnv->iId = thread.Id();
860 thread.SetPriority(EPriorityLess);
861 thread.Resume();
862 thread.Close();
864 else
866 gEpocEnv->iCallerStatus = aStatus;
867 if(aStatus != NULL)
868 *aStatus = KRequestPending;
869 gEpocEnv->iId = RThread().Id();
870 // when priority is not lowered screen updates much more frequently, which
871 // may be undesired, for example in case of openttd's generating world dialog
872 RThread().SetPriority(EPriorityLess);
873 DoMain( NULL );
876 return gEpocEnv->iId;
879 EXPORT_C int CSDL::AppendWsEvent(const TWsEvent& aEvent)
881 return EpocSdlEnv::EventQueue().Append(aEvent);
884 EXPORT_C void CSDL::SDLPanic(const TDesC& aInfo, int aErr)
886 EpocSdlEnv::PanicMain(aInfo, aErr);
889 EXPORT_C int CSDL::GetSDLCode(int aScanCode)
891 if(aScanCode < 0)
892 return MAX_SCANCODE;
893 if(aScanCode >= MAX_SCANCODE)
894 return -1;
895 return KeyMap()[aScanCode];
898 EXPORT_C int CSDL::SDLCodesCount() const
900 return MAX_SCANCODE;
903 EXPORT_C void CSDL::ResetSDLCodes()
905 ResetKeyMap();
908 EXPORT_C int CSDL::SetSDLCode(int aScanCode, int aSDLCode)
910 const int current = GetSDLCode(aScanCode);
911 if(aScanCode >= 0 && aScanCode < MAX_SCANCODE)
912 KeyMap()[aScanCode] = static_cast<SDLKey>(aSDLCode);
913 return current;
917 EXPORT_C MSDLObserver* CSDL::Observer()
919 return gEpocEnv->iAppSrv->Observer();
922 EXPORT_C void CSDL::SetObserver(MSDLObserver* aObserver)
924 gEpocEnv->iAppSrv->SetObserver(aObserver);
927 EXPORT_C void CSDL::Resume()
929 EpocSdlEnv::Resume();
932 EXPORT_C void CSDL::Suspend()
934 if(gEpocEnv->iDsa != NULL)
935 gEpocEnv->iDsa->DoStop();
938 EXPORT_C void CSDL::Resize()
940 if(gEpocEnv->iWaitingForOrientationChange)
942 EpocSdlEnv::AllocSurface(gEpocEnv->iSize, gEpocEnv->iMode);
943 gEpocEnv->iWaitingForOrientationChange = false;
945 else
947 TSize size = gEpocEnv->iDsa->Window()->Size();
948 SDL_PrivateResize(size.iWidth, size.iHeight);
952 EXPORT_C CSDL::CSDL()
955 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct)
957 if(aButtonAct != ERemConCoreApiButtonClick)
958 return;
960 TWsEvent event;
961 event.SetType(EEventKey);
962 event.SetTimeNow();
964 switch(aOperationId)
966 case ERemConCoreApiVolumeDown:
967 event.Key()->iScanCode = EStdKeyDecVolume;
968 event.SetType(EEventKeyDown);
969 AppendWsEvent(event);
970 event.SetType(EEventKeyUp);
971 AppendWsEvent(event);
972 break;
974 case ERemConCoreApiVolumeUp:
975 event.Key()->iScanCode = EStdKeyIncVolume;
976 event.SetType(EEventKeyDown);
977 AppendWsEvent(event);
978 event.SetType(EEventKeyUp);
979 AppendWsEvent(event);
980 break;
982 default:
983 break;
987 TBool EnvUtils::Rendezvous(RThread& aThread, TRequestStatus& aStatus)
989 if(gEpocEnv->iId != TThreadId(0) &&
990 aThread.Open(gEpocEnv->iId) &&
991 aThread.ExitType() == EExitPending)
993 aThread.Rendezvous(aStatus);
994 return ETrue;
996 return EFalse;
999 void* SDL_LoadObject(const char *sofile)
1001 RLibrary* lib = new RLibrary();
1002 if(lib == NULL)
1003 return NULL;
1004 TFileName name;
1005 name.Copy(TPtrC8((const TUint8*)sofile));
1006 if(KErrNone == lib->Load(name))
1007 return lib;
1008 delete lib;
1009 return NULL;
1012 void* SDL_LoadFunction(void *handle, const char *name)
1014 TLex8 v((const TUint8*)(name));
1015 int ord;
1017 if(KErrNone != v.Val(ord))
1018 return NULL;
1020 const RLibrary* lib = reinterpret_cast<RLibrary*>(handle);
1021 TLibraryFunction f = lib->Lookup(ord);
1022 return (void*)(f);
1025 void SDL_UnloadObject(void *handle)
1027 RLibrary* lib = reinterpret_cast<RLibrary*>(handle);
1028 lib->Close();
1029 delete lib;