symbian-qemu-0.9.1-12/libsdl-trunk/src/main/symbian/EKA2/SDL_main.cpp
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL_Main.cpp
       
     3     Symbian OS services for SDL
       
     4 
       
     5     Markus Mertama
       
     6 */
       
     7 
       
     8 
       
     9 #include "epoc_sdl.h"
       
    10 
       
    11 #include"sdlepocapi.h"
       
    12 #include <e32base.h>
       
    13 #include <estlib.h>
       
    14 #include <stdio.h>
       
    15 #include <badesca.h>
       
    16 
       
    17 #include "vectorbuffer.h"
       
    18 #include <w32std.h>
       
    19 #include <aknappui.h>
       
    20 #include <aknapp.h>
       
    21 #include "SDL_epocevents_c.h"
       
    22 #include "SDL_keysym.h"
       
    23 #include "dsa.h"
       
    24 
       
    25 
       
    26 #ifdef SYMBIANC
       
    27 #include <reent.h>
       
    28 #endif
       
    29 
       
    30 //Markus Mertama
       
    31 
       
    32 
       
    33 extern SDLKey* KeyMap();
       
    34 extern void ResetKeyMap();
       
    35 
       
    36 class CCurrentAppUi;
       
    37 
       
    38 //const TUid KSDLUid =  { 0xF01F3D69 };
       
    39 
       
    40 NONSHARABLE_CLASS(EnvUtils)
       
    41 	{
       
    42 	public:
       
    43 	static void DisableKeyBlocking();
       
    44 	static TBool Rendezvous(RThread& aThread, TRequestStatus& aStatus);
       
    45 	};
       
    46 
       
    47 TInt Panic(TInt aErr, TInt aLine)
       
    48 	{
       
    49 	TBuf<64> b;
       
    50 	b.Format(_L("Main at %d"), aLine);
       
    51 	User::Panic(b, aErr);
       
    52 	return 0;	
       
    53 	}
       
    54 	
       
    55 
       
    56 NONSHARABLE_CLASS(CCurrentAppUi) : public CAknAppUi
       
    57 	{
       
    58 	public:
       
    59 	static CCurrentAppUi* Cast(CEikAppUi* aUi);
       
    60 	void DisableKeyBlocking();
       
    61 	};
       
    62 	
       
    63 	
       
    64 CCurrentAppUi* CCurrentAppUi::Cast(CEikAppUi* aUi)
       
    65 	{
       
    66 	return static_cast<CCurrentAppUi*>(aUi);	
       
    67 	}
       
    68 	
       
    69 void CCurrentAppUi::DisableKeyBlocking()	
       
    70 	{
       
    71 	SetKeyBlockMode(ENoKeyBlock);	
       
    72 	}
       
    73 
       
    74 
       
    75 class CEventQueue : public CBase, public MEventQueue
       
    76     {
       
    77     public:
       
    78         static CEventQueue* NewL();
       
    79         ~CEventQueue();
       
    80     public:
       
    81         TInt Append(const TWsEvent& aEvent);
       
    82        	const TWsEvent& Shift();
       
    83        	void Lock();
       
    84        	void Unlock();
       
    85         TBool HasData();
       
    86     private:
       
    87         TVector<TWsEvent, 64> iVector;
       
    88         RCriticalSection iCS;
       
    89     };
       
    90     
       
    91  CEventQueue* CEventQueue::NewL()
       
    92     {
       
    93     CEventQueue* q = new (ELeave) CEventQueue();
       
    94     CleanupStack::PushL(q);
       
    95     User::LeaveIfError(q->iCS.CreateLocal());
       
    96     CleanupStack::Pop();
       
    97     return q;
       
    98     }
       
    99     
       
   100 CEventQueue::~CEventQueue()
       
   101     {
       
   102     iCS.Close();
       
   103     }
       
   104     
       
   105 TInt CEventQueue::Append(const TWsEvent& aEvent)
       
   106     {
       
   107     iCS.Wait();
       
   108    	const TInt err = iVector.Append(aEvent);
       
   109     iCS.Signal();
       
   110     return err;
       
   111     }
       
   112     
       
   113     
       
   114 TBool CEventQueue::HasData()
       
   115     {
       
   116     return iVector.Size() > 0;
       
   117     }
       
   118 
       
   119 
       
   120 void CEventQueue::Lock()
       
   121 	{
       
   122     iCS.Wait();
       
   123 	}
       
   124 	
       
   125 void CEventQueue::Unlock()
       
   126 	{
       
   127 	iCS.Signal();
       
   128 	}
       
   129 
       
   130 const TWsEvent& CEventQueue::Shift()
       
   131     {
       
   132     const TWsEvent& event =  iVector.Shift();
       
   133     return event;
       
   134     }
       
   135 
       
   136 
       
   137 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem) :
       
   138 iOperation(aOperation), iItem(aItem), iThread(RThread().Id())
       
   139     {
       
   140     }
       
   141 
       
   142 class CEikonEnv;
       
   143 class CSdlAppServ;
       
   144 
       
   145     
       
   146 NONSHARABLE_CLASS(EpocSdlEnvData)
       
   147     {
       
   148     public:
       
   149     void Free();
       
   150     CEventQueue*            iEventQueue;
       
   151     TMainFunc				iMain;
       
   152     TInt            		iEpocEnvFlags;
       
   153     int                     iArgc;
       
   154     char**                  iArgv;
       
   155     CDsa*                   iDsa;
       
   156     CSdlAppServ*            iAppSrv;
       
   157     TThreadId               iId;
       
   158     CArrayFix<TSdlCleanupItem>* iCleanupItems; 
       
   159     CEikAppUi*				iAppUi;
       
   160     CSDL*					iSdl;
       
   161     };
       
   162   
       
   163    
       
   164 EpocSdlEnvData* gEpocEnv;
       
   165 
       
   166 #define MAINFUNC(x) EXPORT_C TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
       
   167     
       
   168 MAINFUNC(1)
       
   169 MAINFUNC(2)
       
   170 MAINFUNC(3)
       
   171 MAINFUNC(4)
       
   172 MAINFUNC(5)
       
   173 MAINFUNC(6)
       
   174 
       
   175 EXPORT_C TMainFunc::TMainFunc() 
       
   176 	{
       
   177 	Mem::FillZ(iMainFunc, sizeof(iMainFunc));
       
   178 	}
       
   179 	
       
   180 
       
   181 const void* TMainFunc::operator[](TInt aIndex) const
       
   182 	{
       
   183 	return iMainFunc[aIndex];
       
   184 	}
       
   185 
       
   186 
       
   187 NONSHARABLE_CLASS(CSdlAppServ) : public CActive
       
   188     {
       
   189     public:
       
   190         enum
       
   191             {
       
   192             EAppSrvNoop = CDsa::ELastDsaRequest,
       
   193             EAppSrvWindowWidth,
       
   194             EAppSrvWindowHeight,
       
   195             EAppSrvWindowDisplayMode,
       
   196             EAppSrvWindowPointerCursorMode,
       
   197             EAppSrvDsaStatus,
       
   198             EAppSrvStopThread,
       
   199             EAppSrvWaitDsa
       
   200             };
       
   201         CSdlAppServ();
       
   202         void ConstructL();
       
   203         ~CSdlAppServ();
       
   204         TInt Request(TInt aService);
       
   205         TInt RequestValue(TInt aService);
       
   206         void Init(); 
       
   207         void PanicMain(TInt aReason);
       
   208         void PanicMain(const TDesC& aInfo, TInt aReason);
       
   209         void SetObserver(MSDLObserver* aObserver);
       
   210         TInt ObserverEvent(TInt aEvent, TInt aParam);
       
   211         void SetParam(TInt aParam);
       
   212         void HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread);
       
   213         MSDLObserver* Observer();
       
   214     private:
       
   215         void RunL();
       
   216         void DoCancel();
       
   217     private:
       
   218         const TThreadId iMainId;
       
   219         RThread iAppThread;
       
   220         TInt iService;
       
   221         TInt iReturnValue;
       
   222         RSemaphore iSema;
       
   223         MSDLObserver* iObserver;
       
   224         TRequestStatus* iStatusPtr;
       
   225     };
       
   226     
       
   227 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh), iMainId(RThread().Id())
       
   228     {
       
   229     }
       
   230     
       
   231     
       
   232     
       
   233 MSDLObserver* CSdlAppServ::Observer()
       
   234 	{
       
   235 	return iObserver;
       
   236 	}
       
   237 	
       
   238 	
       
   239 void CSdlAppServ::SetObserver(MSDLObserver* aObserver)
       
   240 	{
       
   241 	iObserver = aObserver;
       
   242 	}	
       
   243 	
       
   244 TInt CSdlAppServ::ObserverEvent(TInt aEvent, TInt aParam)
       
   245 	{
       
   246 	if(iObserver != NULL)
       
   247 		{
       
   248 		if(RThread().Id() == gEpocEnv->iId)
       
   249 			{
       
   250 			return iObserver->SdlThreadEvent(aEvent, aParam);
       
   251 			}
       
   252 		else if(RThread().Id() == iMainId)
       
   253 			{
       
   254 			return iObserver->SdlEvent(aEvent, aParam);
       
   255 			}
       
   256 		PANIC(KErrNotSupported);
       
   257 		}
       
   258 	return 0;
       
   259 	}
       
   260 	
       
   261 void CSdlAppServ::PanicMain(TInt aReason)    
       
   262     {
       
   263     iAppThread.Panic(RThread().Name(), aReason);
       
   264     }
       
   265     
       
   266 void CSdlAppServ::PanicMain(const TDesC& aInfo, TInt aReason)    
       
   267     {
       
   268     iAppThread.Panic(aInfo, aReason);
       
   269     }    
       
   270     
       
   271 void CSdlAppServ::ConstructL()
       
   272     {
       
   273     CActiveScheduler::Add(this);
       
   274     User::LeaveIfError(iSema.CreateLocal(1));
       
   275     iStatus = KRequestPending;
       
   276     iStatusPtr = &iStatus;
       
   277     SetActive();
       
   278     }
       
   279         
       
   280  CSdlAppServ::~CSdlAppServ()
       
   281     {
       
   282     Cancel();
       
   283     if(iSema.Handle() != NULL)
       
   284         iSema.Signal();
       
   285     iSema.Close();
       
   286     iAppThread.Close();
       
   287     }
       
   288     
       
   289 TInt CSdlAppServ::Request(TInt aService)
       
   290     {
       
   291     if(RThread().Id() != iAppThread.Id())
       
   292     	{
       
   293     	iSema.Wait();
       
   294     	iService = aService;
       
   295     	iAppThread.RequestComplete(iStatusPtr, KErrNone); 
       
   296     	return KErrNone;
       
   297     	}
       
   298     return KErrBadHandle;
       
   299     }
       
   300     
       
   301 TInt CSdlAppServ::RequestValue(TInt aService)
       
   302     {
       
   303     Request(aService);
       
   304     Request(EAppSrvNoop);
       
   305     return iReturnValue;
       
   306     }
       
   307    
       
   308 void CSdlAppServ::Init()
       
   309     {
       
   310     PANIC_IF_ERROR(iAppThread.Open(iMainId));
       
   311     }
       
   312 
       
   313 void CSdlAppServ::SetParam(TInt aParam)
       
   314 	{
       
   315 	iReturnValue = aParam;
       
   316 	}
       
   317 	
       
   318 void CSdlAppServ::HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread)
       
   319 	{
       
   320 	if(iObserver != NULL && aMainThread)
       
   321 		{
       
   322 		switch(aService)
       
   323 			{
       
   324 			case MSDLObserver::EEventScreenSizeChanged:
       
   325 			if(aReturnValue == MSDLObserver::EScreenSizeChangedDefaultPalette)
       
   326 				EpocSdlEnv::LockPalette(EFalse);
       
   327 			break;
       
   328 			}
       
   329 		}
       
   330 	if(!aMainThread && aService == MSDLObserver::EEventSuspend)
       
   331 		{
       
   332 		if(iObserver == NULL || 
       
   333 		(gEpocEnv->iDsa->Stopped() && aReturnValue != MSDLObserver::ESuspendNoSuspend))
       
   334 			{
       
   335 			EpocSdlEnv::Suspend();
       
   336 			}
       
   337 		}
       
   338 	}
       
   339 
       
   340 void CSdlAppServ::RunL()
       
   341     {
       
   342     if(iStatus == KErrNone)
       
   343         {
       
   344         switch(iService)
       
   345             {
       
   346             case CSdlAppServ::EAppSrvWaitDsa:
       
   347             	EpocSdlEnv::SetWaitDsa();
       
   348             	iReturnValue = EpocSdlEnv::IsDsaAvailable();
       
   349             //		}
       
   350             //	gEpocEnv->iDsa->Stop();
       
   351             //	gEpocEnv->iDsa->RestartL();
       
   352             	break;
       
   353            	 case CSdlAppServ::EAppSrvStopThread:
       
   354             	gEpocEnv->iDsa->SetSuspend();
       
   355             	break;
       
   356             case EpocSdlEnv::EDisableKeyBlocking:
       
   357                 EnvUtils::DisableKeyBlocking();
       
   358                 break;
       
   359           
       
   360             case EAppSrvWindowPointerCursorMode:
       
   361                 iReturnValue = gEpocEnv->iDsa != NULL ?
       
   362                  gEpocEnv->iDsa->Session().PointerCursorMode() : KErrNotReady; 
       
   363                 break;
       
   364             case EAppSrvDsaStatus:
       
   365             	gEpocEnv->iDsa->Stop();
       
   366                 iReturnValue = KErrNone;
       
   367                 break;
       
   368             case CDsa::ERequestUpdate:
       
   369             	gEpocEnv->iDsa->UnlockHWSurfaceRequestComplete();
       
   370             	break;
       
   371             case EAppSrvNoop:
       
   372                 break;
       
   373             case MSDLObserver::EEventResume:
       
   374             case MSDLObserver::EEventSuspend:
       
   375             case MSDLObserver::EEventScreenSizeChanged:
       
   376             case MSDLObserver::EEventWindowReserved:
       
   377             case MSDLObserver::EEventKeyMapInit:
       
   378             case MSDLObserver::EEventWindowNotAvailable:
       
   379             case MSDLObserver::EEventMainExit:
       
   380             	iReturnValue = ObserverEvent(iService, iReturnValue);
       
   381             	HandleObserverValue(iService, iReturnValue, ETrue);
       
   382             	break;
       
   383             default:
       
   384                 PANIC(KErrNotSupported);
       
   385             }
       
   386         iStatus = KRequestPending;
       
   387         iStatusPtr = &iStatus;
       
   388         SetActive();
       
   389         }
       
   390     iSema.Signal();
       
   391     }
       
   392     
       
   393 void CSdlAppServ::DoCancel()
       
   394     {
       
   395     iSema.Wait();
       
   396     TRequestStatus* s = &iStatus;
       
   397     iAppThread.RequestComplete(s, KErrCancel); 
       
   398     }
       
   399  
       
   400 
       
   401 
       
   402 MEventQueue& EpocSdlEnv::EventQueue()
       
   403     {
       
   404     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   405     return *gEpocEnv->iEventQueue;
       
   406     }
       
   407 
       
   408 
       
   409 TBool EpocSdlEnv::Flags(TInt aFlag)
       
   410     {
       
   411 	const TInt flag = gEpocEnv->iEpocEnvFlags & aFlag;
       
   412 	return flag == aFlag;
       
   413     }
       
   414 
       
   415 TInt EpocSdlEnv::Argc()
       
   416     {
       
   417     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   418     return gEpocEnv->iArgc;
       
   419     }
       
   420     
       
   421     
       
   422 char** EpocSdlEnv::Argv()
       
   423     {
       
   424     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   425     return gEpocEnv->iArgv;
       
   426     }
       
   427     
       
   428     
       
   429 TBool EpocSdlEnv::IsDsaAvailable()
       
   430     {
       
   431     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   432     return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
       
   433     }
       
   434 
       
   435   
       
   436 void EpocSdlEnv::WaitDsaAvailable()
       
   437 	{
       
   438 	EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0);
       
   439 	gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread);
       
   440 	if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
       
   441 		{
       
   442 		EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0);
       
   443 		}
       
   444 	}
       
   445 	
       
   446 void EpocSdlEnv::Suspend()
       
   447 	{
       
   448 	if(gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
       
   449 		{
       
   450 	//	gEpocEnv->iDsa->ReleaseStop(); 
       
   451 		gEpocEnv->iDsa->SetSuspend(); 
       
   452 		RThread().Suspend();
       
   453 		EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0);
       
   454 		}
       
   455 	}
       
   456 	
       
   457 void EpocSdlEnv::SetWaitDsa()
       
   458 	{
       
   459 	if(!IsDsaAvailable())
       
   460 		{
       
   461 		RThread th;
       
   462 		th.Open(gEpocEnv->iId);
       
   463 		th.Suspend();
       
   464 		th.Close();
       
   465 		gEpocEnv->iDsa->SetSuspend(); 
       
   466 		}
       
   467 	}
       
   468 	
       
   469 void EpocSdlEnv::Resume()
       
   470 	{
       
   471 	gEpocEnv->iDsa->Resume();
       
   472 	RThread th;
       
   473 	th.Open(gEpocEnv->iId);
       
   474 	th.Resume();
       
   475 	th.Close();
       
   476 	
       
   477 	const TInt value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, 0);
       
   478 	gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue);
       
   479 	}
       
   480     
       
   481 
       
   482 TInt EpocSdlEnv::AllocSwSurface(const TSize& aSize, TDisplayMode aMode)
       
   483 	{
       
   484 	return gEpocEnv->iDsa->AllocSurface(EFalse, aSize, aMode);
       
   485 	}
       
   486 	
       
   487 TInt EpocSdlEnv::AllocHwSurface(const TSize& aSize, TDisplayMode aMode)
       
   488 	{
       
   489 	return gEpocEnv->iDsa->AllocSurface(ETrue, aSize, aMode);
       
   490 	}
       
   491 		
       
   492 	
       
   493 void EpocSdlEnv::UnlockHwSurface()
       
   494 	{
       
   495 	gEpocEnv->iDsa->UnlockHwSurface();
       
   496 	}
       
   497 	
       
   498 TUint8* EpocSdlEnv::LockHwSurface()
       
   499 	{
       
   500 	return gEpocEnv->iDsa->LockHwSurface();
       
   501 	}
       
   502 
       
   503 
       
   504 void EpocSdlEnv::UpdateSwSurface()
       
   505 	{
       
   506 	gEpocEnv->iDsa->UpdateSwSurface();
       
   507 	}
       
   508 	
       
   509 TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
       
   510 	{
       
   511 	return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
       
   512 	}
       
   513 	
       
   514 void EpocSdlEnv::Request(TInt aService)
       
   515     {
       
   516     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   517     gEpocEnv->iAppSrv->Request(aService);
       
   518     }
       
   519     
       
   520     
       
   521 TSize EpocSdlEnv::WindowSize(const TSize& aRequestedSize)
       
   522     { 
       
   523     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   524     if(EpocSdlEnv::Flags(CSDL::EAllowImageResize) && gEpocEnv->iDsa->WindowSize() != aRequestedSize)
       
   525     	{
       
   526     	TRAP_IGNORE(gEpocEnv->iDsa->CreateZoomerL(aRequestedSize));
       
   527     	}
       
   528     return gEpocEnv->iDsa->WindowSize();
       
   529     }
       
   530     
       
   531  TSize EpocSdlEnv::WindowSize()
       
   532     { 
       
   533     __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
       
   534     return gEpocEnv->iDsa->WindowSize();
       
   535     }   
       
   536     
       
   537 TDisplayMode EpocSdlEnv::DisplayMode()
       
   538     {
       
   539     return gEpocEnv->iDsa->DisplayMode();
       
   540     }
       
   541     
       
   542 TPointerCursorMode EpocSdlEnv::PointerMode()
       
   543     {
       
   544     return static_cast<TPointerCursorMode>
       
   545     (gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode));
       
   546     }
       
   547     
       
   548 TInt EpocSdlEnv::SetPalette(TInt aFirstcolor, TInt aColorCount, TUint32* aPalette)  
       
   549 	{
       
   550 	return 	gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
       
   551 	}
       
   552 
       
   553 void EpocSdlEnv::PanicMain(TInt aErr)
       
   554     {
       
   555     gEpocEnv->iAppSrv->PanicMain(aErr);
       
   556     }
       
   557     
       
   558     
       
   559 TInt EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
       
   560     {
       
   561     TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
       
   562     return err;
       
   563     }
       
   564     
       
   565 void EpocSdlEnv::RemoveCleanupItem(TAny* aItem)
       
   566     {
       
   567     for(TInt i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
       
   568         {
       
   569         if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
       
   570             gEpocEnv->iCleanupItems->Delete(i);
       
   571         }
       
   572     }
       
   573     
       
   574 void EpocSdlEnv::CleanupItems()     
       
   575 	{
       
   576 	const TThreadId id = RThread().Id();
       
   577 	TInt last = gEpocEnv->iCleanupItems->Count() - 1;
       
   578 	TInt i;
       
   579 	for(i = last; i >= 0 ; i--)
       
   580         {
       
   581         TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
       
   582         if(item.iThread == id)
       
   583         	{
       
   584         	item.iThread = TThreadId(0); 
       
   585         	item.iOperation(item.iItem);
       
   586         	}
       
   587         }
       
   588     last = gEpocEnv->iCleanupItems->Count() - 1;
       
   589 	for(i = last; i >= 0 ; i--)
       
   590         {
       
   591         TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
       
   592         if(item.iThread == TThreadId(0))
       
   593         	{
       
   594         	gEpocEnv->iCleanupItems->Delete(i);
       
   595         	}
       
   596         }
       
   597 	}
       
   598 	
       
   599 void EpocSdlEnv::FreeSurface()
       
   600 	{
       
   601 	Request(CSdlAppServ::EAppSrvDsaStatus);
       
   602 	gEpocEnv->iDsa->Free();
       
   603 	}
       
   604   
       
   605 void EpocSdlEnv::LockPalette(TBool aLock)
       
   606 	{
       
   607 	gEpocEnv->iDsa->LockPalette(aLock);
       
   608 	}
       
   609     
       
   610 void EpocSdlEnv::ObserverEvent(TInt aService, TInt aParam)
       
   611 	{
       
   612 	const TBool sdlThread = RThread().Id() == gEpocEnv->iId;
       
   613 	const TInt valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam);
       
   614 	gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread);
       
   615 	if(sdlThread)
       
   616 		{
       
   617 		gEpocEnv->iAppSrv->SetParam(aParam);
       
   618 		const TInt valuet = gEpocEnv->iAppSrv->RequestValue(aService);
       
   619 		gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse);	
       
   620 		}
       
   621 	}
       
   622 			
       
   623     
       
   624 TPoint EpocSdlEnv::WindowCoordinates(const TPoint& aPoint)    
       
   625     {
       
   626     return gEpocEnv->iDsa->WindowCoordinates(aPoint);	
       
   627     }
       
   628     
       
   629 void EpocSdlEnv::PanicMain(const TDesC& aInfo, TInt aErr)
       
   630     {
       
   631     gEpocEnv->iAppSrv->PanicMain(aInfo, aErr);
       
   632     }
       
   633 //Dsa is a low priority ao, it has to wait if its pending event, but ws
       
   634 //event has been prioritized before it
       
   635 //this is not called from app thread!
       
   636 void EpocSdlEnv::WaitDeviceChange() 
       
   637     {
       
   638   	LockPalette(ETrue);
       
   639     gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa);
       
   640     const TSize sz = WindowSize();
       
   641     const TInt param = reinterpret_cast<TInt>(&sz);
       
   642     ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param);
       
   643     	
       
   644    // RThread().Suspend();
       
   645     }  
       
   646     
       
   647 LOCAL_C TBool CheckSdl() 
       
   648     {
       
   649     TInt isExit = ETrue;
       
   650     RThread sdl;
       
   651     if(sdl.Open(gEpocEnv->iId) == KErrNone)
       
   652         {
       
   653         if(sdl.ExitType() == EExitPending)
       
   654             {
       
   655             isExit = EFalse;
       
   656             }
       
   657         sdl.Close();
       
   658         }
       
   659     return isExit;
       
   660     }
       
   661     
       
   662 void EpocSdlEnvData::Free()
       
   663     {
       
   664     if(RThread().Id() == gEpocEnv->iId)
       
   665     	{
       
   666     	iDsa->Free();
       
   667     	return;
       
   668     	}
       
   669    
       
   670     __ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrNotReady));
       
   671         
       
   672     for(TInt i = 0; i < iArgc; i++)
       
   673         User::Free( iArgv[i] );
       
   674         
       
   675     User::Free(iArgv);	
       
   676      
       
   677     
       
   678     delete iEventQueue;
       
   679     
       
   680     if(iDsa != NULL)
       
   681     	iDsa->Free();
       
   682     
       
   683 	delete iDsa;
       
   684 	delete iAppSrv;
       
   685     }
       
   686 
       
   687 _LIT(KSDLMain, "SDLMain");
       
   688 
       
   689 LOCAL_C int MainL()
       
   690     {
       
   691     gEpocEnv->iCleanupItems = new (ELeave) CArrayFixFlat<TSdlCleanupItem>(8);
       
   692     
       
   693     char** envp=0;
       
   694      /* !! process exits here if there is "exit()" in main! */
       
   695     int ret = 0;
       
   696     for(TInt i = 0; i  < 6; i++)
       
   697         {
       
   698         void* f = (void*) gEpocEnv->iMain[i];
       
   699         if(f != NULL)
       
   700             {
       
   701             switch(i)
       
   702                 {
       
   703                 case 0:
       
   704                     ret = ((mainfunc1)f)(); 
       
   705                     return ret;
       
   706                 case 3:
       
   707                     ((mainfunc1)f)(); 
       
   708                     return ret;
       
   709                 case 1:
       
   710                     ret = ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
       
   711                     return ret;
       
   712                 case 4:
       
   713                     ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
       
   714                     return ret;
       
   715                 case 2:
       
   716                     ret = ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
       
   717                     return ret;
       
   718                 case 5:
       
   719                     ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
       
   720                     return ret;
       
   721                 }
       
   722             }
       
   723         }
       
   724     PANIC(KErrNotFound);
       
   725     return 0;
       
   726     }
       
   727 
       
   728 LOCAL_C TInt DoMain(TAny* /*aParam*/)
       
   729     {
       
   730     
       
   731     
       
   732     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   733       	
       
   734 	TBool fbsconnected = EFalse;
       
   735 	if(RFbsSession::GetSession() == NULL)
       
   736 	    {
       
   737 	    PANIC_IF_ERROR(RFbsSession::Connect());
       
   738 	    fbsconnected = ETrue;
       
   739 	    }
       
   740 	
       
   741  	gEpocEnv->iAppSrv->Init();	
       
   742 
       
   743 #ifdef SYMBIANC 
       
   744     // Create stdlib 
       
   745     _REENT;
       
   746 #endif
       
   747 
       
   748     // Call stdlib main
       
   749     int ret = 0;
       
   750     
       
   751     //completes waiting rendesvous
       
   752     RThread::Rendezvous(KErrNone);
       
   753     
       
   754     TRAPD(err, err = MainL());
       
   755     
       
   756     EpocSdlEnv::ObserverEvent(MSDLObserver::EEventMainExit, err);
       
   757    
       
   758     // Free resources and return
       
   759     
       
   760   	EpocSdlEnv::CleanupItems();
       
   761         
       
   762     gEpocEnv->iCleanupItems->Reset();
       
   763     delete gEpocEnv->iCleanupItems;
       
   764     gEpocEnv->iCleanupItems = NULL;
       
   765     
       
   766     gEpocEnv->Free(); //free up in thread resources 
       
   767     
       
   768 #ifdef SYMBIANC    
       
   769     _cleanup(); //this is normally called at exit, I call it here
       
   770 #endif
       
   771 
       
   772     if(fbsconnected)
       
   773         RFbsSession::Disconnect();
       
   774     
       
   775 #ifdef SYMBIANC     
       
   776     CloseSTDLIB();
       
   777 #endif
       
   778        
       
   779  //   delete as;
       
   780    	delete cleanup;	
       
   781 
       
   782     return err == KErrNone ? ret : err;;
       
   783     }
       
   784     
       
   785 
       
   786     
       
   787 EXPORT_C CSDL::~CSDL()
       
   788     {
       
   789    	gEpocEnv->Free();
       
   790     User::Free(gEpocEnv);
       
   791     gEpocEnv->iSdl = NULL;
       
   792     }
       
   793 
       
   794 EXPORT_C CSDL* CSDL::NewL(TInt aFlags)
       
   795     {
       
   796     __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists));
       
   797     gEpocEnv = (EpocSdlEnvData*) User::AllocL(sizeof(EpocSdlEnvData));
       
   798     Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData));
       
   799    
       
   800     gEpocEnv->iEpocEnvFlags = aFlags;
       
   801     gEpocEnv->iEventQueue = CEventQueue::NewL();
       
   802    
       
   803     gEpocEnv->iAppSrv = new (ELeave) CSdlAppServ();
       
   804     gEpocEnv->iAppSrv->ConstructL();
       
   805     
       
   806     CSDL* sdl = new (ELeave) CSDL();
       
   807     
       
   808     gEpocEnv->iSdl = sdl;
       
   809     
       
   810     return sdl;
       
   811     }
       
   812     
       
   813   /*  
       
   814 EXPORT_C void CSDL::ReInitL(TFlags aFlags)
       
   815 	{
       
   816 	const TFlags prevFlags = gEpocEnv->iEpocEnvFlags;
       
   817 	gEpocEnv->iEpocEnvFlags = aFlags;
       
   818 	TInt err = KErrNone;
       
   819 	if(((prevFlags & EDrawModeDSB) != (aFlags & EDrawModeDSB)) && gEpocEnv->iDsa)
       
   820 		{
       
   821 		delete gEpocEnv->iDsa;
       
   822 		gEpocEnv->iDsa = NULL;
       
   823 		gEpocEnv->iDsa = CDsa::RecreateL(EpocSdlEnv::Flags(CSDL::EDrawModeDSB));
       
   824 		}
       
   825 	}
       
   826  */
       
   827 
       
   828 
       
   829 EXPORT_C void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice)
       
   830     {
       
   831     if(gEpocEnv->iDsa == NULL)
       
   832     	gEpocEnv->iDsa = CDsa::CreateL(aSession);
       
   833     gEpocEnv->iDsa->ConstructL(aWindow, aDevice);
       
   834     }
       
   835         
       
   836    
       
   837 EXPORT_C TThreadId CSDL::CallMainL(const TMainFunc& aFunc, TRequestStatus* const aStatus, const CDesC8Array* const aArg, TInt aFlags, TInt aStackSize)
       
   838     {
       
   839     ASSERT(gEpocEnv != NULL);
       
   840     gEpocEnv->iMain = aFunc;
       
   841     const TBool args = aArg != NULL;
       
   842     
       
   843     gEpocEnv->iArgc = aArg->Count() + 1;
       
   844     gEpocEnv->iArgv = (char**) User::AllocL(sizeof(char*) * (gEpocEnv->iArgc + 1));  
       
   845       
       
   846     TInt k = 0;
       
   847     const TFileName processName = RProcess().FileName();
       
   848     const TInt len = processName.Length();
       
   849     gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1);
       
   850     Mem::Copy(gEpocEnv->iArgv[k], processName.Ptr(), len);
       
   851     gEpocEnv->iArgv[k][len] = 0;
       
   852       
       
   853     for(TInt i =  0; args && (i < aArg->Count()); i++)
       
   854         {
       
   855         k++;
       
   856         const TInt len = aArg->MdcaPoint(i).Length();
       
   857         gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1);
       
   858         Mem::Copy(gEpocEnv->iArgv[k], aArg->MdcaPoint(i).Ptr(), len);
       
   859         gEpocEnv->iArgv[k][len] = 0;
       
   860         }
       
   861         
       
   862     gEpocEnv->iArgv[gEpocEnv->iArgc] = NULL;
       
   863          
       
   864     RThread thread;
       
   865     User::LeaveIfError(thread.Create(KSDLMain, DoMain, aStackSize, NULL, NULL));
       
   866     
       
   867     if(aStatus != NULL)
       
   868     	{
       
   869     	thread.Logon(*aStatus);
       
   870     	}
       
   871     	
       
   872     gEpocEnv->iId = thread.Id();
       
   873     thread.SetPriority(EPriorityLess);
       
   874     if((aFlags & CSDL::ERequestResume) == 0)
       
   875         {
       
   876         thread.Resume();
       
   877         }
       
   878     thread.Close();
       
   879     return gEpocEnv->iId;
       
   880     }
       
   881     
       
   882 EXPORT_C TInt CSDL::AppendWsEvent(const TWsEvent& aEvent)
       
   883     {
       
   884     return EpocSdlEnv::EventQueue().Append(aEvent);
       
   885     }
       
   886     
       
   887 EXPORT_C void CSDL::SDLPanic(const TDesC& aInfo, TInt aErr)
       
   888     {
       
   889     EpocSdlEnv::PanicMain(aInfo, aErr);
       
   890     }
       
   891     
       
   892 EXPORT_C TInt CSDL::GetSDLCode(TInt aScanCode)
       
   893     {
       
   894     if(aScanCode < 0)
       
   895         return MAX_SCANCODE;
       
   896     if(aScanCode >= MAX_SCANCODE)
       
   897         return -1;
       
   898     return KeyMap()[aScanCode];
       
   899     }
       
   900     
       
   901 EXPORT_C TInt CSDL::SDLCodesCount() const
       
   902 	{
       
   903 	return MAX_SCANCODE;
       
   904 	}
       
   905 	
       
   906 EXPORT_C void CSDL::ResetSDLCodes()
       
   907 	{
       
   908 	ResetKeyMap();
       
   909 	}
       
   910     
       
   911 EXPORT_C void CSDL::SetOrientation(TOrientationMode aMode)
       
   912 	{
       
   913 	gEpocEnv->iDsa->SetOrientation(aMode);
       
   914 	}
       
   915     
       
   916 EXPORT_C TInt CSDL::SetSDLCode(TInt aScanCode, TInt aSDLCode)
       
   917     {
       
   918     const TInt current = GetSDLCode(aScanCode);
       
   919     if(aScanCode >= 0 && aScanCode < MAX_SCANCODE)
       
   920         KeyMap()[aScanCode] = static_cast<SDLKey>(aSDLCode);
       
   921     return current;
       
   922     }
       
   923 
       
   924 
       
   925 EXPORT_C MSDLObserver* CSDL::Observer()
       
   926 	{
       
   927 	return gEpocEnv->iAppSrv->Observer();
       
   928 	}    
       
   929     
       
   930 EXPORT_C void CSDL::SetObserver(MSDLObserver* aObserver)
       
   931 	{
       
   932 	gEpocEnv->iAppSrv->SetObserver(aObserver);
       
   933 	}
       
   934 	
       
   935 EXPORT_C void CSDL::Resume()
       
   936 	{
       
   937 	EpocSdlEnv::Resume();
       
   938 	}
       
   939 	
       
   940 EXPORT_C void CSDL::Suspend()
       
   941 	{
       
   942 	gEpocEnv->iDsa->DoStop();
       
   943 	}
       
   944 	
       
   945 EXPORT_C CSDL::CSDL()
       
   946     {
       
   947     }
       
   948 
       
   949 EXPORT_C void CSDL::DisableKeyBlocking(CAknAppUi& aAppUi) const
       
   950 	{
       
   951 	gEpocEnv->iAppUi = &aAppUi;
       
   952 	EnvUtils::DisableKeyBlocking();
       
   953 	}
       
   954 
       
   955 EXPORT_C TInt CSDL::SetBlitter(MBlitter* aBlitter)
       
   956 	{
       
   957 	if(gEpocEnv && gEpocEnv->iDsa)
       
   958 		{
       
   959 		gEpocEnv->iDsa->SetBlitter(aBlitter);
       
   960 		return KErrNone;
       
   961 		}
       
   962 	return KErrNotReady;
       
   963 	}
       
   964 		
       
   965 	
       
   966 EXPORT_C TInt CSDL::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
       
   967 	{
       
   968 	if(gEpocEnv && gEpocEnv->iDsa)
       
   969 		{
       
   970 		return gEpocEnv->iDsa->AppendOverlay(aOverlay, aPriority);
       
   971 		}
       
   972 	return KErrNotReady;
       
   973 	}
       
   974 
       
   975 EXPORT_C TInt CSDL::RemoveOverlay(MOverlay& aOverlay)	
       
   976 	{
       
   977 	if(gEpocEnv && gEpocEnv->iDsa)
       
   978 		{
       
   979 		return gEpocEnv->iDsa->RemoveOverlay(aOverlay);
       
   980 		}
       
   981 	return KErrNotReady;
       
   982 	}
       
   983 
       
   984 EXPORT_C TInt CSDL::RedrawRequest()
       
   985 	{
       
   986 	if(gEpocEnv && gEpocEnv->iDsa)
       
   987 		{
       
   988 		return gEpocEnv->iDsa->RedrawRequest();
       
   989 		}
       
   990 	return KErrNotReady;
       
   991 	}
       
   992 	
       
   993 /*
       
   994 EXPORT_C CSDL* CSDL::Current()
       
   995     {
       
   996     return gEpocEnv != NULL ? gEpocEnv->iSdl : NULL;
       
   997     }
       
   998 
       
   999     
       
  1000 EXPORT_C TInt CSDL::SetVolume(TInt aVolume)
       
  1001     {
       
  1002     return EpocSdlEnv::SetVolume(aVolume);
       
  1003     } 
       
  1004     
       
  1005 EXPORT_C TInt CSDL::Volume() const
       
  1006     {
       
  1007     return EpocSdlEnv::Volume();
       
  1008     }     
       
  1009 	
       
  1010 EXPORT_C TInt CSDL::MaxVolume() const
       
  1011     {
       
  1012     return EpocSdlEnv::MaxVolume();
       
  1013     } 	
       
  1014 */
       
  1015 			
       
  1016 void EnvUtils::DisableKeyBlocking()
       
  1017 	{
       
  1018 	if(gEpocEnv->iAppUi != NULL)
       
  1019 		return CCurrentAppUi::Cast(gEpocEnv->iAppUi)->DisableKeyBlocking();
       
  1020 	}
       
  1021 	
       
  1022 TBool EnvUtils::Rendezvous(RThread& aThread, TRequestStatus& aStatus)
       
  1023 	{
       
  1024 	if(gEpocEnv->iId != TThreadId(0) &&
       
  1025     		 	aThread.Open(gEpocEnv->iId) &&
       
  1026     		  	aThread.ExitType() == EExitPending)
       
  1027     			{
       
  1028     			aThread.Rendezvous(aStatus);
       
  1029     			return ETrue;
       
  1030     			}
       
  1031     return EFalse;
       
  1032 	}
       
  1033 	
       
  1034 	
       
  1035