Don't suspend SDL when exit is requested.
[SDL.s60v3.git] / src / main / symbian / sdlexe.cpp
blobc723a4ce6bb299a44e99c0ed0ee1bddb923383ea
1 #include <aknapp.h>
2 #include <aknappui.h>
3 #include <eikdoc.h>
4 #include <sdlepocapi.h>
5 #include <bautils.h>
6 #include <eikstart.h>
7 #include <badesca.h>
8 #include <bautils.h>
9 #include <apgcli.h>
10 #include <sdlmain.h>
11 #include <eikedwin.h>
12 #include <eiklabel.h>
13 #include <sdlexe.rsg>
14 #include <aknglobalmsgquery.h>
15 #include <apgwgnam.h>
17 class CApaDocument;
19 LOCAL_C void MakeCCmdLineL(const TDesC8& aParam, CDesC8Array& aArray)
21 const TChar dq('\"');
23 TLex8 lex(aParam);
24 TBool in = EFalse;
26 lex.SkipSpaceAndMark();
28 while(!lex.Eos())
30 TPtrC8 ptr;
31 if(in)
33 const TPtrC8 rem = lex.RemainderFromMark();
34 const int pos = rem.Locate(dq);
35 if(pos > 0)
37 lex.Inc(pos);
38 ptr.Set(lex.MarkedToken());
39 lex.SkipAndMark(1);
41 else
43 ptr.Set(rem);
45 in = EFalse;
47 else
49 ptr.Set(lex.NextToken());
50 const int pos = ptr.Locate(dq);
51 if(pos == 0)
53 lex.UnGetToMark();
54 lex.SkipAndMark(1);
55 in = ETrue;
56 continue; // back to in brace
58 else
59 lex.SkipSpaceAndMark();
62 aArray.AppendL(ptr);
66 NONSHARABLE_CLASS(TSdlClass)
68 public:
69 TSdlClass();
70 void SetMain(const TMainFunc& aFunc, int aFlags, MSDLMainObs* aObs, int aExeFlags);
71 int SdlFlags() const;
72 const TMainFunc& Main() const;
73 void SendEvent(int aEvent, int aParam, CSDL* aSDL);
74 int AppFlags() const;
75 void AppFlags(int aFlags);
77 private:
78 TMainFunc iFunc;
79 int iSdlFlags;
80 int iExeFlags;
81 MSDLMainObs* iObs;
85 void TSdlClass::AppFlags(int aFlags)
87 iExeFlags |= aFlags;
90 void TSdlClass::SendEvent(int aEvent, int aParam, CSDL* aSDL)
92 if(iObs != NULL)
93 iObs->SDLMainEvent(aEvent, aParam, aSDL);
96 int TSdlClass::AppFlags() const
98 return iExeFlags;
101 void TSdlClass::SetMain(const TMainFunc& aFunc, int aFlags, MSDLMainObs* aObs, int aExeFlags)
103 iFunc = aFunc;
104 iSdlFlags = aFlags;
105 iExeFlags = aExeFlags;
106 iObs = aObs;
109 const TMainFunc& TSdlClass::Main() const
111 return iFunc;
115 int TSdlClass::SdlFlags() const
117 return iSdlFlags;
120 TSdlClass::TSdlClass()
122 Mem::FillZ(this, sizeof(this));
125 TSdlClass gSDLClass;
127 ////////////////////////////////////////////////////////////////
129 NONSHARABLE_CLASS(CSDLApplication) : public CAknApplication
131 public:
132 CSDLApplication();
134 private:
135 CApaDocument* CreateDocumentL();
136 TFileName ResourceFileName() const;
137 TUid AppDllUid() const;
138 void FindMeL();
140 TUid iUid;
143 NONSHARABLE_CLASS(CSDLDocument) : public CEikDocument
145 public:
146 CSDLDocument(CEikApplication& aApp);
148 private:
149 CEikAppUi* CreateAppUiL();
152 ////////////////////////////////////////////////////////////////////
154 NONSHARABLE_CLASS(MExitWait)
156 public:
157 virtual void DoExit(int aErr) = 0;
160 /////////////////////////////////////////////////////////////////////////
162 NONSHARABLE_CLASS(CExitWait) : public CActive
164 public:
165 CExitWait(MExitWait& aWait);
166 ~CExitWait();
168 private:
169 void RunL();
170 void DoCancel();
172 MExitWait& iWait;
173 TRequestStatus* iStatusPtr;
176 ////////////////////////////////////////////////////////////////////////
178 NONSHARABLE_CLASS(CSDLWin) : public CCoeControl
180 public:
181 void ConstructL(const TRect& aRect);
182 RWindow& GetWindow() const;
184 private:
185 void Draw(const TRect& aRect) const;
188 ////////////////////////////////////////////////////////////////////////////
190 NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi, public MExitWait, public MSDLObserver
192 public:
193 ~CSDLAppUi();
195 private:
196 void ConstructL();
197 void HandleCommandL(int aCommand);
198 void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination);
199 void HandleResourceChangeL(int aType);
201 void DoExit(int aErr);
203 int SdlEvent(int aEvent, int aParam);
204 int SdlThreadEvent(int aEvent, int aParam);
206 void StartL();
207 static TBool StartL(TAny* aThis);
209 TBool ParamEditorL(TDes& aCheat);
211 TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine);
213 void PrepareToExit();
214 void HandleConsoleWindowL();
215 void HandleConsoleWindow();
216 void HandleForegroundEventL(TBool aForeground);
218 static TBool IdleRequestL(TAny* aThis);
220 CExitWait* iWait;
221 CSDLWin* iSDLWin;
222 CSDL* iSdl;
223 CIdle* iStarter;
224 CDesC8Array* iParams;
225 int iResOffset;
226 CIdle* iIdle;
227 int iStdOut;
230 ////////////////////////////////////////////////////////////////////////////////////////
232 CApaDocument* CSDLApplication::CreateDocumentL()
234 return new (ELeave) CSDLDocument(*this);
237 TUid CSDLApplication::AppDllUid() const
239 return iUid;
242 CSDLApplication::CSDLApplication()
244 TRAPD(err, FindMeL());
245 ASSERT(err == KErrNone);
248 void CSDLApplication::FindMeL()
250 RApaLsSession apa;
251 User::LeaveIfError(apa.Connect());
252 CleanupClosePushL(apa);
253 User::LeaveIfError(apa.GetAllApps());
254 TFileName name = RProcess().FileName();
255 TApaAppInfo info;
256 while(apa.GetNextApp(info) == KErrNone)
258 if(info.iFullName.CompareF(name) == 0)
260 iUid = info.iUid;
261 break;
264 CleanupStack::PopAndDestroy();
267 TFileName CSDLApplication::ResourceFileName() const
269 return KNullDesC();
272 ///////////////////////////////////////////////////////////////////////////////////////////
274 CExitWait::CExitWait(MExitWait& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait)
276 CActiveScheduler::Add(this);
277 SetActive();
278 iStatusPtr = &iStatus;
281 CExitWait::~CExitWait()
283 Cancel();
286 void CExitWait::RunL()
288 if(iStatusPtr != NULL)
289 iWait.DoExit(iStatus.Int());
292 void CExitWait::DoCancel()
294 if(iStatusPtr != NULL)
295 User::RequestComplete(iStatusPtr, KErrCancel);
298 //////////////////////////////////////////////////////////////////////////////////////////////
300 CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp)
303 CEikAppUi* CSDLDocument::CreateAppUiL()
305 return new (ELeave) CSDLAppUi;
308 ///////////////////////////////////////////////////////////////////////////
310 void CSDLWin::ConstructL(const TRect& aRect)
312 CreateWindowL();
313 SetRect(aRect);
314 ActivateL();
317 RWindow& CSDLWin::GetWindow() const
319 return Window();
322 void CSDLWin::Draw(const TRect& /*aRect*/) const
324 CWindowGc& gc = SystemGc();
325 gc.SetPenStyle(CGraphicsContext::ESolidPen);
326 gc.SetPenColor(KRgbGray);
327 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
328 gc.SetBrushColor(0x000000);
329 gc.DrawRect(Rect());
332 /////////////////////////////////////////////////////////////////////////
334 CSDLAppUi::~CSDLAppUi()
336 if(iIdle)
337 iIdle->Cancel();
338 delete iIdle;
339 if(iStarter)
340 iStarter->Cancel();
341 delete iStarter;
342 delete iWait;
343 delete iSdl;
344 delete iSDLWin;
345 delete iParams;
348 void CSDLAppUi::ConstructL()
350 BaseConstructL(ENoAppResourceFile | ENoScreenFurniture);
352 RFs fs;
353 fs.Connect();
354 TFileName name;
355 fs.PrivatePath(name);
356 fs.Close();
357 name.Append( _L("sdlexe.rsc") );
358 name.Insert( 0, _L("C:") );
359 iResOffset = iCoeEnv->AddResourceFileL(name);
361 iIdle = CIdle::NewL(CActive::EPriorityIdle);
363 iSDLWin = new (ELeave) CSDLWin;
364 iSDLWin->ConstructL(ApplicationRect());
366 iSdl = CSDL::NewL(gSDLClass.SdlFlags());
368 gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl);
370 iSdl->SetObserver(this);
371 iSdl->DisableKeyBlocking(*this);
372 iSdl->SetContainerWindowL(
373 iSDLWin->GetWindow(),
374 iEikonEnv->WsSession(),
375 *iEikonEnv->ScreenDevice());
377 iStarter = CIdle::NewL(CActive::EPriorityLow);
378 iStarter->Start(TCallBack(StartL, this));
381 TBool CSDLAppUi::StartL(TAny* aThis)
383 static_cast<CSDLAppUi*>(aThis)->StartL();
384 return EFalse;
387 void CSDLAppUi::PrepareToExit()
389 CAknAppUiBase::PrepareToExit(); //aknappu::PrepareToExit crashes
390 iCoeEnv->DeleteResourceFile(iResOffset);
393 TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine)
395 const TPtrC8 cmdLine = aCommandLine.TailEnd();
396 iParams = new (ELeave) CDesC8ArrayFlat(8);
397 MakeCCmdLineL(cmdLine, *iParams);
398 return EFalse;
401 TBool CSDLAppUi::ParamEditorL(TDes& aCheat)
403 CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat);
404 CleanupStack::PushL(query);
405 query->SetPromptL(_L("Enter parameters"));
406 CleanupStack::Pop();
407 return query->ExecuteLD(R_PARAMEDITOR);
410 void CSDLAppUi::StartL()
412 if(gSDLClass.AppFlags() & SDLEnv::EParamQuery)
414 TBuf8<256> cmd;
415 RFile file;
416 int err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead);
417 if(err == KErrNone)
419 file.Read(cmd);
420 file.Close();
421 MakeCCmdLineL(cmd, *iParams);
423 if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery))
425 TBuf<256> buffer;
426 if(ParamEditorL(buffer))
428 cmd.Copy(buffer);
429 MakeCCmdLineL(cmd, *iParams);
433 iWait = new (ELeave) CExitWait(*this);
434 iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000);
437 void CSDLAppUi::HandleCommandL(int aCommand)
439 switch(aCommand)
441 case EAknSoftkeyBack:
442 case EAknSoftkeyExit:
443 case EAknCmdExit:
444 case EEikCmdExit:
445 gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
446 if(iWait == NULL || !iWait->IsActive() || iSdl == NULL)
448 Exit();
450 else
452 TWsEvent event;
453 event.SetType(EEventSwitchOff), event.SetTimeNow();
454 iSdl->AppendWsEvent(event);
456 break;
460 void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
462 if(iSdl && iWait)
463 iSdl->AppendWsEvent(aEvent);
464 CAknAppUi::HandleWsEventL(aEvent, aDestination);
467 void CSDLAppUi::HandleResourceChangeL(int aType)
469 CAknAppUi::HandleResourceChangeL(aType);
470 if(aType == KEikDynamicLayoutVariantSwitch)
472 iSDLWin->SetRect(ApplicationRect());
473 iSdl->SetContainerWindowL(
474 iSDLWin->GetWindow(),
475 iEikonEnv->WsSession(),
476 *iEikonEnv->ScreenDevice());
480 void CSDLAppUi::DoExit(int/*Err*/)
482 Exit();
485 int CSDLAppUi::SdlThreadEvent(int aEvent, int /*aParam*/)
487 switch(aEvent)
489 case MSDLObserver::EEventResume:
490 break;
491 case MSDLObserver::EEventSuspend:
492 break;
493 case MSDLObserver::EEventWindowReserved:
494 break;
495 case MSDLObserver::EEventWindowNotAvailable:
496 break;
497 case MSDLObserver::EEventScreenSizeChanged:
498 break;
500 return MSDLObserver::EParameterNone;
503 int CSDLAppUi::SdlEvent(int aEvent, int /*aParam*/)
505 switch(aEvent)
507 case MSDLObserver::EEventResume:
508 break;
509 case MSDLObserver::EEventSuspend:
510 break;
511 case MSDLObserver::EEventWindowReserved:
512 break;
513 case MSDLObserver::EEventWindowNotAvailable:
515 TRAP_IGNORE(HandleConsoleWindowL());
517 break;
518 case MSDLObserver::EEventScreenSizeChanged:
519 break;
520 case MSDLObserver::EEventKeyMapInit:
521 break;
522 case MSDLObserver::EEventMainExit:
523 if(iStdOut != 0)
525 gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
526 iEikonEnv->WsSession().SetWindowGroupOrdinalPosition(iStdOut, 0);
528 break;
530 return MSDLObserver::EParameterNone;
533 void CSDLAppUi::HandleForegroundEventL(TBool aForeground)
535 CAknAppUi::HandleForegroundEventL(aForeground);
536 if(!aForeground)
537 HandleConsoleWindow();
540 void CSDLAppUi::HandleConsoleWindow()
542 if(!iIdle->IsActive())
543 iIdle->Start(TCallBack(IdleRequestL, this));
546 TBool CSDLAppUi::IdleRequestL(TAny* aThis)
548 static_cast<CSDLAppUi*>(aThis)->HandleConsoleWindowL();
549 return EFalse;
552 void CSDLAppUi::HandleConsoleWindowL()
554 if(gSDLClass.AppFlags() & SDLEnv::EAllowConsoleView)
556 return;
558 RWsSession& ses = iEikonEnv->WsSession();
559 const int focus = ses.GetFocusWindowGroup();
560 CApaWindowGroupName* name = CApaWindowGroupName::NewLC(ses, focus);
561 const TPtrC caption = name->Caption();
562 if(0 == caption.CompareF(_L("STDOUT")))
564 iStdOut = focus;
565 ses.SetWindowGroupOrdinalPosition(iEikonEnv->RootWin().Identifier(), 0);
567 CleanupStack::PopAndDestroy(); //name
570 ////////////////////////////////////////////////////////////////////////
572 CApaApplication* NewApplication()
574 return new CSDLApplication();
577 EXPORT_C int SDLEnv::SetMain(const TMainFunc& aFunc, int aSdlFlags, MSDLMainObs* aObs, int aSdlExeFlags)
579 gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags);
580 return EikStart::RunApplication(NewApplication);