Mercurial > sdl-ios-xcode
view src/main/symbian/EKA2/SDL_main.cpp @ 4347:38f22ed3a433 SDL-1.2
Option to fix bug #851
For some people setting the period size works better (and is what SDL 1.2.13 did), but for most people it's the same or worse. You can use an environment variable to pick which one you want.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 17 Oct 2009 06:55:17 +0000 |
parents | e85e65aec22f |
children |
line wrap: on
line source
/* SDL_Main.cpp Symbian OS services for SDL Markus Mertama */ #include "epoc_sdl.h" #include"sdlepocapi.h" #include <e32base.h> #include <estlib.h> #include <stdio.h> #include <badesca.h> #include "vectorbuffer.h" #include <w32std.h> #include <aknappui.h> #include <aknapp.h> #include "SDL_epocevents_c.h" #include "SDL_keysym.h" #include "dsa.h" #ifdef SYMBIANC #include <reent.h> #endif //Markus Mertama extern SDLKey* KeyMap(); extern void ResetKeyMap(); class CCurrentAppUi; //const TUid KSDLUid = { 0xF01F3D69 }; NONSHARABLE_CLASS(EnvUtils) { public: static void DisableKeyBlocking(); static TBool Rendezvous(RThread& aThread, TRequestStatus& aStatus); }; TInt Panic(TInt aErr, TInt aLine) { TBuf<64> b; b.Format(_L("Main at %d"), aLine); User::Panic(b, aErr); return 0; } NONSHARABLE_CLASS(CCurrentAppUi) : public CAknAppUi { public: static CCurrentAppUi* Cast(CEikAppUi* aUi); void DisableKeyBlocking(); }; CCurrentAppUi* CCurrentAppUi::Cast(CEikAppUi* aUi) { return static_cast<CCurrentAppUi*>(aUi); } void CCurrentAppUi::DisableKeyBlocking() { SetKeyBlockMode(ENoKeyBlock); } class CEventQueue : public CBase, public MEventQueue { public: static CEventQueue* NewL(); ~CEventQueue(); public: TInt Append(const TWsEvent& aEvent); const TWsEvent& Shift(); void Lock(); void Unlock(); TBool HasData(); private: TVector<TWsEvent, 64> iVector; RCriticalSection iCS; }; CEventQueue* CEventQueue::NewL() { CEventQueue* q = new (ELeave) CEventQueue(); CleanupStack::PushL(q); User::LeaveIfError(q->iCS.CreateLocal()); CleanupStack::Pop(); return q; } CEventQueue::~CEventQueue() { iCS.Close(); } TInt CEventQueue::Append(const TWsEvent& aEvent) { iCS.Wait(); const TInt err = iVector.Append(aEvent); iCS.Signal(); return err; } TBool CEventQueue::HasData() { return iVector.Size() > 0; } void CEventQueue::Lock() { iCS.Wait(); } void CEventQueue::Unlock() { iCS.Signal(); } const TWsEvent& CEventQueue::Shift() { const TWsEvent& event = iVector.Shift(); return event; } TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem) : iOperation(aOperation), iItem(aItem), iThread(RThread().Id()) { } class CEikonEnv; class CSdlAppServ; NONSHARABLE_CLASS(EpocSdlEnvData) { public: void Free(); CEventQueue* iEventQueue; TMainFunc iMain; TInt iEpocEnvFlags; int iArgc; char** iArgv; CDsa* iDsa; CSdlAppServ* iAppSrv; TThreadId iId; CArrayFix<TSdlCleanupItem>* iCleanupItems; CEikAppUi* iAppUi; CSDL* iSdl; }; EpocSdlEnvData* gEpocEnv; #define MAINFUNC(x) EXPORT_C TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;} MAINFUNC(1) MAINFUNC(2) MAINFUNC(3) MAINFUNC(4) MAINFUNC(5) MAINFUNC(6) EXPORT_C TMainFunc::TMainFunc() { Mem::FillZ(iMainFunc, sizeof(iMainFunc)); } const void* TMainFunc::operator[](TInt aIndex) const { return iMainFunc[aIndex]; } NONSHARABLE_CLASS(CSdlAppServ) : public CActive { public: enum { EAppSrvNoop = CDsa::ELastDsaRequest, EAppSrvWindowWidth, EAppSrvWindowHeight, EAppSrvWindowDisplayMode, EAppSrvWindowPointerCursorMode, EAppSrvDsaStatus, EAppSrvStopThread, EAppSrvWaitDsa }; CSdlAppServ(); void ConstructL(); ~CSdlAppServ(); TInt Request(TInt aService); TInt RequestValue(TInt aService); void Init(); void PanicMain(TInt aReason); void PanicMain(const TDesC& aInfo, TInt aReason); void SetObserver(MSDLObserver* aObserver); TInt ObserverEvent(TInt aEvent, TInt aParam); void SetParam(TInt aParam); void HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread); MSDLObserver* Observer(); private: void RunL(); void DoCancel(); private: const TThreadId iMainId; RThread iAppThread; TInt iService; TInt iReturnValue; RSemaphore iSema; MSDLObserver* iObserver; TRequestStatus* iStatusPtr; }; CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh), iMainId(RThread().Id()) { } MSDLObserver* CSdlAppServ::Observer() { return iObserver; } void CSdlAppServ::SetObserver(MSDLObserver* aObserver) { iObserver = aObserver; } TInt CSdlAppServ::ObserverEvent(TInt aEvent, TInt aParam) { if(iObserver != NULL) { if(RThread().Id() == gEpocEnv->iId) { return iObserver->SdlThreadEvent(aEvent, aParam); } else if(RThread().Id() == iMainId) { return iObserver->SdlEvent(aEvent, aParam); } PANIC(KErrNotSupported); } return 0; } void CSdlAppServ::PanicMain(TInt aReason) { iAppThread.Panic(RThread().Name(), aReason); } void CSdlAppServ::PanicMain(const TDesC& aInfo, TInt aReason) { iAppThread.Panic(aInfo, aReason); } void CSdlAppServ::ConstructL() { CActiveScheduler::Add(this); User::LeaveIfError(iSema.CreateLocal(1)); iStatus = KRequestPending; iStatusPtr = &iStatus; SetActive(); } CSdlAppServ::~CSdlAppServ() { Cancel(); if(iSema.Handle() != NULL) iSema.Signal(); iSema.Close(); iAppThread.Close(); } TInt CSdlAppServ::Request(TInt aService) { if(RThread().Id() != iAppThread.Id()) { iSema.Wait(); iService = aService; iAppThread.RequestComplete(iStatusPtr, KErrNone); return KErrNone; } return KErrBadHandle; } TInt CSdlAppServ::RequestValue(TInt aService) { Request(aService); Request(EAppSrvNoop); return iReturnValue; } void CSdlAppServ::Init() { PANIC_IF_ERROR(iAppThread.Open(iMainId)); } void CSdlAppServ::SetParam(TInt aParam) { iReturnValue = aParam; } void CSdlAppServ::HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread) { if(iObserver != NULL && aMainThread) { switch(aService) { case MSDLObserver::EEventScreenSizeChanged: if(aReturnValue == MSDLObserver::EScreenSizeChangedDefaultPalette) EpocSdlEnv::LockPalette(EFalse); break; } } if(!aMainThread && aService == MSDLObserver::EEventSuspend) { if(iObserver == NULL || (gEpocEnv->iDsa->Stopped() && aReturnValue != MSDLObserver::ESuspendNoSuspend)) { EpocSdlEnv::Suspend(); } } } void CSdlAppServ::RunL() { if(iStatus == KErrNone) { switch(iService) { case CSdlAppServ::EAppSrvWaitDsa: EpocSdlEnv::SetWaitDsa(); iReturnValue = EpocSdlEnv::IsDsaAvailable(); // } // gEpocEnv->iDsa->Stop(); // gEpocEnv->iDsa->RestartL(); break; case CSdlAppServ::EAppSrvStopThread: gEpocEnv->iDsa->SetSuspend(); break; case EpocSdlEnv::EDisableKeyBlocking: EnvUtils::DisableKeyBlocking(); break; case EAppSrvWindowPointerCursorMode: iReturnValue = gEpocEnv->iDsa != NULL ? gEpocEnv->iDsa->Session().PointerCursorMode() : KErrNotReady; break; case EAppSrvDsaStatus: gEpocEnv->iDsa->Stop(); iReturnValue = KErrNone; break; case CDsa::ERequestUpdate: gEpocEnv->iDsa->UnlockHWSurfaceRequestComplete(); break; case EAppSrvNoop: break; case MSDLObserver::EEventResume: case MSDLObserver::EEventSuspend: case MSDLObserver::EEventScreenSizeChanged: case MSDLObserver::EEventWindowReserved: case MSDLObserver::EEventKeyMapInit: case MSDLObserver::EEventWindowNotAvailable: case MSDLObserver::EEventMainExit: iReturnValue = ObserverEvent(iService, iReturnValue); HandleObserverValue(iService, iReturnValue, ETrue); break; default: PANIC(KErrNotSupported); } iStatus = KRequestPending; iStatusPtr = &iStatus; SetActive(); } iSema.Signal(); } void CSdlAppServ::DoCancel() { iSema.Wait(); TRequestStatus* s = &iStatus; iAppThread.RequestComplete(s, KErrCancel); } MEventQueue& EpocSdlEnv::EventQueue() { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); return *gEpocEnv->iEventQueue; } TBool EpocSdlEnv::Flags(TInt aFlag) { const TInt flag = gEpocEnv->iEpocEnvFlags & aFlag; return flag == aFlag; } TInt EpocSdlEnv::Argc() { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); return gEpocEnv->iArgc; } char** EpocSdlEnv::Argv() { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); return gEpocEnv->iArgv; } TBool EpocSdlEnv::IsDsaAvailable() { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable(); } void EpocSdlEnv::WaitDsaAvailable() { EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0); gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread); if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop)) { EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0); } } void EpocSdlEnv::Suspend() { if(gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop)) { // gEpocEnv->iDsa->ReleaseStop(); gEpocEnv->iDsa->SetSuspend(); RThread().Suspend(); EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0); } } void EpocSdlEnv::SetWaitDsa() { if(!IsDsaAvailable()) { RThread th; th.Open(gEpocEnv->iId); th.Suspend(); th.Close(); gEpocEnv->iDsa->SetSuspend(); } } void EpocSdlEnv::Resume() { gEpocEnv->iDsa->Resume(); RThread th; th.Open(gEpocEnv->iId); th.Resume(); th.Close(); const TInt value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, 0); gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue); } TInt EpocSdlEnv::AllocSwSurface(const TSize& aSize, TDisplayMode aMode) { return gEpocEnv->iDsa->AllocSurface(EFalse, aSize, aMode); } TInt EpocSdlEnv::AllocHwSurface(const TSize& aSize, TDisplayMode aMode) { return gEpocEnv->iDsa->AllocSurface(ETrue, aSize, aMode); } void EpocSdlEnv::UnlockHwSurface() { gEpocEnv->iDsa->UnlockHwSurface(); } TUint8* EpocSdlEnv::LockHwSurface() { return gEpocEnv->iDsa->LockHwSurface(); } void EpocSdlEnv::UpdateSwSurface() { gEpocEnv->iDsa->UpdateSwSurface(); } TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect) { return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect); } void EpocSdlEnv::Request(TInt aService) { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); gEpocEnv->iAppSrv->Request(aService); } TSize EpocSdlEnv::WindowSize(const TSize& aRequestedSize) { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); if(EpocSdlEnv::Flags(CSDL::EAllowImageResize) && gEpocEnv->iDsa->WindowSize() != aRequestedSize) { TRAP_IGNORE(gEpocEnv->iDsa->CreateZoomerL(aRequestedSize)); } return gEpocEnv->iDsa->WindowSize(); } TSize EpocSdlEnv::WindowSize() { __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); return gEpocEnv->iDsa->WindowSize(); } TDisplayMode EpocSdlEnv::DisplayMode() { return gEpocEnv->iDsa->DisplayMode(); } TPointerCursorMode EpocSdlEnv::PointerMode() { return static_cast<TPointerCursorMode> (gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode)); } TInt EpocSdlEnv::SetPalette(TInt aFirstcolor, TInt aColorCount, TUint32* aPalette) { return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette); } void EpocSdlEnv::PanicMain(TInt aErr) { gEpocEnv->iAppSrv->PanicMain(aErr); } TInt EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem) { TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem)); return err; } void EpocSdlEnv::RemoveCleanupItem(TAny* aItem) { for(TInt i = 0; i < gEpocEnv->iCleanupItems->Count(); i++) { if(gEpocEnv->iCleanupItems->At(i).iItem == aItem) gEpocEnv->iCleanupItems->Delete(i); } } void EpocSdlEnv::CleanupItems() { const TThreadId id = RThread().Id(); TInt last = gEpocEnv->iCleanupItems->Count() - 1; TInt i; for(i = last; i >= 0 ; i--) { TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i); if(item.iThread == id) { item.iThread = TThreadId(0); item.iOperation(item.iItem); } } last = gEpocEnv->iCleanupItems->Count() - 1; for(i = last; i >= 0 ; i--) { TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i); if(item.iThread == TThreadId(0)) { gEpocEnv->iCleanupItems->Delete(i); } } } void EpocSdlEnv::FreeSurface() { Request(CSdlAppServ::EAppSrvDsaStatus); gEpocEnv->iDsa->Free(); } void EpocSdlEnv::LockPalette(TBool aLock) { gEpocEnv->iDsa->LockPalette(aLock); } void EpocSdlEnv::ObserverEvent(TInt aService, TInt aParam) { const TBool sdlThread = RThread().Id() == gEpocEnv->iId; const TInt valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam); gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread); if(sdlThread) { gEpocEnv->iAppSrv->SetParam(aParam); const TInt valuet = gEpocEnv->iAppSrv->RequestValue(aService); gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse); } } TPoint EpocSdlEnv::WindowCoordinates(const TPoint& aPoint) { return gEpocEnv->iDsa->WindowCoordinates(aPoint); } void EpocSdlEnv::PanicMain(const TDesC& aInfo, TInt aErr) { gEpocEnv->iAppSrv->PanicMain(aInfo, aErr); } //Dsa is a low priority ao, it has to wait if its pending event, but ws //event has been prioritized before it //this is not called from app thread! void EpocSdlEnv::WaitDeviceChange() { LockPalette(ETrue); gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa); const TSize sz = WindowSize(); const TInt param = reinterpret_cast<TInt>(&sz); ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param); // RThread().Suspend(); } LOCAL_C TBool CheckSdl() { TInt isExit = ETrue; RThread sdl; if(sdl.Open(gEpocEnv->iId) == KErrNone) { if(sdl.ExitType() == EExitPending) { isExit = EFalse; } sdl.Close(); } return isExit; } void EpocSdlEnvData::Free() { if(RThread().Id() == gEpocEnv->iId) { iDsa->Free(); return; } __ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrNotReady)); for(TInt i = 0; i < iArgc; i++) User::Free( iArgv[i] ); User::Free(iArgv); delete iEventQueue; if(iDsa != NULL) iDsa->Free(); delete iDsa; delete iAppSrv; } _LIT(KSDLMain, "SDLMain"); LOCAL_C int MainL() { gEpocEnv->iCleanupItems = new (ELeave) CArrayFixFlat<TSdlCleanupItem>(8); char** envp=0; /* !! process exits here if there is "exit()" in main! */ int ret = 0; for(TInt i = 0; i < 6; i++) { void* f = (void*) gEpocEnv->iMain[i]; if(f != NULL) { switch(i) { case 0: ret = ((mainfunc1)f)(); return ret; case 3: ((mainfunc1)f)(); return ret; case 1: ret = ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv()); return ret; case 4: ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv()); return ret; case 2: ret = ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp); return ret; case 5: ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp); return ret; } } } PANIC(KErrNotFound); return 0; } LOCAL_C TInt DoMain(TAny* /*aParam*/) { CTrapCleanup* cleanup = CTrapCleanup::New(); TBool fbsconnected = EFalse; if(RFbsSession::GetSession() == NULL) { PANIC_IF_ERROR(RFbsSession::Connect()); fbsconnected = ETrue; } gEpocEnv->iAppSrv->Init(); #ifdef SYMBIANC // Create stdlib _REENT; #endif // Call stdlib main int ret = 0; //completes waiting rendesvous RThread::Rendezvous(KErrNone); TRAPD(err, err = MainL()); EpocSdlEnv::ObserverEvent(MSDLObserver::EEventMainExit, err); // Free resources and return EpocSdlEnv::CleanupItems(); gEpocEnv->iCleanupItems->Reset(); delete gEpocEnv->iCleanupItems; gEpocEnv->iCleanupItems = NULL; gEpocEnv->Free(); //free up in thread resources #ifdef SYMBIANC _cleanup(); //this is normally called at exit, I call it here #endif if(fbsconnected) RFbsSession::Disconnect(); #ifdef SYMBIANC CloseSTDLIB(); #endif // delete as; delete cleanup; return err == KErrNone ? ret : err;; } EXPORT_C CSDL::~CSDL() { gEpocEnv->Free(); User::Free(gEpocEnv); gEpocEnv->iSdl = NULL; } EXPORT_C CSDL* CSDL::NewL(TInt aFlags) { __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists)); gEpocEnv = (EpocSdlEnvData*) User::AllocL(sizeof(EpocSdlEnvData)); Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData)); gEpocEnv->iEpocEnvFlags = aFlags; gEpocEnv->iEventQueue = CEventQueue::NewL(); gEpocEnv->iAppSrv = new (ELeave) CSdlAppServ(); gEpocEnv->iAppSrv->ConstructL(); CSDL* sdl = new (ELeave) CSDL(); gEpocEnv->iSdl = sdl; return sdl; } /* EXPORT_C void CSDL::ReInitL(TFlags aFlags) { const TFlags prevFlags = gEpocEnv->iEpocEnvFlags; gEpocEnv->iEpocEnvFlags = aFlags; TInt err = KErrNone; if(((prevFlags & EDrawModeDSB) != (aFlags & EDrawModeDSB)) && gEpocEnv->iDsa) { delete gEpocEnv->iDsa; gEpocEnv->iDsa = NULL; gEpocEnv->iDsa = CDsa::RecreateL(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)); } } */ EXPORT_C void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice) { if(gEpocEnv->iDsa == NULL) gEpocEnv->iDsa = CDsa::CreateL(aSession); gEpocEnv->iDsa->ConstructL(aWindow, aDevice); } EXPORT_C TThreadId CSDL::CallMainL(const TMainFunc& aFunc, TRequestStatus* const aStatus, const CDesC8Array* const aArg, TInt aFlags, TInt aStackSize) { ASSERT(gEpocEnv != NULL); gEpocEnv->iMain = aFunc; const TBool args = aArg != NULL; gEpocEnv->iArgc = aArg->Count() + 1; gEpocEnv->iArgv = (char**) User::AllocL(sizeof(char*) * (gEpocEnv->iArgc + 1)); TInt k = 0; const TFileName processName = RProcess().FileName(); const TInt len = processName.Length(); gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1); Mem::Copy(gEpocEnv->iArgv[k], processName.Ptr(), len); gEpocEnv->iArgv[k][len] = 0; for(TInt i = 0; args && (i < aArg->Count()); i++) { k++; const TInt len = aArg->MdcaPoint(i).Length(); gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1); Mem::Copy(gEpocEnv->iArgv[k], aArg->MdcaPoint(i).Ptr(), len); gEpocEnv->iArgv[k][len] = 0; } gEpocEnv->iArgv[gEpocEnv->iArgc] = NULL; RThread thread; User::LeaveIfError(thread.Create(KSDLMain, DoMain, aStackSize, NULL, NULL)); if(aStatus != NULL) { thread.Logon(*aStatus); } gEpocEnv->iId = thread.Id(); thread.SetPriority(EPriorityLess); if((aFlags & CSDL::ERequestResume) == 0) { thread.Resume(); } thread.Close(); return gEpocEnv->iId; } EXPORT_C TInt CSDL::AppendWsEvent(const TWsEvent& aEvent) { return EpocSdlEnv::EventQueue().Append(aEvent); } EXPORT_C void CSDL::SDLPanic(const TDesC& aInfo, TInt aErr) { EpocSdlEnv::PanicMain(aInfo, aErr); } EXPORT_C TInt CSDL::GetSDLCode(TInt aScanCode) { if(aScanCode < 0) return MAX_SCANCODE; if(aScanCode >= MAX_SCANCODE) return -1; return KeyMap()[aScanCode]; } EXPORT_C TInt CSDL::SDLCodesCount() const { return MAX_SCANCODE; } EXPORT_C void CSDL::ResetSDLCodes() { ResetKeyMap(); } EXPORT_C void CSDL::SetOrientation(TOrientationMode aMode) { gEpocEnv->iDsa->SetOrientation(aMode); } EXPORT_C TInt CSDL::SetSDLCode(TInt aScanCode, TInt aSDLCode) { const TInt current = GetSDLCode(aScanCode); if(aScanCode >= 0 && aScanCode < MAX_SCANCODE) KeyMap()[aScanCode] = static_cast<SDLKey>(aSDLCode); return current; } EXPORT_C MSDLObserver* CSDL::Observer() { return gEpocEnv->iAppSrv->Observer(); } EXPORT_C void CSDL::SetObserver(MSDLObserver* aObserver) { gEpocEnv->iAppSrv->SetObserver(aObserver); } EXPORT_C void CSDL::Resume() { EpocSdlEnv::Resume(); } EXPORT_C void CSDL::Suspend() { gEpocEnv->iDsa->DoStop(); } EXPORT_C CSDL::CSDL() { } EXPORT_C void CSDL::DisableKeyBlocking(CAknAppUi& aAppUi) const { gEpocEnv->iAppUi = &aAppUi; EnvUtils::DisableKeyBlocking(); } EXPORT_C TInt CSDL::SetBlitter(MBlitter* aBlitter) { if(gEpocEnv && gEpocEnv->iDsa) { gEpocEnv->iDsa->SetBlitter(aBlitter); return KErrNone; } return KErrNotReady; } EXPORT_C TInt CSDL::AppendOverlay(MOverlay& aOverlay, TInt aPriority) { if(gEpocEnv && gEpocEnv->iDsa) { return gEpocEnv->iDsa->AppendOverlay(aOverlay, aPriority); } return KErrNotReady; } EXPORT_C TInt CSDL::RemoveOverlay(MOverlay& aOverlay) { if(gEpocEnv && gEpocEnv->iDsa) { return gEpocEnv->iDsa->RemoveOverlay(aOverlay); } return KErrNotReady; } EXPORT_C TInt CSDL::RedrawRequest() { if(gEpocEnv && gEpocEnv->iDsa) { return gEpocEnv->iDsa->RedrawRequest(); } return KErrNotReady; } /* EXPORT_C CSDL* CSDL::Current() { return gEpocEnv != NULL ? gEpocEnv->iSdl : NULL; } EXPORT_C TInt CSDL::SetVolume(TInt aVolume) { return EpocSdlEnv::SetVolume(aVolume); } EXPORT_C TInt CSDL::Volume() const { return EpocSdlEnv::Volume(); } EXPORT_C TInt CSDL::MaxVolume() const { return EpocSdlEnv::MaxVolume(); } */ void EnvUtils::DisableKeyBlocking() { if(gEpocEnv->iAppUi != NULL) return CCurrentAppUi::Cast(gEpocEnv->iAppUi)->DisableKeyBlocking(); } TBool EnvUtils::Rendezvous(RThread& aThread, TRequestStatus& aStatus) { if(gEpocEnv->iId != TThreadId(0) && aThread.Open(gEpocEnv->iId) && aThread.ExitType() == EExitPending) { aThread.Rendezvous(aStatus); return ETrue; } return EFalse; }