Big cleanup part 1.
[SDL.s60v3.git] / src / main / symbian / sdlexe.cpp
blob5eff270f11130648fb749adc8fccc149863981b7
1 // INCLUDES
2 #include <aknapp.h>
3 #include <aknappui.h>
4 #include <eikdoc.h>
5 #include <sdlepocapi.h>
6 #include <bautils.h>
7 #include <eikstart.h>
8 #include <badesca.h>
9 #include <bautils.h>
10 #include <apgcli.h>
11 #include <sdlmain.h>
12 #include <eikedwin.h>
13 #include <eiklabel.h>
14 #include <sdlexe.rsg>
15 #include <aknglobalmsgquery.h>
16 #include <apgwgnam.h>
21 // FORWARD DECLARATIONS
22 class CApaDocument;
25 //const TUid KSDLUID = { 0xF01F605E };
27 LOCAL_C void MakeCCmdLineL(const TDesC8& aParam, CDesC8Array& aArray)
30 const TChar dq('\"');
32 TLex8 lex(aParam);
33 TBool in = EFalse;
35 lex.SkipSpaceAndMark();
37 while(!lex.Eos())
39 TPtrC8 ptr;
40 if(in)
42 const TPtrC8 rem = lex.RemainderFromMark();
43 const TInt pos = rem.Locate(dq);
44 if(pos > 0)
46 lex.Inc(pos);
47 ptr.Set(lex.MarkedToken());
48 lex.SkipAndMark(1);
50 else
52 ptr.Set(rem);
54 in = EFalse;
56 else
58 ptr.Set(lex.NextToken());
59 const TInt pos = ptr.Locate(dq);
60 if(pos == 0)
62 lex.UnGetToMark();
63 lex.SkipAndMark(1);
64 in = ETrue;
65 continue; // back to in brace
67 else
68 lex.SkipSpaceAndMark();
71 aArray.AppendL(ptr);
76 NONSHARABLE_CLASS(TVirtualCursor) : public MOverlay
78 public:
79 TVirtualCursor();
80 void Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha);
81 void Move(TInt aX, TInt aY);
82 void MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const;
83 void Toggle();
84 TBool IsOn() const;
85 private:
86 void Draw(CBitmapContext& aGc, const TRect& aTargetRect, const TSize& aSize);
87 private:
88 TRect iRect;
89 TPoint iInc;
90 TPoint iPos;
91 TBool iIsOn;
92 CFbsBitmap* iCBmp;
93 CFbsBitmap* iAlpha;
97 TVirtualCursor::TVirtualCursor() : iInc(0, 0), iIsOn(EFalse), iCBmp(NULL)
101 const TInt KMaxMove = 10;
103 void TVirtualCursor::Move(TInt aX, TInt aY)
105 if(aX > 0 && iInc.iX > 0)
106 ++iInc.iX;
107 else if(aX < 0 && iInc.iX < 0)
108 --iInc.iX;
109 else
110 iInc.iX = aX;
112 if(aY > 0 && iInc.iY > 0)
113 ++iInc.iY;
114 else if(aY < 0 && iInc.iY < 0)
115 --iInc.iY;
116 else
117 iInc.iY = aY;
119 iInc.iX = Min(KMaxMove, iInc.iX);
121 iInc.iX = Max(-KMaxMove, iInc.iX);
123 iInc.iY = Min(KMaxMove, iInc.iY);
125 iInc.iY =Max(-KMaxMove, iInc.iY);
127 const TPoint pos = iPos + iInc;
128 if(iRect.Contains(pos))
130 iPos = pos;
132 else
134 iInc = TPoint(0, 0);
139 void TVirtualCursor::Toggle()
141 iIsOn = !iIsOn;
145 TBool TVirtualCursor::IsOn() const
147 return iIsOn;
150 void TVirtualCursor::Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha)
152 iRect = aRect;
153 iCBmp = aBmp;
154 iAlpha = aAlpha;
158 void TVirtualCursor::MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const
160 aEvent.SetType(EEventPointer),
161 aEvent.SetTimeNow();
162 TPointerEvent& pointer = *aEvent.Pointer();
163 pointer.iType = TPointerEvent::EButton1Down;
164 pointer.iPosition = iPos;
165 pointer.iParentPosition = aBasePos;
169 void TVirtualCursor::Draw(CBitmapContext& aGc, const TRect& /*aTargetRect*/, const TSize& /*aSize*/)
171 if(iIsOn && iCBmp != NULL)
173 const TRect rect(TPoint(0, 0), iCBmp->SizeInPixels());
174 aGc.AlphaBlendBitmaps(iPos, iCBmp, rect, iAlpha, TPoint(0, 0));
179 NONSHARABLE_CLASS(TSdlClass)
181 public:
182 TSdlClass();
183 void SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags);
184 TInt SdlFlags() const;
185 const TMainFunc& Main() const;
186 void SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL);
187 TInt AppFlags() const;
188 void AppFlags(TInt aFlags);
189 private:
190 TMainFunc iFunc;
191 TInt iSdlFlags;
192 TInt iExeFlags;
193 MSDLMainObs* iObs;
197 void TSdlClass::AppFlags(TInt aFlags)
199 iExeFlags |= aFlags;
202 void TSdlClass::SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL)
204 if(iObs != NULL)
205 iObs->SDLMainEvent(aEvent, aParam, aSDL);
208 TInt TSdlClass::AppFlags() const
210 return iExeFlags;
213 void TSdlClass::SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags)
215 iFunc = aFunc;
216 iSdlFlags = aFlags;
217 iExeFlags = aExeFlags;
218 iObs = aObs;
221 const TMainFunc& TSdlClass::Main() const
223 return iFunc;
227 TInt TSdlClass::SdlFlags() const
229 return iSdlFlags;
234 TSdlClass::TSdlClass()
236 Mem::FillZ(this, sizeof(this));
239 TSdlClass gSDLClass;
242 ////////////////////////////////////////////////////////////////
244 NONSHARABLE_CLASS(CSDLApplication) : public CAknApplication
246 public:
247 CSDLApplication();
248 private:
249 CApaDocument* CreateDocumentL();
250 TFileName ResourceFileName() const;
251 TUid AppDllUid() const;
252 void FindMeL();
253 TUid iUid;
256 NONSHARABLE_CLASS(CSDLDocument) : public CEikDocument
258 public:
259 CSDLDocument(CEikApplication& aApp);
260 private:
261 CEikAppUi* CreateAppUiL();
265 ////////////////////////////////////////////////////////////////////
268 NONSHARABLE_CLASS(MExitWait)
270 public:
271 virtual void DoExit(TInt aErr) = 0;
274 /////////////////////////////////////////////////////////////////////////
276 NONSHARABLE_CLASS(CExitWait) : public CActive
278 public:
279 CExitWait(MExitWait& aWait);
280 ~CExitWait();
281 private:
282 void RunL();
283 void DoCancel();
284 private:
285 MExitWait& iWait;
286 TRequestStatus* iStatusPtr;
289 ////////////////////////////////////////////////////////////////////////
292 NONSHARABLE_CLASS(CSDLWin) : public CCoeControl
294 public:
295 void ConstructL(const TRect& aRect);
296 RWindow& GetWindow() const;
297 void SetNoDraw();
298 private:
299 void Draw(const TRect& aRect) const;
300 private:
301 TBool iNoDraw;
305 ////////////////////////////////////////////////////////////////////////////
307 NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi, public MExitWait, public MSDLObserver
309 public:
310 ~CSDLAppUi();
311 private: // New functions
312 void ConstructL();
313 void HandleCommandL(TInt aCommand);
314 void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination);
315 void HandleResourceChangeL(TInt aType);
317 void DoExit(TInt aErr);
319 TInt SdlEvent(TInt aEvent, TInt aParam);
320 TInt SdlThreadEvent(TInt aEvent, TInt aParam);
322 void StartL();
323 static TBool StartL(TAny* aThis);
325 TBool ParamEditorL(TDes& aCheat);
327 TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine);
329 void PrepareToExit();
330 void HandleConsoleWindowL();
331 void HandleConsoleWindow();
332 void HandleForegroundEventL(TBool aForeground);
334 static TBool IdleRequestL(TAny* aThis);
336 TBool HandleKeyL(const TWsEvent& aEvent);
339 private:
340 CExitWait* iWait;
341 CSDLWin* iSDLWin;
342 CSDL* iSdl;
343 CIdle* iStarter;
344 TBool iExitRequest;
345 CDesC8Array* iParams;
346 TInt iResOffset;
347 CIdle* iIdle;
348 TInt iStdOut;
349 TVirtualCursor iCursor;
350 CFbsBitmap* iCBmp;
351 CFbsBitmap* iAlpha;
354 ////////////////////////////////////////////////////////////////////////////////////////7
356 CApaDocument* CSDLApplication::CreateDocumentL()
358 return new (ELeave) CSDLDocument(*this);
361 TUid CSDLApplication::AppDllUid() const
363 return iUid;
367 CSDLApplication::CSDLApplication()
369 TRAPD(err, FindMeL());
370 ASSERT(err == KErrNone);
373 void CSDLApplication::FindMeL()
375 RApaLsSession apa;
376 User::LeaveIfError(apa.Connect());
377 CleanupClosePushL(apa);
378 User::LeaveIfError(apa.GetAllApps());
379 TFileName name = RProcess().FileName();
380 TApaAppInfo info;
381 while(apa.GetNextApp(info) == KErrNone)
383 if(info.iFullName.CompareF(name) == 0)
385 iUid = info.iUid;
386 break;
389 CleanupStack::PopAndDestroy();
392 TFileName CSDLApplication::ResourceFileName() const
394 return KNullDesC();
397 ///////////////////////////////////////////////////////////////////////////////////////////
399 CExitWait::CExitWait(MExitWait& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait)
401 CActiveScheduler::Add(this);
402 SetActive();
403 iStatusPtr = &iStatus;
406 CExitWait::~CExitWait()
408 Cancel();
411 void CExitWait::RunL()
413 if(iStatusPtr != NULL )
414 iWait.DoExit(iStatus.Int());
417 void CExitWait::DoCancel()
419 if(iStatusPtr != NULL )
420 User::RequestComplete(iStatusPtr , KErrCancel);
424 //////////////////////////////////////////////////////////////////////////////////////////////
426 CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp)
429 CEikAppUi* CSDLDocument::CreateAppUiL()
431 return new (ELeave) CSDLAppUi;
434 ///////////////////////////////////////////////////////////////////////////
436 void CSDLWin:: ConstructL(const TRect& aRect)
438 CreateWindowL();
439 SetRect(aRect);
440 ActivateL();
444 RWindow& CSDLWin::GetWindow() const
446 return Window();
450 void CSDLWin::Draw(const TRect& /*aRect*/) const
452 if(!iNoDraw)
454 CWindowGc& gc = SystemGc();
455 gc.SetPenStyle(CGraphicsContext::ESolidPen);
456 gc.SetPenColor(KRgbGray);
457 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
458 gc.SetBrushColor(0x000000);
459 gc.DrawRect(Rect());
463 void CSDLWin::SetNoDraw()
465 iNoDraw = ETrue;
468 /////////////////////////////////////////////////////////////////////////
470 CSDLAppUi::~CSDLAppUi()
472 if(iIdle)
473 iIdle->Cancel();
474 delete iIdle;
475 if(iStarter != NULL)
476 iStarter->Cancel();
477 delete iStarter;
478 delete iWait;
479 delete iSdl;
480 delete iSDLWin;
481 delete iParams;
482 delete iCBmp;
483 delete iAlpha;
487 void CSDLAppUi::ConstructL()
489 BaseConstructL(ENoAppResourceFile | ENoScreenFurniture);
492 RLibrary lib;
493 User::LeaveIfError(lib.Load(_L("sdlexe.dll")));
494 TFileName name = lib.FileName();
495 lib.Close();
496 name.Replace(3, name.Length() - 3, _L("resource\\apps\\sdlexe.rsc"));
497 BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(), name);
498 iResOffset = iCoeEnv->AddResourceFileL(name);
500 name.Replace(name.Length() - 3, 3, _L("mbm"));
502 TEntry e;
503 const TInt err = iEikonEnv->FsSession().Entry(name, e);
505 iCBmp = iEikonEnv->CreateBitmapL(name, 0);
506 iAlpha = iEikonEnv->CreateBitmapL(name, 1);
508 iIdle = CIdle::NewL(CActive::EPriorityIdle);
510 iSDLWin = new (ELeave) CSDLWin;
511 iSDLWin->ConstructL(ApplicationRect());
513 iSdl = CSDL::NewL(gSDLClass.SdlFlags());
515 gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl);
517 iSdl->SetObserver(this);
518 iSdl->DisableKeyBlocking(*this);
519 iSdl->SetContainerWindowL(
520 iSDLWin->GetWindow(),
521 iEikonEnv->WsSession(),
522 *iEikonEnv->ScreenDevice());
523 iSdl->AppendOverlay(iCursor, 0);
525 iCursor.Set(TRect(TPoint(0, 0), iSDLWin->Size()), iCBmp, iAlpha);
527 iStarter = CIdle::NewL(CActive::EPriorityLow);
528 iStarter->Start(TCallBack(StartL, this));
535 TBool CSDLAppUi::StartL(TAny* aThis)
537 static_cast<CSDLAppUi*>(aThis)->StartL();
538 return EFalse;
542 void CSDLAppUi::PrepareToExit()
544 CAknAppUiBase::PrepareToExit(); //aknappu::PrepareToExit crashes
545 iCoeEnv->DeleteResourceFile(iResOffset);
548 TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine)
550 const TPtrC8 cmdLine = aCommandLine.TailEnd();
551 iParams = new (ELeave) CDesC8ArrayFlat(8);
552 MakeCCmdLineL(cmdLine, *iParams);
553 return EFalse;
557 TBool CSDLAppUi::ParamEditorL(TDes& aCheat)
559 CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat);
560 CleanupStack::PushL(query);
561 query->SetPromptL(_L("Enter parameters"));
562 CleanupStack::Pop();
563 return query->ExecuteLD(R_PARAMEDITOR);
566 void CSDLAppUi::StartL()
568 if(gSDLClass.AppFlags() & SDLEnv::EParamQuery)
570 TBuf8<256> cmd;
571 RFile file;
572 TInt err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead);
573 if(err == KErrNone)
575 file.Read(cmd);
576 file.Close();
577 MakeCCmdLineL(cmd, *iParams);
579 if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery))
581 TBuf<256> buffer;
582 if(ParamEditorL(buffer))
584 cmd.Copy(buffer);
585 MakeCCmdLineL(cmd, *iParams);
589 iWait = new (ELeave) CExitWait(*this);
590 iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000);
593 void CSDLAppUi::HandleCommandL(TInt aCommand)
595 switch(aCommand)
597 case EAknSoftkeyBack:
598 case EAknSoftkeyExit:
599 case EAknCmdExit:
600 case EEikCmdExit:
601 gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
602 if(iWait == NULL || !iWait->IsActive() || iSdl == NULL)
604 Exit();
606 else if(!iExitRequest)
608 TWsEvent event;
609 event.SetType(EEventSwitchOff),
610 event.SetTimeNow();
611 iSdl->AppendWsEvent(event);
612 User::After(1000000);
613 iExitRequest = ETrue; //trick how SDL can be closed!
614 iSdl->Suspend();
616 break;
622 TBool CSDLAppUi::HandleKeyL(const TWsEvent& aEvent)
624 const TInt type = aEvent.Type();
625 if(!(type == EEventKey || type == EEventKeyUp || type == EEventKeyDown))
627 return ETrue;
629 const TKeyEvent& key = *aEvent.Key();
630 if((key.iScanCode == EStdKeyYes) && (gSDLClass.AppFlags() & SDLEnv::EVirtualMouse))
632 if(type == EEventKeyUp)
634 iCursor.Toggle();
635 iSdl->RedrawRequest();
637 return EFalse;
639 if(iCursor.IsOn())
641 switch(key.iScanCode)
643 case EStdKeyUpArrow:
644 iCursor.Move(0, -1);
645 break;
646 case EStdKeyDownArrow:
647 iCursor.Move(0, 1);
648 break;
649 case EStdKeyLeftArrow:
650 iCursor.Move(-1, 0);
651 break;
652 case EStdKeyRightArrow:
653 iCursor.Move(1, 0);
654 break;
655 case EStdKeyDevice3:
656 if(type == EEventKeyUp)
658 TWsEvent event;
659 iCursor.MakeEvent(event, iSDLWin->Position());
660 iSdl->AppendWsEvent(event);
662 return EFalse;
663 default:
664 return ETrue;
666 iSdl->RedrawRequest();
667 return EFalse;
669 return ETrue;
672 void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
674 if(iSdl && iWait && HandleKeyL(aEvent))
675 iSdl->AppendWsEvent(aEvent);
676 CAknAppUi::HandleWsEventL(aEvent, aDestination);
679 void CSDLAppUi::HandleResourceChangeL(TInt aType)
681 CAknAppUi::HandleResourceChangeL(aType);
682 if(aType == KEikDynamicLayoutVariantSwitch)
684 iSDLWin->SetRect(ApplicationRect());
685 iSdl->SetContainerWindowL(
686 iSDLWin->GetWindow(),
687 iEikonEnv->WsSession(),
688 *iEikonEnv->ScreenDevice());
693 void CSDLAppUi::DoExit(TInt/*Err*/)
695 iExitRequest = ETrue;
696 Exit();
700 TInt CSDLAppUi::SdlThreadEvent(TInt aEvent, TInt /*aParam*/)
702 switch(aEvent)
704 case MSDLObserver::EEventResume:
705 break;
706 case MSDLObserver::EEventSuspend:
707 if(iExitRequest)
708 return MSDLObserver::ESuspendNoSuspend;
709 break;
710 case MSDLObserver::EEventWindowReserved:
711 break;
712 case MSDLObserver::EEventWindowNotAvailable:
713 break;
714 case MSDLObserver::EEventScreenSizeChanged:
715 break;
717 return MSDLObserver::EParameterNone;
720 TInt CSDLAppUi::SdlEvent(TInt aEvent, TInt /*aParam*/)
722 switch(aEvent)
724 case MSDLObserver::EEventResume:
725 break;
726 case MSDLObserver::EEventSuspend:
727 if(iExitRequest)
728 return MSDLObserver::ESuspendNoSuspend;
729 break;
730 case MSDLObserver::EEventWindowReserved:
731 break;
732 case MSDLObserver::EEventWindowNotAvailable:
734 TRAP_IGNORE(HandleConsoleWindowL());
736 break;
737 case MSDLObserver::EEventScreenSizeChanged:
738 break;
739 case MSDLObserver::EEventKeyMapInit:
740 break;
741 case MSDLObserver::EEventMainExit:
742 if(iStdOut != 0)
744 gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
745 iEikonEnv->WsSession().SetWindowGroupOrdinalPosition(iStdOut, 0);
747 break;
749 return MSDLObserver::EParameterNone;
752 void CSDLAppUi::HandleForegroundEventL(TBool aForeground)
754 CAknAppUi::HandleForegroundEventL(aForeground);
755 if(!aForeground)
756 HandleConsoleWindow();
759 void CSDLAppUi::HandleConsoleWindow()
761 if(!iIdle->IsActive())
762 iIdle->Start(TCallBack(IdleRequestL, this));
765 TBool CSDLAppUi::IdleRequestL(TAny* aThis)
767 static_cast<CSDLAppUi*>(aThis)->HandleConsoleWindowL();
768 return EFalse;
771 void CSDLAppUi::HandleConsoleWindowL()
773 if(gSDLClass.AppFlags() & SDLEnv::EAllowConsoleView)
775 return;
777 RWsSession& ses = iEikonEnv->WsSession();
778 const TInt focus = ses.GetFocusWindowGroup();
779 CApaWindowGroupName* name = CApaWindowGroupName::NewLC(ses, focus);
780 const TPtrC caption = name->Caption();
781 if(0 == caption.CompareF(_L("STDOUT")))
783 iStdOut = focus;
784 ses.SetWindowGroupOrdinalPosition(iEikonEnv->RootWin().Identifier(), 0);
786 CleanupStack::PopAndDestroy(); //name
792 ////////////////////////////////////////////////////////////////////////
795 CApaApplication* NewApplication()
797 return new CSDLApplication();
801 EXPORT_C TInt SDLEnv::SetMain(const TMainFunc& aFunc, TInt aSdlFlags, MSDLMainObs* aObs, TInt aSdlExeFlags)
803 gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags);
804 return EikStart::RunApplication(NewApplication);
807 //////////////////////////////////////////////////////////////////////
809 TInt SDLUiPrint(const TDesC8& /*aInfo*/)
811 return KErrNotFound;