📄 sdl_main.cpp
字号:
/* 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 Mertamaextern 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -