Simplify exit procedure.
[SDL.s60v3.git] / src / main / symbian / sdlexe.cpp
blob1a8a0f334724629980919e9fa528f50f5e0a6350
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(CExitWait) : public CActive
156 public:
157 CExitWait(CAknAppUi& aWait);
158 ~CExitWait();
160 private:
161 void RunL();
162 void DoCancel();
164 CAknAppUi& iWait;
165 TRequestStatus* iStatusPtr;
168 ////////////////////////////////////////////////////////////////////////
170 NONSHARABLE_CLASS(CSDLWin) : public CCoeControl
172 public:
173 void ConstructL(const TRect& aRect);
174 RWindow& GetWindow() const;
176 private:
177 void Draw(const TRect& aRect) const;
180 ////////////////////////////////////////////////////////////////////////////
182 NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi
184 public:
185 ~CSDLAppUi();
187 private:
188 void ConstructL();
189 void HandleCommandL(int aCommand);
190 void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination);
191 void HandleResourceChangeL(int aType);
193 void StartL();
194 static TBool StartL(TAny* aThis);
196 TBool ParamEditorL(TDes& aCheat);
198 TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine);
200 void HandleForegroundEventL(TBool aForeground);
202 CExitWait* iWait;
203 CSDLWin* iSDLWin;
204 CSDL* iSdl;
205 CIdle* iStarter;
206 CDesC8Array* iParams;
207 int iResOffset;
210 ////////////////////////////////////////////////////////////////////////////////////////
212 CApaDocument* CSDLApplication::CreateDocumentL()
214 return new (ELeave) CSDLDocument(*this);
217 TUid CSDLApplication::AppDllUid() const
219 return iUid;
222 CSDLApplication::CSDLApplication()
224 TRAPD(err, FindMeL());
225 ASSERT(err == KErrNone);
228 void CSDLApplication::FindMeL()
230 RApaLsSession apa;
231 User::LeaveIfError(apa.Connect());
232 CleanupClosePushL(apa);
233 User::LeaveIfError(apa.GetAllApps());
234 TFileName name = RProcess().FileName();
235 TApaAppInfo info;
236 while(apa.GetNextApp(info) == KErrNone)
238 if(info.iFullName.CompareF(name) == 0)
240 iUid = info.iUid;
241 break;
244 CleanupStack::PopAndDestroy();
247 TFileName CSDLApplication::ResourceFileName() const
249 return KNullDesC();
252 ///////////////////////////////////////////////////////////////////////////////////////////
254 CExitWait::CExitWait(CAknAppUi& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait)
256 CActiveScheduler::Add(this);
257 SetActive();
258 iStatusPtr = &iStatus;
261 CExitWait::~CExitWait()
263 Cancel();
266 void CExitWait::RunL()
268 if(iStatusPtr != NULL)
269 iWait.Exit();
272 void CExitWait::DoCancel()
274 if(iStatusPtr != NULL)
275 User::RequestComplete(iStatusPtr, KErrCancel);
278 //////////////////////////////////////////////////////////////////////////////////////////////
280 CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp)
283 CEikAppUi* CSDLDocument::CreateAppUiL()
285 return new (ELeave) CSDLAppUi;
288 ///////////////////////////////////////////////////////////////////////////
290 void CSDLWin::ConstructL(const TRect& aRect)
292 CreateWindowL();
293 SetRect(aRect);
294 ActivateL();
297 RWindow& CSDLWin::GetWindow() const
299 return Window();
302 void CSDLWin::Draw(const TRect& /*aRect*/) const
304 CWindowGc& gc = SystemGc();
305 gc.SetPenStyle(CGraphicsContext::ESolidPen);
306 gc.SetPenColor(KRgbGray);
307 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
308 gc.SetBrushColor(0x000000);
309 gc.DrawRect(Rect());
312 /////////////////////////////////////////////////////////////////////////
314 CSDLAppUi::~CSDLAppUi()
316 if(iStarter)
317 iStarter->Cancel();
318 delete iStarter;
319 delete iWait;
320 delete iSdl;
321 delete iSDLWin;
322 delete iParams;
325 void CSDLAppUi::ConstructL()
327 BaseConstructL(ENoAppResourceFile | ENoScreenFurniture);
329 RFs fs;
330 fs.Connect();
331 TFileName name;
332 fs.PrivatePath(name);
333 fs.Close();
334 name.Append( _L("sdlexe.rsc") );
335 name.Insert( 0, _L("C:") );
336 iResOffset = iCoeEnv->AddResourceFileL(name);
338 iSDLWin = new (ELeave) CSDLWin;
339 iSDLWin->ConstructL(ApplicationRect());
341 iSdl = CSDL::NewL(gSDLClass.SdlFlags());
343 gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl);
345 iSdl->DisableKeyBlocking(*this);
346 iSdl->SetContainerWindowL(
347 iSDLWin->GetWindow(),
348 iEikonEnv->WsSession(),
349 *iEikonEnv->ScreenDevice());
351 iStarter = CIdle::NewL(CActive::EPriorityLow);
352 iStarter->Start(TCallBack(StartL, this));
355 TBool CSDLAppUi::StartL(TAny* aThis)
357 static_cast<CSDLAppUi*>(aThis)->StartL();
358 return EFalse;
361 TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine)
363 const TPtrC8 cmdLine = aCommandLine.TailEnd();
364 iParams = new (ELeave) CDesC8ArrayFlat(8);
365 MakeCCmdLineL(cmdLine, *iParams);
366 return EFalse;
369 TBool CSDLAppUi::ParamEditorL(TDes& aCheat)
371 CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat);
372 CleanupStack::PushL(query);
373 query->SetPromptL(_L("Enter parameters"));
374 CleanupStack::Pop();
375 return query->ExecuteLD(R_PARAMEDITOR);
378 void CSDLAppUi::StartL()
380 if(gSDLClass.AppFlags() & SDLEnv::EParamQuery)
382 TBuf8<256> cmd;
383 RFile file;
384 int err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead);
385 if(err == KErrNone)
387 file.Read(cmd);
388 file.Close();
389 MakeCCmdLineL(cmd, *iParams);
391 if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery))
393 TBuf<256> buffer;
394 if(ParamEditorL(buffer))
396 cmd.Copy(buffer);
397 MakeCCmdLineL(cmd, *iParams);
401 iCoeEnv->DeleteResourceFile(iResOffset);
403 iWait = new (ELeave) CExitWait(*this);
404 iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000);
407 void CSDLAppUi::HandleCommandL(int aCommand)
409 switch(aCommand)
411 case EAknSoftkeyBack:
412 case EAknSoftkeyExit:
413 case EAknCmdExit:
414 case EEikCmdExit:
415 if(iWait == NULL || !iWait->IsActive() || iSdl == NULL)
417 Exit();
419 else
421 TWsEvent event;
422 event.SetType(EEventSwitchOff), event.SetTimeNow();
423 iSdl->AppendWsEvent(event);
425 break;
427 default:
428 break;
432 void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
434 if(aEvent.Type() == KAknUidValueEndKeyCloseEvent)
436 if(iWait != NULL && iWait->IsActive() && iSdl != NULL)
438 TWsEvent event;
439 event.SetType(EEventSwitchOff), event.SetTimeNow();
440 iSdl->AppendWsEvent(event);
441 return;
445 if(iSdl && iWait)
446 iSdl->AppendWsEvent(aEvent);
447 CAknAppUi::HandleWsEventL(aEvent, aDestination);
450 void CSDLAppUi::HandleResourceChangeL(int aType)
452 CAknAppUi::HandleResourceChangeL(aType);
453 if(aType == KEikDynamicLayoutVariantSwitch)
455 iSDLWin->SetRect(ApplicationRect());
456 iSdl->SetContainerWindowL(
457 iSDLWin->GetWindow(),
458 iEikonEnv->WsSession(),
459 *iEikonEnv->ScreenDevice());
463 void CSDLAppUi::HandleForegroundEventL(TBool aForeground)
465 CAknAppUi::HandleForegroundEventL(aForeground);
468 ////////////////////////////////////////////////////////////////////////
470 CApaApplication* NewApplication()
472 return new CSDLApplication();
475 EXPORT_C int SDLEnv::SetMain(const TMainFunc& aFunc, int aSdlFlags, MSDLMainObs* aObs, int aSdlExeFlags)
477 gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags);
478 return EikStart::RunApplication(NewApplication);