blob: 3dc69d4aad1bf5994525c34c86d9e1837e49a137 [file] [log] [blame]
/*
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;
}