implement input to avoid PD common dependency
[sdl_omap.git] / src / main / symbian / EKA2 / sdlexe.cpp
CommitLineData
e14743d1 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>
17
18
19
20// FORWARD DECLARATIONS
21class CApaDocument;
22
23
24//const TUid KSDLUID = { 0xF01F605E };
25
26LOCAL_C void MakeCCmdLineL(const TDesC8& aParam, CDesC8Array& aArray)
27 {
28
29 const TChar dq('\"');
30
31 TLex8 lex(aParam);
32 TBool in = EFalse;
33
34 lex.SkipSpaceAndMark();
35
36 while(!lex.Eos())
37 {
38 TPtrC8 ptr;
39 if(in)
40 {
41 const TPtrC8 rem = lex.RemainderFromMark();
42 const TInt pos = rem.Locate(dq);
43 if(pos > 0)
44 {
45 lex.Inc(pos);
46 ptr.Set(lex.MarkedToken());
47 lex.SkipAndMark(1);
48 }
49 else
50 {
51 ptr.Set(rem);
52 }
53 in = EFalse;
54 }
55 else
56 {
57 ptr.Set(lex.NextToken());
58 const TInt pos = ptr.Locate(dq);
59 if(pos == 0)
60 {
61 lex.UnGetToMark();
62 lex.SkipAndMark(1);
63 in = ETrue;
64 continue; // back to in brace
65 }
66 else
67 lex.SkipSpaceAndMark();
68 }
69
70 aArray.AppendL(ptr);
71
72 }
73 }
74
75NONSHARABLE_CLASS(TVirtualCursor) : public MOverlay
76 {
77 public:
78 TVirtualCursor();
79 void Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha);
80 void Move(TInt aX, TInt aY);
81 void MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const;
82 void Toggle();
83 TBool IsOn() const;
84 private:
85 void Draw(CBitmapContext& aGc, const TRect& aTargetRect, const TSize& aSize);
86 private:
87 TRect iRect;
88 TPoint iInc;
89 TPoint iPos;
90 TBool iIsOn;
91 CFbsBitmap* iCBmp;
92 CFbsBitmap* iAlpha;
93 };
94
95
96TVirtualCursor::TVirtualCursor() : iInc(0, 0), iIsOn(EFalse), iCBmp(NULL)
97 {
98 }
99
100const TInt KMaxMove = 10;
101
102void TVirtualCursor::Move(TInt aX, TInt aY)
103 {
104 if(aX > 0 && iInc.iX > 0)
105 ++iInc.iX;
106 else if(aX < 0 && iInc.iX < 0)
107 --iInc.iX;
108 else
109 iInc.iX = aX;
110
111 if(aY > 0 && iInc.iY > 0)
112 ++iInc.iY;
113 else if(aY < 0 && iInc.iY < 0)
114 --iInc.iY;
115 else
116 iInc.iY = aY;
117
118 iInc.iX = Min(KMaxMove, iInc.iX);
119
120 iInc.iX = Max(-KMaxMove, iInc.iX);
121
122 iInc.iY = Min(KMaxMove, iInc.iY);
123
124 iInc.iY =Max(-KMaxMove, iInc.iY);
125
126 const TPoint pos = iPos + iInc;
127 if(iRect.Contains(pos))
128 {
129 iPos = pos;
130 }
131 else
132 {
133 iInc = TPoint(0, 0);
134 }
135 }
136
137
138void TVirtualCursor::Toggle()
139 {
140 iIsOn = !iIsOn;
141 }
142
143
144TBool TVirtualCursor::IsOn() const
145 {
146 return iIsOn;
147 }
148
149void TVirtualCursor::Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha)
150 {
151 iRect = aRect;
152 iCBmp = aBmp;
153 iAlpha = aAlpha;
154 }
155
156
157void TVirtualCursor::MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const
158 {
159 aEvent.SetType(EEventPointer),
160 aEvent.SetTimeNow();
161 TPointerEvent& pointer = *aEvent.Pointer();
162 pointer.iType = TPointerEvent::EButton1Down;
163 pointer.iPosition = iPos;
164 pointer.iParentPosition = aBasePos;
165 }
166
167
168void TVirtualCursor::Draw(CBitmapContext& aGc, const TRect& /*aTargetRect*/, const TSize& /*aSize*/)
169 {
170 if(iIsOn && iCBmp != NULL)
171 {
172 const TRect rect(TPoint(0, 0), iCBmp->SizeInPixels());
173 aGc.AlphaBlendBitmaps(iPos, iCBmp, rect, iAlpha, TPoint(0, 0));
174 }
175
176 }
177
178NONSHARABLE_CLASS(TSdlClass)
179 {
180 public:
181 TSdlClass();
182 void SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags);
183 TInt SdlFlags() const;
184 const TMainFunc& Main() const;
185 void SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL);
186 TInt AppFlags() const;
187 void AppFlags(TInt aFlags);
188 private:
189 TMainFunc iFunc;
190 TInt iSdlFlags;
191 TInt iExeFlags;
192 MSDLMainObs* iObs;
193 };
194
195
196void TSdlClass::AppFlags(TInt aFlags)
197 {
198 iExeFlags |= aFlags;
199 }
200
201void TSdlClass::SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL)
202 {
203 if(iObs != NULL)
204 iObs->SDLMainEvent(aEvent, aParam, aSDL);
205 }
206
207TInt TSdlClass::AppFlags() const
208 {
209 return iExeFlags;
210 }
211
212void TSdlClass::SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags)
213 {
214 iFunc = aFunc;
215 iSdlFlags = aFlags;
216 iExeFlags = aExeFlags;
217 iObs = aObs;
218 }
219
220const TMainFunc& TSdlClass::Main() const
221 {
222 return iFunc;
223 }
224
225
226 TInt TSdlClass::SdlFlags() const
227 {
228 return iSdlFlags;
229 }
230
231
232
233TSdlClass::TSdlClass()
234 {
235 Mem::FillZ(this, sizeof(this));
236 }
237
238TSdlClass gSDLClass;
239
240
241////////////////////////////////////////////////////////////////
242
243NONSHARABLE_CLASS(CSDLApplication) : public CAknApplication
244 {
245 public:
246 CSDLApplication();
247 private:
248 CApaDocument* CreateDocumentL();
249 TFileName ResourceFileName() const;
250 TUid AppDllUid() const;
251 void FindMeL();
252 TUid iUid;
253 };
254
255NONSHARABLE_CLASS(CSDLDocument) : public CEikDocument
256 {
257 public:
258 CSDLDocument(CEikApplication& aApp);
259 private:
260 CEikAppUi* CreateAppUiL();
261
262 };
263
264 ////////////////////////////////////////////////////////////////////
265
266
267NONSHARABLE_CLASS(MExitWait)
268 {
269 public:
270 virtual void DoExit(TInt aErr) = 0;
271 };
272
273/////////////////////////////////////////////////////////////////////////
274
275NONSHARABLE_CLASS(CExitWait) : public CActive
276 {
277 public:
278 CExitWait(MExitWait& aWait);
279 ~CExitWait();
280 private:
281 void RunL();
282 void DoCancel();
283 private:
284 MExitWait& iWait;
285 TRequestStatus* iStatusPtr;
286 };
287
288////////////////////////////////////////////////////////////////////////
289
290
291NONSHARABLE_CLASS(CSDLWin) : public CCoeControl
292 {
293 public:
294 void ConstructL(const TRect& aRect);
295 RWindow& GetWindow() const;
296 void SetNoDraw();
297 private:
298 void Draw(const TRect& aRect) const;
299 private:
300 TBool iNoDraw;
301 };
302
303
304////////////////////////////////////////////////////////////////////////////
305
306NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi, public MExitWait, MSDLObserver
307 {
308 public:
309 ~CSDLAppUi();
310 private: // New functions
311 void ConstructL();
312 void HandleCommandL(TInt aCommand);
313 void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination);
314 void HandleResourceChangeL(TInt aType);
315
316 void DoExit(TInt aErr);
317
318 TInt SdlEvent(TInt aEvent, TInt aParam);
319 TInt SdlThreadEvent(TInt aEvent, TInt aParam);
320
321 void StartL();
322 static TBool StartL(TAny* aThis);
323
324 TBool ParamEditorL(TDes& aCheat);
325
326 TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine);
327
328 void PrepareToExit();
329 void HandleConsoleWindowL();
330 void HandleConsoleWindow();
331 void HandleForegroundEventL(TBool aForeground);
332
333 static TBool IdleRequestL(TAny* aThis);
334
335 TBool HandleKeyL(const TWsEvent& aEvent);
336
337
338 private:
339 CExitWait* iWait;
340 CSDLWin* iSDLWin;
341 CSDL* iSdl;
342 CIdle* iStarter;
343 TBool iExitRequest;
344 CDesC8Array* iParams;
345 TInt iResOffset;
346 CIdle* iIdle;
347 TInt iStdOut;
348 TVirtualCursor iCursor;
349 CFbsBitmap* iCBmp;
350 CFbsBitmap* iAlpha;
351 // TTime iLastPress;
352 // CSDL::TOrientationMode iOrientation;
353 };
354
355////////////////////////////////////////////////////////////////////////////////////////7
356
357CApaDocument* CSDLApplication::CreateDocumentL()
358 {
359 return new (ELeave) CSDLDocument(*this);
360 }
361
362TUid CSDLApplication::AppDllUid() const
363 {
364 return iUid;
365 }
366
367
368CSDLApplication::CSDLApplication()
369 {
370 TRAPD(err, FindMeL());
371 ASSERT(err == KErrNone);
372 }
373
374void CSDLApplication::FindMeL()
375 {
376 RApaLsSession apa;
377 User::LeaveIfError(apa.Connect());
378 CleanupClosePushL(apa);
379 User::LeaveIfError(apa.GetAllApps());
380 TFileName name = RProcess().FileName();
381 TApaAppInfo info;
382 while(apa.GetNextApp(info) == KErrNone)
383 {
384 if(info.iFullName.CompareF(name) == 0)
385 {
386 iUid = info.iUid;
387 break;
388 }
389 }
390 CleanupStack::PopAndDestroy();
391 }
392
393TFileName CSDLApplication::ResourceFileName() const
394 {
395 return KNullDesC();
396 }
397
398///////////////////////////////////////////////////////////////////////////////////////////
399
400CExitWait::CExitWait(MExitWait& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait)
401 {
402 CActiveScheduler::Add(this);
403 SetActive();
404 iStatusPtr = &iStatus;
405 }
406
407CExitWait::~CExitWait()
408 {
409 Cancel();
410 }
411
412void CExitWait::RunL()
413 {
414 if(iStatusPtr != NULL )
415 iWait.DoExit(iStatus.Int());
416 }
417
418void CExitWait::DoCancel()
419 {
420 if(iStatusPtr != NULL )
421 User::RequestComplete(iStatusPtr , KErrCancel);
422 }
423
424
425//////////////////////////////////////////////////////////////////////////////////////////////
426
427CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp)
428 {}
429
430CEikAppUi* CSDLDocument::CreateAppUiL()
431 {
432 return new (ELeave) CSDLAppUi;
433 }
434
435///////////////////////////////////////////////////////////////////////////
436
437void CSDLWin:: ConstructL(const TRect& aRect)
438 {
439 CreateWindowL();
440 SetRect(aRect);
441 ActivateL();
442 }
443
444
445RWindow& CSDLWin::GetWindow() const
446 {
447 return Window();
448 }
449
450
451void CSDLWin::Draw(const TRect& /*aRect*/) const
452 {
453 if(!iNoDraw)
454 {
455 CWindowGc& gc = SystemGc();
456 gc.SetPenStyle(CGraphicsContext::ESolidPen);
457 gc.SetPenColor(KRgbGray);
458 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
459 gc.SetBrushColor(0xaaaaaa);
460 gc.DrawRect(Rect());
461 }
462 }
463
464void CSDLWin::SetNoDraw()
465 {
466 iNoDraw = ETrue;
467 }
468
469/////////////////////////////////////////////////////////////////////////
470
471CSDLAppUi::~CSDLAppUi()
472 {
473 if(iIdle)
474 iIdle->Cancel();
475 delete iIdle;
476 if(iStarter != NULL)
477 iStarter->Cancel();
478 delete iStarter;
479 delete iWait;
480 delete iSdl;
481 delete iSDLWin;
482 delete iParams;
483 delete iCBmp;
484 delete iAlpha;
485 }
486
487
488void CSDLAppUi::ConstructL()
489 {
490 BaseConstructL(ENoAppResourceFile | ENoScreenFurniture);
491
492
493 RLibrary lib;
494 User::LeaveIfError(lib.Load(_L("sdlexe.dll")));
495 TFileName name = lib.FileName();
496 lib.Close();
497 name.Replace(3, name.Length() - 3, _L("resource\\apps\\sdlexe.rsc"));
498 BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(), name);
499 iResOffset = iCoeEnv->AddResourceFileL(name);
500
501 name.Replace(name.Length() - 3, 3, _L("mbm"));
502
503 TEntry e;
504 const TInt err = iEikonEnv->FsSession().Entry(name, e);
505
506 iCBmp = iEikonEnv->CreateBitmapL(name, 0);
507 iAlpha = iEikonEnv->CreateBitmapL(name, 1);
508
509 iIdle = CIdle::NewL(CActive::EPriorityIdle);
510
511 iSDLWin = new (ELeave) CSDLWin;
512 iSDLWin->ConstructL(ApplicationRect());
513
514 iSdl = CSDL::NewL(gSDLClass.SdlFlags());
515
516 gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl);
517
518 iSdl->SetObserver(this);
519 iSdl->DisableKeyBlocking(*this);
520 iSdl->SetContainerWindowL(
521 iSDLWin->GetWindow(),
522 iEikonEnv->WsSession(),
523 *iEikonEnv->ScreenDevice());
524 iSdl->AppendOverlay(iCursor, 0);
525
526 iCursor.Set(TRect(TPoint(0, 0), iSDLWin->Size()), iCBmp, iAlpha);
527
528 iStarter = CIdle::NewL(CActive::EPriorityLow);
529 iStarter->Start(TCallBack(StartL, this));
530
531
532 }
533
534
535
536TBool CSDLAppUi::StartL(TAny* aThis)
537 {
538 static_cast<CSDLAppUi*>(aThis)->StartL();
539 return EFalse;
540 }
541
542
543void CSDLAppUi::PrepareToExit()
544 {
545 CAknAppUiBase::PrepareToExit(); //aknappu::PrepareToExit crashes
546 iCoeEnv->DeleteResourceFile(iResOffset);
547 }
548
549TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine)
550 {
551 const TPtrC8 cmdLine = aCommandLine.TailEnd();
552 iParams = new (ELeave) CDesC8ArrayFlat(8);
553 MakeCCmdLineL(cmdLine, *iParams);
554 return EFalse;
555 }
556
557
558 TBool CSDLAppUi::ParamEditorL(TDes& aCheat)
559 {
560 CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat);
561 CleanupStack::PushL(query);
562 query->SetPromptL(_L("Enter parameters"));
563 CleanupStack::Pop();
564 return query->ExecuteLD(R_PARAMEDITOR);
565 }
566
567 void CSDLAppUi::StartL()
568 {
569 if(gSDLClass.AppFlags() & SDLEnv::EParamQuery)
570 {
571 TBuf8<256> cmd;
572 RFile file;
573 TInt err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead);
574 if(err == KErrNone)
575 {
576 file.Read(cmd);
577 file.Close();
578 MakeCCmdLineL(cmd, *iParams);
579 }
580 if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery))
581 {
582 TBuf<256> buffer;
583 if(ParamEditorL(buffer))
584 {
585 cmd.Copy(buffer);
586 MakeCCmdLineL(cmd, *iParams);
587 }
588 }
589 }
590 iWait = new (ELeave) CExitWait(*this);
591 iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000);
592 }
593
594void CSDLAppUi::HandleCommandL(TInt aCommand)
595 {
596 switch(aCommand)
597 {
598 case EAknSoftkeyBack:
599 case EAknSoftkeyExit:
600 case EAknCmdExit:
601 case EEikCmdExit:
602 gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
603 if(iWait == NULL || !iWait->IsActive() || iSdl == NULL)
604 {
605 Exit();
606 }
607 else if(!iExitRequest)
608 {
609 iExitRequest = ETrue; //trick how SDL can be closed!
610 iSdl->Suspend();
611 }
612 break;
613 }
614 }
615
616
617
618TBool CSDLAppUi::HandleKeyL(const TWsEvent& aEvent)
619 {
620 const TInt type = aEvent.Type();
621 if(!(type == EEventKey || type == EEventKeyUp || type == EEventKeyDown))
622 {
623 return ETrue;
624 }
625 const TKeyEvent& key = *aEvent.Key();
626 if((key.iScanCode == EStdKeyYes) && (gSDLClass.AppFlags() & SDLEnv::EVirtualMouse))
627 {
628 if(type == EEventKeyUp)
629 {
630 iCursor.Toggle();
631 iSdl->RedrawRequest();
632 }
633 return EFalse;
634 }
635 if(iCursor.IsOn())
636 {
637 switch(key.iScanCode)
638 {
639 case EStdKeyUpArrow:
640 iCursor.Move(0, -1);
641 break;
642 case EStdKeyDownArrow:
643 iCursor.Move(0, 1);
644 break;
645 case EStdKeyLeftArrow:
646 iCursor.Move(-1, 0);
647 break;
648 case EStdKeyRightArrow:
649 iCursor.Move(1, 0);
650 break;
651 case EStdKeyDevice3:
652 if(type == EEventKeyUp)
653 {
654 TWsEvent event;
655 iCursor.MakeEvent(event, iSDLWin->Position());
656 iSdl->AppendWsEvent(event);
657 }
658 return EFalse;
659 default:
660 return ETrue;
661 }
662 iSdl->RedrawRequest();
663 return EFalse;
664 }
665 return ETrue;
666 }
667
668 void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
669 {
670 if(iSdl && iWait && HandleKeyL(aEvent))
671 iSdl->AppendWsEvent(aEvent);
672 CAknAppUi::HandleWsEventL(aEvent, aDestination);
673 }
674
675 void CSDLAppUi::HandleResourceChangeL(TInt aType)
676 {
677 CAknAppUi::HandleResourceChangeL(aType);
678 if(aType == KEikDynamicLayoutVariantSwitch)
679 {
680 iSDLWin->SetRect(ApplicationRect());
681 iSdl->SetContainerWindowL(
682 iSDLWin->GetWindow(),
683 iEikonEnv->WsSession(),
684 *iEikonEnv->ScreenDevice());
685 }
686 }
687
688
689void CSDLAppUi::DoExit(TInt/*Err*/)
690 {
691 iExitRequest = ETrue;
692 Exit();
693 }
694
695
696 TInt CSDLAppUi::SdlThreadEvent(TInt aEvent, TInt /*aParam*/)
697 {
698 switch(aEvent)
699 {
700 case MSDLObserver::EEventResume:
701 break;
702 case MSDLObserver::EEventSuspend:
703 if(iExitRequest)
704 return MSDLObserver::ESuspendNoSuspend;
705 break;
706 case MSDLObserver::EEventWindowReserved:
707 break;
708 case MSDLObserver::EEventWindowNotAvailable:
709 break;
710 case MSDLObserver::EEventScreenSizeChanged:
711 break;
712 }
713 return MSDLObserver::EParameterNone;
714 }
715
716TInt CSDLAppUi::SdlEvent(TInt aEvent, TInt /*aParam*/)
717 {
718 switch(aEvent)
719 {
720 case MSDLObserver::EEventResume:
721 break;
722 case MSDLObserver::EEventSuspend:
723 if(iExitRequest)
724 return MSDLObserver::ESuspendNoSuspend;
725 break;
726 case MSDLObserver::EEventWindowReserved:
727 break;
728 case MSDLObserver::EEventWindowNotAvailable:
729 {
730 TRAP_IGNORE(HandleConsoleWindowL());
731 }
732 break;
733 case MSDLObserver::EEventScreenSizeChanged:
734 break;
735 case MSDLObserver::EEventKeyMapInit:
736 break;
737 case MSDLObserver::EEventMainExit:
738 if(iStdOut != 0)
739 {
740 gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
741 iEikonEnv->WsSession().SetWindowGroupOrdinalPosition(iStdOut, 0);
742 }
743 break;
744 }
745 return MSDLObserver::EParameterNone;
746 }
747
748void CSDLAppUi::HandleForegroundEventL(TBool aForeground)
749 {
750 CAknAppUi::HandleForegroundEventL(aForeground);
751 if(!aForeground)
752 HandleConsoleWindow();
753 }
754
755void CSDLAppUi::HandleConsoleWindow()
756 {
757 if(!iIdle->IsActive())
758 iIdle->Start(TCallBack(IdleRequestL, this));
759 }
760
761TBool CSDLAppUi::IdleRequestL(TAny* aThis)
762 {
763 static_cast<CSDLAppUi*>(aThis)->HandleConsoleWindowL();
764 return EFalse;
765 }
766
767void CSDLAppUi::HandleConsoleWindowL()
768 {
769 if(gSDLClass.AppFlags() & SDLEnv::EAllowConsoleView)
770 {
771 return;
772 }
773 RWsSession& ses = iEikonEnv->WsSession();
774 const TInt focus = ses.GetFocusWindowGroup();
775 CApaWindowGroupName* name = CApaWindowGroupName::NewLC(ses, focus);
776 const TPtrC caption = name->Caption();
777 if(0 == caption.CompareF(_L("STDOUT")))
778 {
779 iStdOut = focus;
780 ses.SetWindowGroupOrdinalPosition(iEikonEnv->RootWin().Identifier(), 0);
781 }
782 CleanupStack::PopAndDestroy(); //name
783 }
784
785
786////////////////////////////////////////////////////////////////////////
787
788
789CApaApplication* NewApplication()
790 {
791 return new CSDLApplication();
792 }
793
794
795EXPORT_C TInt SDLEnv::SetMain(const TMainFunc& aFunc, TInt aSdlFlags, MSDLMainObs* aObs, TInt aSdlExeFlags)
796 {
797 gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags);
798 return EikStart::RunApplication(NewApplication);
799 }
800
801//////////////////////////////////////////////////////////////////////
802
803TInt SDLUiPrint(const TDesC8& /*aInfo*/)
804 {
805 return KErrNotFound;
806 }
807
808
809