From a855d6202536ff28e5aae4f22a0f31d8f5b325d0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 21 Jan 2017 15:18:31 -0500 Subject: Port of Duke Nukem 3D This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9 --- .../plugins/sdl/src/main/symbian/EKA1/SDL_main.cpp | 152 +++ .../plugins/sdl/src/main/symbian/EKA2/SDL_main.cpp | 1035 ++++++++++++++++++++ apps/plugins/sdl/src/main/symbian/EKA2/sdlexe.cpp | 809 +++++++++++++++ apps/plugins/sdl/src/main/symbian/EKA2/sdllib.cpp | 12 + .../sdl/src/main/symbian/EKA2/vectorbuffer.cpp | 62 ++ .../sdl/src/main/symbian/EKA2/vectorbuffer.h | 240 +++++ 6 files changed, 2310 insertions(+) create mode 100644 apps/plugins/sdl/src/main/symbian/EKA1/SDL_main.cpp create mode 100644 apps/plugins/sdl/src/main/symbian/EKA2/SDL_main.cpp create mode 100644 apps/plugins/sdl/src/main/symbian/EKA2/sdlexe.cpp create mode 100644 apps/plugins/sdl/src/main/symbian/EKA2/sdllib.cpp create mode 100644 apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.cpp create mode 100644 apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h (limited to 'apps/plugins/sdl/src/main/symbian') diff --git a/apps/plugins/sdl/src/main/symbian/EKA1/SDL_main.cpp b/apps/plugins/sdl/src/main/symbian/EKA1/SDL_main.cpp new file mode 100644 index 0000000000..683db874ff --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA1/SDL_main.cpp @@ -0,0 +1,152 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_main.cpp + The Epoc executable startup functions + + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_error.h" + +#if defined(__WINS__) +#include +IMPORT_C void RegisterWsExe(const TDesC &aName); +#endif + +/* The prototype for the application's main() function */ +#define main SDL_main +extern "C" int main (int argc, char *argv[], char *envp[]); +extern "C" void exit (int ret); + + +/* Epoc main function */ + +#ifdef __WINS__ + + +void GetCmdLine(int& aArgc, char**& aArgv) + { + RChunk chunk; + + if(chunk.OpenGlobal(RThread().Name(), ETrue) != KErrNone) + return; + + TUint* ptr = (TUint*) chunk.Base(); + if(ptr != NULL) + { + aArgc = (int) *(ptr); // count + aArgv = (char**) *(ptr + 1); + } + chunk.Close(); + } + +#endif + + +TInt E32Main() + { + /* Get the clean-up stack */ + CTrapCleanup* cleanup = CTrapCleanup::New(); + + /* Arrange for multi-threaded operation */ + SpawnPosixServerThread(); + + /* Get args and environment */ + int argc=0; + char** argv=0; + char** envp=0; + +#ifndef __WINS__ + __crt0(argc,argv,envp); +#else + GetCmdLine(argc, argv); +#endif + /* Start the application! */ + + /* Create stdlib */ + _REENT; + + /* Set process and thread priority and name */ + + RThread currentThread; + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + currentThread.Rename(exeName.Name()); + currentThread.SetProcessPriority(EPriorityLow); + currentThread.SetPriority(EPriorityMuchLess); + + /* Call stdlib main */ + int ret = main(argc, argv, envp); /* !! process exits here if there is "exit()" in main! */ + + /* Call exit */ + //exit(ret); /* !! process exits here! */ + //Markus: I do not understand above + //I commented it at let this function + //to return ret value - was it purpose + //that cleanup below is not called at all - why? + + /* Free resources and return */ + + _cleanup(); //this is normally called at exit, I call it here, Markus + + CloseSTDLIB(); + delete cleanup; +#ifdef __WINS__ +// User::Panic(_L("exit"), ret); + // RThread().Kill(ret); //Markus get rid of this thread + // RThread().RaiseException(EExcKill); +#endif + return ret;//Markus, or exit(ret); ?? + //return(KErrNone); + } + + +#ifdef __WINS__ +EXPORT_C TInt WinsMain() + { + return E32Main(); + // return WinsMain(0, 0, 0); + } +#endif + +/* Epoc dll entry point */ +#if defined(__WINS__) +GLDEF_C TInt E32Dll(TDllReason) + { + return(KErrNone); + } +#endif + + diff --git a/apps/plugins/sdl/src/main/symbian/EKA2/SDL_main.cpp b/apps/plugins/sdl/src/main/symbian/EKA2/SDL_main.cpp new file mode 100644 index 0000000000..3dc69d4aad --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA2/SDL_main.cpp @@ -0,0 +1,1035 @@ +/* + SDL_Main.cpp + Symbian OS services for SDL + + Markus Mertama +*/ + + +#include "epoc_sdl.h" + +#include"sdlepocapi.h" +#include +#include +#include +#include + +#include "vectorbuffer.h" +#include +#include +#include +#include "SDL_epocevents_c.h" +#include "SDL_keysym.h" +#include "dsa.h" + + +#ifdef SYMBIANC +#include +#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(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 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* 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 + (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(&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(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(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; + } + + + diff --git a/apps/plugins/sdl/src/main/symbian/EKA2/sdlexe.cpp b/apps/plugins/sdl/src/main/symbian/EKA2/sdlexe.cpp new file mode 100644 index 0000000000..bb160c4090 --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA2/sdlexe.cpp @@ -0,0 +1,809 @@ +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +// FORWARD DECLARATIONS +class CApaDocument; + + +//const TUid KSDLUID = { 0xF01F605E }; + +LOCAL_C void MakeCCmdLineL(const TDesC8& aParam, CDesC8Array& aArray) + { + + const TChar dq('\"'); + + TLex8 lex(aParam); + TBool in = EFalse; + + lex.SkipSpaceAndMark(); + + while(!lex.Eos()) + { + TPtrC8 ptr; + if(in) + { + const TPtrC8 rem = lex.RemainderFromMark(); + const TInt pos = rem.Locate(dq); + if(pos > 0) + { + lex.Inc(pos); + ptr.Set(lex.MarkedToken()); + lex.SkipAndMark(1); + } + else + { + ptr.Set(rem); + } + in = EFalse; + } + else + { + ptr.Set(lex.NextToken()); + const TInt pos = ptr.Locate(dq); + if(pos == 0) + { + lex.UnGetToMark(); + lex.SkipAndMark(1); + in = ETrue; + continue; // back to in brace + } + else + lex.SkipSpaceAndMark(); + } + + aArray.AppendL(ptr); + + } + } + +NONSHARABLE_CLASS(TVirtualCursor) : public MOverlay + { + public: + TVirtualCursor(); + void Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha); + void Move(TInt aX, TInt aY); + void MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const; + void Toggle(); + TBool IsOn() const; + private: + void Draw(CBitmapContext& aGc, const TRect& aTargetRect, const TSize& aSize); + private: + TRect iRect; + TPoint iInc; + TPoint iPos; + TBool iIsOn; + CFbsBitmap* iCBmp; + CFbsBitmap* iAlpha; + }; + + +TVirtualCursor::TVirtualCursor() : iInc(0, 0), iIsOn(EFalse), iCBmp(NULL) + { + } + +const TInt KMaxMove = 10; + +void TVirtualCursor::Move(TInt aX, TInt aY) + { + if(aX > 0 && iInc.iX > 0) + ++iInc.iX; + else if(aX < 0 && iInc.iX < 0) + --iInc.iX; + else + iInc.iX = aX; + + if(aY > 0 && iInc.iY > 0) + ++iInc.iY; + else if(aY < 0 && iInc.iY < 0) + --iInc.iY; + else + iInc.iY = aY; + + iInc.iX = Min(KMaxMove, iInc.iX); + + iInc.iX = Max(-KMaxMove, iInc.iX); + + iInc.iY = Min(KMaxMove, iInc.iY); + + iInc.iY =Max(-KMaxMove, iInc.iY); + + const TPoint pos = iPos + iInc; + if(iRect.Contains(pos)) + { + iPos = pos; + } + else + { + iInc = TPoint(0, 0); + } + } + + +void TVirtualCursor::Toggle() + { + iIsOn = !iIsOn; + } + + +TBool TVirtualCursor::IsOn() const + { + return iIsOn; + } + +void TVirtualCursor::Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha) + { + iRect = aRect; + iCBmp = aBmp; + iAlpha = aAlpha; + } + + +void TVirtualCursor::MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const + { + aEvent.SetType(EEventPointer), + aEvent.SetTimeNow(); + TPointerEvent& pointer = *aEvent.Pointer(); + pointer.iType = TPointerEvent::EButton1Down; + pointer.iPosition = iPos; + pointer.iParentPosition = aBasePos; + } + + +void TVirtualCursor::Draw(CBitmapContext& aGc, const TRect& /*aTargetRect*/, const TSize& /*aSize*/) + { + if(iIsOn && iCBmp != NULL) + { + const TRect rect(TPoint(0, 0), iCBmp->SizeInPixels()); + aGc.AlphaBlendBitmaps(iPos, iCBmp, rect, iAlpha, TPoint(0, 0)); + } + + } + +NONSHARABLE_CLASS(TSdlClass) + { + public: + TSdlClass(); + void SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags); + TInt SdlFlags() const; + const TMainFunc& Main() const; + void SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL); + TInt AppFlags() const; + void AppFlags(TInt aFlags); + private: + TMainFunc iFunc; + TInt iSdlFlags; + TInt iExeFlags; + MSDLMainObs* iObs; + }; + + +void TSdlClass::AppFlags(TInt aFlags) + { + iExeFlags |= aFlags; + } + +void TSdlClass::SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL) + { + if(iObs != NULL) + iObs->SDLMainEvent(aEvent, aParam, aSDL); + } + +TInt TSdlClass::AppFlags() const + { + return iExeFlags; + } + +void TSdlClass::SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags) + { + iFunc = aFunc; + iSdlFlags = aFlags; + iExeFlags = aExeFlags; + iObs = aObs; + } + +const TMainFunc& TSdlClass::Main() const + { + return iFunc; + } + + + TInt TSdlClass::SdlFlags() const + { + return iSdlFlags; + } + + + +TSdlClass::TSdlClass() + { + Mem::FillZ(this, sizeof(this)); + } + +TSdlClass gSDLClass; + + +//////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CSDLApplication) : public CAknApplication + { + public: + CSDLApplication(); + private: + CApaDocument* CreateDocumentL(); + TFileName ResourceFileName() const; + TUid AppDllUid() const; + void FindMeL(); + TUid iUid; + }; + +NONSHARABLE_CLASS(CSDLDocument) : public CEikDocument + { + public: + CSDLDocument(CEikApplication& aApp); + private: + CEikAppUi* CreateAppUiL(); + + }; + + //////////////////////////////////////////////////////////////////// + + +NONSHARABLE_CLASS(MExitWait) + { + public: + virtual void DoExit(TInt aErr) = 0; + }; + +///////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CExitWait) : public CActive + { + public: + CExitWait(MExitWait& aWait); + ~CExitWait(); + private: + void RunL(); + void DoCancel(); + private: + MExitWait& iWait; + TRequestStatus* iStatusPtr; + }; + +//////////////////////////////////////////////////////////////////////// + + +NONSHARABLE_CLASS(CSDLWin) : public CCoeControl + { + public: + void ConstructL(const TRect& aRect); + RWindow& GetWindow() const; + void SetNoDraw(); + private: + void Draw(const TRect& aRect) const; + private: + TBool iNoDraw; + }; + + +//////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi, public MExitWait, MSDLObserver + { + public: + ~CSDLAppUi(); + private: // New functions + void ConstructL(); + void HandleCommandL(TInt aCommand); + void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination); + void HandleResourceChangeL(TInt aType); + + void DoExit(TInt aErr); + + TInt SdlEvent(TInt aEvent, TInt aParam); + TInt SdlThreadEvent(TInt aEvent, TInt aParam); + + void StartL(); + static TBool StartL(TAny* aThis); + + TBool ParamEditorL(TDes& aCheat); + + TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine); + + void PrepareToExit(); + void HandleConsoleWindowL(); + void HandleConsoleWindow(); + void HandleForegroundEventL(TBool aForeground); + + static TBool IdleRequestL(TAny* aThis); + + TBool HandleKeyL(const TWsEvent& aEvent); + + + private: + CExitWait* iWait; + CSDLWin* iSDLWin; + CSDL* iSdl; + CIdle* iStarter; + TBool iExitRequest; + CDesC8Array* iParams; + TInt iResOffset; + CIdle* iIdle; + TInt iStdOut; + TVirtualCursor iCursor; + CFbsBitmap* iCBmp; + CFbsBitmap* iAlpha; + // TTime iLastPress; + // CSDL::TOrientationMode iOrientation; + }; + +////////////////////////////////////////////////////////////////////////////////////////7 + +CApaDocument* CSDLApplication::CreateDocumentL() + { + return new (ELeave) CSDLDocument(*this); + } + +TUid CSDLApplication::AppDllUid() const + { + return iUid; + } + + +CSDLApplication::CSDLApplication() + { + TRAPD(err, FindMeL()); + ASSERT(err == KErrNone); + } + +void CSDLApplication::FindMeL() + { + RApaLsSession apa; + User::LeaveIfError(apa.Connect()); + CleanupClosePushL(apa); + User::LeaveIfError(apa.GetAllApps()); + TFileName name = RProcess().FileName(); + TApaAppInfo info; + while(apa.GetNextApp(info) == KErrNone) + { + if(info.iFullName.CompareF(name) == 0) + { + iUid = info.iUid; + break; + } + } + CleanupStack::PopAndDestroy(); + } + +TFileName CSDLApplication::ResourceFileName() const + { + return KNullDesC(); + } + +/////////////////////////////////////////////////////////////////////////////////////////// + +CExitWait::CExitWait(MExitWait& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait) + { + CActiveScheduler::Add(this); + SetActive(); + iStatusPtr = &iStatus; + } + +CExitWait::~CExitWait() + { + Cancel(); + } + +void CExitWait::RunL() + { + if(iStatusPtr != NULL ) + iWait.DoExit(iStatus.Int()); + } + +void CExitWait::DoCancel() + { + if(iStatusPtr != NULL ) + User::RequestComplete(iStatusPtr , KErrCancel); + } + + +////////////////////////////////////////////////////////////////////////////////////////////// + +CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp) + {} + +CEikAppUi* CSDLDocument::CreateAppUiL() + { + return new (ELeave) CSDLAppUi; + } + +/////////////////////////////////////////////////////////////////////////// + +void CSDLWin:: ConstructL(const TRect& aRect) + { + CreateWindowL(); + SetRect(aRect); + ActivateL(); + } + + +RWindow& CSDLWin::GetWindow() const + { + return Window(); + } + + +void CSDLWin::Draw(const TRect& /*aRect*/) const + { + if(!iNoDraw) + { + CWindowGc& gc = SystemGc(); + gc.SetPenStyle(CGraphicsContext::ESolidPen); + gc.SetPenColor(KRgbGray); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetBrushColor(0xaaaaaa); + gc.DrawRect(Rect()); + } + } + +void CSDLWin::SetNoDraw() + { + iNoDraw = ETrue; + } + +///////////////////////////////////////////////////////////////////////// + +CSDLAppUi::~CSDLAppUi() + { + if(iIdle) + iIdle->Cancel(); + delete iIdle; + if(iStarter != NULL) + iStarter->Cancel(); + delete iStarter; + delete iWait; + delete iSdl; + delete iSDLWin; + delete iParams; + delete iCBmp; + delete iAlpha; + } + + +void CSDLAppUi::ConstructL() + { + BaseConstructL(ENoAppResourceFile | ENoScreenFurniture); + + + RLibrary lib; + User::LeaveIfError(lib.Load(_L("sdlexe.dll"))); + TFileName name = lib.FileName(); + lib.Close(); + name.Replace(3, name.Length() - 3, _L("resource\\apps\\sdlexe.rsc")); + BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(), name); + iResOffset = iCoeEnv->AddResourceFileL(name); + + name.Replace(name.Length() - 3, 3, _L("mbm")); + + TEntry e; + const TInt err = iEikonEnv->FsSession().Entry(name, e); + + iCBmp = iEikonEnv->CreateBitmapL(name, 0); + iAlpha = iEikonEnv->CreateBitmapL(name, 1); + + iIdle = CIdle::NewL(CActive::EPriorityIdle); + + iSDLWin = new (ELeave) CSDLWin; + iSDLWin->ConstructL(ApplicationRect()); + + iSdl = CSDL::NewL(gSDLClass.SdlFlags()); + + gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl); + + iSdl->SetObserver(this); + iSdl->DisableKeyBlocking(*this); + iSdl->SetContainerWindowL( + iSDLWin->GetWindow(), + iEikonEnv->WsSession(), + *iEikonEnv->ScreenDevice()); + iSdl->AppendOverlay(iCursor, 0); + + iCursor.Set(TRect(TPoint(0, 0), iSDLWin->Size()), iCBmp, iAlpha); + + iStarter = CIdle::NewL(CActive::EPriorityLow); + iStarter->Start(TCallBack(StartL, this)); + + + } + + + +TBool CSDLAppUi::StartL(TAny* aThis) + { + static_cast(aThis)->StartL(); + return EFalse; + } + + +void CSDLAppUi::PrepareToExit() + { + CAknAppUiBase::PrepareToExit(); //aknappu::PrepareToExit crashes + iCoeEnv->DeleteResourceFile(iResOffset); + } + +TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine) + { + const TPtrC8 cmdLine = aCommandLine.TailEnd(); + iParams = new (ELeave) CDesC8ArrayFlat(8); + MakeCCmdLineL(cmdLine, *iParams); + return EFalse; + } + + + TBool CSDLAppUi::ParamEditorL(TDes& aCheat) + { + CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat); + CleanupStack::PushL(query); + query->SetPromptL(_L("Enter parameters")); + CleanupStack::Pop(); + return query->ExecuteLD(R_PARAMEDITOR); + } + + void CSDLAppUi::StartL() + { + if(gSDLClass.AppFlags() & SDLEnv::EParamQuery) + { + TBuf8<256> cmd; + RFile file; + TInt err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead); + if(err == KErrNone) + { + file.Read(cmd); + file.Close(); + MakeCCmdLineL(cmd, *iParams); + } + if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery)) + { + TBuf<256> buffer; + if(ParamEditorL(buffer)) + { + cmd.Copy(buffer); + MakeCCmdLineL(cmd, *iParams); + } + } + } + iWait = new (ELeave) CExitWait(*this); + iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000); + } + +void CSDLAppUi::HandleCommandL(TInt aCommand) + { + switch(aCommand) + { + case EAknSoftkeyBack: + case EAknSoftkeyExit: + case EAknCmdExit: + case EEikCmdExit: + gSDLClass.AppFlags(SDLEnv::EAllowConsoleView); + if(iWait == NULL || !iWait->IsActive() || iSdl == NULL) + { + Exit(); + } + else if(!iExitRequest) + { + iExitRequest = ETrue; //trick how SDL can be closed! + iSdl->Suspend(); + } + break; + } + } + + + +TBool CSDLAppUi::HandleKeyL(const TWsEvent& aEvent) + { + const TInt type = aEvent.Type(); + if(!(type == EEventKey || type == EEventKeyUp || type == EEventKeyDown)) + { + return ETrue; + } + const TKeyEvent& key = *aEvent.Key(); + if((key.iScanCode == EStdKeyYes) && (gSDLClass.AppFlags() & SDLEnv::EVirtualMouse)) + { + if(type == EEventKeyUp) + { + iCursor.Toggle(); + iSdl->RedrawRequest(); + } + return EFalse; + } + if(iCursor.IsOn()) + { + switch(key.iScanCode) + { + case EStdKeyUpArrow: + iCursor.Move(0, -1); + break; + case EStdKeyDownArrow: + iCursor.Move(0, 1); + break; + case EStdKeyLeftArrow: + iCursor.Move(-1, 0); + break; + case EStdKeyRightArrow: + iCursor.Move(1, 0); + break; + case EStdKeyDevice3: + if(type == EEventKeyUp) + { + TWsEvent event; + iCursor.MakeEvent(event, iSDLWin->Position()); + iSdl->AppendWsEvent(event); + } + return EFalse; + default: + return ETrue; + } + iSdl->RedrawRequest(); + return EFalse; + } + return ETrue; + } + + void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination) + { + if(iSdl && iWait && HandleKeyL(aEvent)) + iSdl->AppendWsEvent(aEvent); + CAknAppUi::HandleWsEventL(aEvent, aDestination); + } + + void CSDLAppUi::HandleResourceChangeL(TInt aType) + { + CAknAppUi::HandleResourceChangeL(aType); + if(aType == KEikDynamicLayoutVariantSwitch) + { + iSDLWin->SetRect(ApplicationRect()); + iSdl->SetContainerWindowL( + iSDLWin->GetWindow(), + iEikonEnv->WsSession(), + *iEikonEnv->ScreenDevice()); + } + } + + +void CSDLAppUi::DoExit(TInt/*Err*/) + { + iExitRequest = ETrue; + Exit(); + } + + + TInt CSDLAppUi::SdlThreadEvent(TInt aEvent, TInt /*aParam*/) + { + switch(aEvent) + { + case MSDLObserver::EEventResume: + break; + case MSDLObserver::EEventSuspend: + if(iExitRequest) + return MSDLObserver::ESuspendNoSuspend; + break; + case MSDLObserver::EEventWindowReserved: + break; + case MSDLObserver::EEventWindowNotAvailable: + break; + case MSDLObserver::EEventScreenSizeChanged: + break; + } + return MSDLObserver::EParameterNone; + } + +TInt CSDLAppUi::SdlEvent(TInt aEvent, TInt /*aParam*/) + { + switch(aEvent) + { + case MSDLObserver::EEventResume: + break; + case MSDLObserver::EEventSuspend: + if(iExitRequest) + return MSDLObserver::ESuspendNoSuspend; + break; + case MSDLObserver::EEventWindowReserved: + break; + case MSDLObserver::EEventWindowNotAvailable: + { + TRAP_IGNORE(HandleConsoleWindowL()); + } + break; + case MSDLObserver::EEventScreenSizeChanged: + break; + case MSDLObserver::EEventKeyMapInit: + break; + case MSDLObserver::EEventMainExit: + if(iStdOut != 0) + { + gSDLClass.AppFlags(SDLEnv::EAllowConsoleView); + iEikonEnv->WsSession().SetWindowGroupOrdinalPosition(iStdOut, 0); + } + break; + } + return MSDLObserver::EParameterNone; + } + +void CSDLAppUi::HandleForegroundEventL(TBool aForeground) + { + CAknAppUi::HandleForegroundEventL(aForeground); + if(!aForeground) + HandleConsoleWindow(); + } + +void CSDLAppUi::HandleConsoleWindow() + { + if(!iIdle->IsActive()) + iIdle->Start(TCallBack(IdleRequestL, this)); + } + +TBool CSDLAppUi::IdleRequestL(TAny* aThis) + { + static_cast(aThis)->HandleConsoleWindowL(); + return EFalse; + } + +void CSDLAppUi::HandleConsoleWindowL() + { + if(gSDLClass.AppFlags() & SDLEnv::EAllowConsoleView) + { + return; + } + RWsSession& ses = iEikonEnv->WsSession(); + const TInt focus = ses.GetFocusWindowGroup(); + CApaWindowGroupName* name = CApaWindowGroupName::NewLC(ses, focus); + const TPtrC caption = name->Caption(); + if(0 == caption.CompareF(_L("STDOUT"))) + { + iStdOut = focus; + ses.SetWindowGroupOrdinalPosition(iEikonEnv->RootWin().Identifier(), 0); + } + CleanupStack::PopAndDestroy(); //name + } + + +//////////////////////////////////////////////////////////////////////// + + +CApaApplication* NewApplication() + { + return new CSDLApplication(); + } + + +EXPORT_C TInt SDLEnv::SetMain(const TMainFunc& aFunc, TInt aSdlFlags, MSDLMainObs* aObs, TInt aSdlExeFlags) + { + gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags); + return EikStart::RunApplication(NewApplication); + } + +////////////////////////////////////////////////////////////////////// + +TInt SDLUiPrint(const TDesC8& /*aInfo*/) + { + return KErrNotFound; + } + + + diff --git a/apps/plugins/sdl/src/main/symbian/EKA2/sdllib.cpp b/apps/plugins/sdl/src/main/symbian/EKA2/sdllib.cpp new file mode 100644 index 0000000000..7c09996ec7 --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA2/sdllib.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + + +GLREF_C TInt E32Main() + { + return SDLEnv::SetMain(SDL_main, CSDL::EEnableFocusStop | CSDL::EAllowImageResize, + NULL, SDLEnv::EParamQuery | SDLEnv::EVirtualMouse); + } + + \ No newline at end of file diff --git a/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.cpp b/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.cpp new file mode 100644 index 0000000000..72c3b3e5c0 --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.cpp @@ -0,0 +1,62 @@ +/* + vectorbuffer.cpp + yet another circle buffer + + Markus Mertama +*/ + +#include"vectorbuffer.h" + + + +void VectorPanic(TInt aErr, TInt aLine) + { + TBuf<64> b; + b.Format(_L("vector buffer at % d "), aLine); + User::Panic(b, aErr); + } + +void TNodeBuffer::TNode::Terminator(TNodeBuffer::TNode* aNode) + { + Mem::Copy(iSucc, &aNode, sizeof(TNode*)); + } + +TInt TNodeBuffer::TNode::Size() const + { + return reinterpret_cast(iSucc) - Ptr(); + } + +const TUint8* TNodeBuffer::TNode::Ptr() const + { + return reinterpret_cast(this) + sizeof(TNode); + } + +TNodeBuffer::TNode* TNodeBuffer::TNode::Empty(TUint8* aBuffer) + { + TNode* node = reinterpret_cast(aBuffer); + node->iSucc = node + 1; + return node; + } + + TNodeBuffer::TNode* TNodeBuffer::TNode::New(TNode* aPred, const TDesC8& aData) + { + TNode* node = aPred->Size() == 0 ? aPred : aPred->iSucc; + + + TUint8* start = reinterpret_cast(node) + sizeof(TNode); + node->iSucc = reinterpret_cast(start + aData.Size()); + node->iSucc->iSucc = NULL; //terminator + + __ASSERT_DEBUG(node->Size() == aData.Size(), VECPANIC(KErrCorrupt)); + + Mem::Copy(start, aData.Ptr(), aData.Size()); + return node; + } + + + + + + + + \ No newline at end of file diff --git a/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h b/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h new file mode 100644 index 0000000000..3d8be58d6a --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h @@ -0,0 +1,240 @@ +/* + vectorbuffer.cpp + yet another circle buffer + + Markus Mertama +*/ + +#ifndef __VECTORBUFFER_H__ +#define __VECTORBUFFER_H__ + +#include +#define VLOG(x) +#define VECPANIC(x) VectorPanic(x, __LINE__) +void VectorPanic(TInt, TInt); + + +//int DEBUG_INT; + +NONSHARABLE_CLASS(TNodeBuffer) + { + public: + protected: + NONSHARABLE_CLASS(TNode) + { + public: + static TNode* Empty(TUint8* iBuffer); + static TNode* New(TNode* aPrev, const TDesC8& aData); + const TUint8* Ptr() const; + TInt Size() const; + inline TNode* Succ(); + static void SetSucc(TNode*& aNode); + void Terminator(TNode* aNode); + private: + TNode* iSucc; + }; + }; + +inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ() + { + return iSucc; + } + +template +NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer + { + public: + TVectorBuffer(); + TInt Append(const TDesC8& aData); + // TInt AppendOverwrite(const TDesC8& aData); + TPtrC8 Shift(); + TPtrC8 operator[](TInt aIndex) const; + TInt Size() const; + private: + TInt GetRoom(TInt aSize) const; + TInt Unreserved() const; + private: + TNode* iTop; + TNode* iBottom; + TInt iSize; + TUint8 iBuffer[C]; + }; + +template +TVectorBuffer::TVectorBuffer() : iSize(0) + { + Mem::FillZ(iBuffer, C); + iTop = TNode::Empty(iBuffer); //these points to buffer + iBottom = TNode::Empty(iBuffer); + } + +template +TInt TVectorBuffer::Unreserved() const + { + __ASSERT_DEBUG(iBottom < iBottom->Succ(), VECPANIC(KErrCorrupt)); + const TInt bytesbetween = + reinterpret_cast(iBottom->Succ()) - + reinterpret_cast(iTop); + const TInt topsize = sizeof(TNode); + if(bytesbetween > 0) //bytesbetween is room between bottom and top + { //therefore free room is subracted from free space + + const TInt room = C - bytesbetween - topsize; + return room; + } + if(bytesbetween == 0) + { + + if(Size() > 0) + return 0; + else + return C - topsize; + } + const TInt room = -bytesbetween - topsize; //free is space between pointers + return room; + } + +template +TInt TVectorBuffer::GetRoom(TInt aSize) const + { + const TInt bytesnew = sizeof(TNode) + aSize; + const TInt room = Unreserved() - bytesnew; + return room; + } + +template +TInt TVectorBuffer::Append(const TDesC8& aData) //ei ole ok! + { + const TInt len = aData.Length(); + if(GetRoom(len) < 0) + { + return KErrOverflow; + } + if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode))))) + { + VLOG("rc"); + // RDebug::Print(_L("vector: append")); + TNode* p = TNode::Empty(iBuffer); + iBottom->Terminator(p); + iBottom = p; + return Append(aData); + // Append(); + // iBottom = TNode::New(p, aData); //just append something into end + } + + //DEBUG_INT++; + + iBottom = TNode::New(iBottom, aData); + + iSize += len; + return KErrNone; + } + +/* +template +TInt TVectorBuffer::AppendOverwrite(const TDesC8& aData) //ei ole ok! + { + while(Append(aData) == KErrOverflow) + { + if(iTop->Succ() == NULL) + { + return KErrUnderflow; + } + //Shift(); //data is lost + } + return KErrNone; + } +*/ +template +TPtrC8 TVectorBuffer::Shift() + { + __ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + TNode* node = iTop; + iTop = iTop->Succ(); + if(iTop > node) + { + // DEBUG_INT--; + iSize -= node->Size(); + return TPtrC8(node->Ptr(), node->Size()); + } + else + { + // RDebug::Print(_L("vector: shift")); + return Shift(); //this happens when buffer is terminated, and data lies in next + } + } + +template +TInt TVectorBuffer::Size() const + { + return iSize; + } + +template +TPtrC8 TVectorBuffer::operator[](TInt aIndex) const + { + TInt index = 0; + TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator + while(index < aIndex) + { + TNode* nt = t->Succ(); + if(nt < t) + { + nt = nt->Succ(); + } + t = nt; + if(t->Size() > 0) + index++; + __ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + } + return t->Ptr(); + } + + +template +NONSHARABLE_CLASS(TVector) : public TVectorBuffer + { + public: + TVector(); + TInt Append(const T& aData); + const T& Shift(); + TInt Size() const; + const T& operator[](TInt aIndex) const; + }; + +template +TVector::TVector() : TVectorBuffer() + { + } + +template +TInt TVector::Append(const T& aData) + { + const TPckgC data(aData); + return TVectorBuffer::Append(data); + } + +template +const T& TVector::Shift() + { + const TPtrC8 ptr = TVectorBuffer::Shift(); + return *(reinterpret_cast(ptr.Ptr())); + } + + +template +TInt TVector::Size() const + { + return TVectorBuffer::Size() / sizeof(T); + } + +template +const T& TVector::operator[](TInt aIndex) const + { + const TPtrC8 ptr = TVectorBuffer::operator[](aIndex); + return *(reinterpret_cast(ptr.Ptr())); + } + +#endif + + -- cgit v1.2.3