2 #include "SDL_events_c.h"
5 #include "sdlepocapi.h"
13 #include "SDL_epocevents_c.h"
14 #include "SDL_keysym.h"
16 #include "SDL_loadso.h"
17 #include <remconcoreapitargetobserver.h>
18 #include <remconinterfaceselector.h>
19 #include <remconcoreapitarget.h>
21 extern SDLKey
* KeyMap();
22 extern void ResetKeyMap();
34 CEventQueue
* iEventQueue
;
41 CArrayFix
<TSdlCleanupItem
>* iCleanupItems
;
43 TRequestStatus
* iCallerStatus
;
44 bool iWaitingForOrientationChange
;
50 EpocSdlEnvData
* gEpocEnv
;
55 static void RunSingleThread();
58 void EnvUtils::RunSingleThread()
60 int count
= RThread().RequestCount();
64 if(CActiveScheduler::RunIfReady(err
, CActive::EPriorityIdle
))
66 CActiveScheduler::Current()->WaitForAnyRequest();
71 int Panic(int aErr
, int aLine
)
74 b
.Format(_L("Main at %d"), aLine
);
80 bool CEventQueue::HasData()
82 EnvUtils::RunSingleThread();
83 return !m_queue
.empty();
86 const TWsEvent
CEventQueue::Shift()
88 const TWsEvent event
= m_queue
.front();
94 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation
, TAny
* aItem
) :
95 iOperation(aOperation
), iItem(aItem
), iThread(RThread().Id())
98 #define MAINFUNC(x) TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
107 TMainFunc::TMainFunc()
109 Mem::FillZ(iMainFunc
, sizeof(iMainFunc
));
113 const void* TMainFunc::operator[](int aIndex
) const
115 return iMainFunc
[aIndex
];
119 class CSdlAppServ
: public CActive
124 EAppSrvNoop
= CDsa::ELastDsaRequest
,
127 EAppSrvWindowDisplayMode
,
128 EAppSrvWindowPointerCursorMode
,
136 int Request(int aService
);
137 int RequestValue(int aService
);
139 void PanicMain(int aReason
);
140 void PanicMain(const TDesC
& aInfo
, int aReason
);
141 void SetParam(int aParam
);
146 const TThreadId iMainId
;
150 TRequestStatus
* iStatusPtr
;
153 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh
), iMainId(RThread().Id())
156 void CSdlAppServ::PanicMain(int aReason
)
158 iAppThread
.Panic(RThread().Name(), aReason
);
161 void CSdlAppServ::PanicMain(const TDesC
& aInfo
, int aReason
)
163 iAppThread
.Panic(aInfo
, aReason
);
166 void CSdlAppServ::ConstructL()
168 CActiveScheduler::Add(this);
169 iStatus
= KRequestPending
;
170 iStatusPtr
= &iStatus
;
174 CSdlAppServ::~CSdlAppServ()
180 int CSdlAppServ::Request(int aService
)
182 EnvUtils::RunSingleThread();
184 iAppThread
.RequestComplete(iStatusPtr
, KErrNone
);
188 int CSdlAppServ::RequestValue(int aService
)
191 Request(EAppSrvNoop
);
195 void CSdlAppServ::Init()
197 PANIC_IF_ERROR(iAppThread
.Open(iMainId
));
200 void CSdlAppServ::SetParam(int aParam
)
202 iReturnValue
= aParam
;
205 void CSdlAppServ::RunL()
207 if(iStatus
== KErrNone
)
211 case CSdlAppServ::EAppSrvWaitDsa
:
212 EpocSdlEnv::SetWaitDsa();
213 iReturnValue
= EpocSdlEnv::IsDsaAvailable();
216 case CSdlAppServ::EAppSrvStopThread
:
217 if(gEpocEnv
->iDsa
!= NULL
)
218 gEpocEnv
->iDsa
->SetSuspend();
221 case EAppSrvWindowPointerCursorMode
:
222 iReturnValue
= gEpocEnv
->iDsa
!= NULL
? gEpocEnv
->iDsa
->Session().PointerCursorMode() : KErrNotReady
;
225 case EAppSrvDsaStatus
:
226 if(gEpocEnv
->iDsa
!= NULL
)
227 gEpocEnv
->iDsa
->Stop();
228 iReturnValue
= KErrNone
;
235 PANIC(KErrNotSupported
);
239 iStatus
= KRequestPending
;
240 iStatusPtr
= &iStatus
;
245 void CSdlAppServ::DoCancel()
247 TRequestStatus
* s
= &iStatus
;
248 iAppThread
.RequestComplete(s
, KErrCancel
);
251 CEventQueue
& EpocSdlEnv::EventQueue()
253 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
254 return *gEpocEnv
->iEventQueue
;
257 int EpocSdlEnv::Argc()
259 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
260 return gEpocEnv
->iArgc
;
263 char** EpocSdlEnv::Argv()
265 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
266 return gEpocEnv
->iArgv
;
269 TBool
EpocSdlEnv::IsDsaAvailable()
271 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
272 return gEpocEnv
->iDsa
!= NULL
&& gEpocEnv
->iDsa
->IsDsaAvailable();
275 void EpocSdlEnv::WaitDsaAvailable()
277 gEpocEnv
->iAppSrv
->Request(CSdlAppServ::EAppSrvStopThread
);
280 void EpocSdlEnv::Suspend()
282 if(gEpocEnv
->iDsa
!= NULL
)
284 gEpocEnv
->iDsa
->SetSuspend();
288 void EpocSdlEnv::SetWaitDsa()
290 if(!IsDsaAvailable())
292 if(gEpocEnv
->iDsa
!= NULL
)
293 gEpocEnv
->iDsa
->SetSuspend();
297 void EpocSdlEnv::Resume()
299 if(gEpocEnv
->iDsa
!= NULL
)
301 gEpocEnv
->iDsa
->Resume();
305 int EpocSdlEnv::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
307 return gEpocEnv
->iDsa
->AllocSurface(aSize
, aMode
);
310 void EpocSdlEnv::UnlockHwSurface()
312 gEpocEnv
->iDsa
->UnlockHwSurface();
315 TUint8
* EpocSdlEnv::LockHwSurface()
317 return gEpocEnv
->iDsa
->LockHwSurface();
320 void EpocSdlEnv::UpdateSwSurface()
322 gEpocEnv
->iDsa
->UpdateSwSurface();
325 TBool
EpocSdlEnv::AddUpdateRect(TUint8
* aAddress
, const TRect
& aUpdateRect
, const TRect
& aRect
)
327 return gEpocEnv
->iDsa
->AddUpdateRect(aAddress
, aUpdateRect
, aRect
);
330 void EpocSdlEnv::Request(int aService
)
332 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
333 gEpocEnv
->iAppSrv
->Request(aService
);
336 TDisplayMode
EpocSdlEnv::DisplayMode()
338 return gEpocEnv
->iDsa
== NULL
? ENone
: gEpocEnv
->iDsa
->DisplayMode();
341 TPointerCursorMode
EpocSdlEnv::PointerMode()
343 return static_cast<TPointerCursorMode
>(gEpocEnv
->iAppSrv
->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode
));
346 int EpocSdlEnv::SetPalette(int aFirstcolor
, int aColorCount
, TUint32
* aPalette
)
348 return gEpocEnv
->iDsa
->SetPalette(aFirstcolor
, aColorCount
, aPalette
);
351 void EpocSdlEnv::PanicMain(int aErr
)
353 gEpocEnv
->iAppSrv
->PanicMain(aErr
);
357 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem
& aItem
)
359 TRAPD(err
, gEpocEnv
->iCleanupItems
->AppendL(aItem
));
363 void EpocSdlEnv::RemoveCleanupItem(TAny
* aItem
)
365 for(int i
= 0; i
< gEpocEnv
->iCleanupItems
->Count(); i
++)
367 if(gEpocEnv
->iCleanupItems
->At(i
).iItem
== aItem
)
368 gEpocEnv
->iCleanupItems
->Delete(i
);
372 void EpocSdlEnv::CleanupItems()
374 const TThreadId id
= RThread().Id();
375 int last
= gEpocEnv
->iCleanupItems
->Count() - 1;
378 for(i
= last
; i
>= 0 ; i
--)
380 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
381 if(item
.iThread
== id
)
383 item
.iThread
= TThreadId(0);
384 item
.iOperation(item
.iItem
);
388 last
= gEpocEnv
->iCleanupItems
->Count() - 1;
390 for(i
= last
; i
>= 0 ; i
--)
392 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
393 if(item
.iThread
== TThreadId(0))
395 gEpocEnv
->iCleanupItems
->Delete(i
);
400 void EpocSdlEnv::FreeSurface()
402 Request(CSdlAppServ::EAppSrvDsaStatus
);
403 if(gEpocEnv
->iDsa
!= NULL
)
404 gEpocEnv
->iDsa
->Free();
407 void EpocSdlEnv::PanicMain(const TDesC
& aInfo
, int aErr
)
409 gEpocEnv
->iAppSrv
->PanicMain(aInfo
, aErr
);
412 //Dsa is a low priority ao, it has to wait if its pending event, but ws
413 //event has been prioritized before it
414 //this is not called from app thread!
415 void EpocSdlEnv::WaitDeviceChange()
417 gEpocEnv
->iAppSrv
->RequestValue(CSdlAppServ::EAppSrvWaitDsa
);
420 static TBool
CheckSdl()
424 if(sdl
.Open(gEpocEnv
->iId
) == KErrNone
)
426 if(sdl
.ExitType() == EExitPending
)
435 void EpocSdlEnvData::Free()
437 if(RThread().Id() == gEpocEnv
->iId
)
444 __ASSERT_ALWAYS(iArgv
== NULL
|| CheckSdl(), PANIC(KErrNotReady
));
447 void EpocSdlEnvData::Delete()
449 for(int i
= 0; i
<= iArgc
; i
++)
469 _LIT(KSDLMain
, "SDLMain");
473 gEpocEnv
->iCleanupItems
= new CArrayFixFlat
<TSdlCleanupItem
>(8);
476 /* !! process exits here if there is "exit()" in main! */
478 for(int i
= 0; i
< 6; i
++)
480 void* f
= (void*) gEpocEnv
->iMain
[i
];
486 ret
= ((mainfunc1
)f
)();
494 ret
= ((mainfunc2
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
498 ((mainfunc2
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
502 ret
= ((mainfunc3
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp
);
506 ((mainfunc3
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp
);
515 static int DoMain(TAny
* /*aParam*/)
517 TBool fbsconnected
= EFalse
;
519 gEpocEnv
->iAppSrv
->Init();
524 TRAPD(err
, err
= MainL());
526 // Free resources and return
527 EpocSdlEnv::CleanupItems();
529 gEpocEnv
->iCleanupItems
->Reset();
530 delete gEpocEnv
->iCleanupItems
;
531 gEpocEnv
->iCleanupItems
= NULL
;
533 gEpocEnv
->Free(); //free up in thread resources
536 RFbsSession::Disconnect();
538 if(gEpocEnv
->iCallerStatus
!= NULL
)
540 User::RequestComplete(gEpocEnv
->iCallerStatus
, err
);
545 return err
== KErrNone
? ret
: err
;
560 __ASSERT_ALWAYS(gEpocEnv
== NULL
, PANIC(KErrAlreadyExists
));
561 gEpocEnv
= new EpocSdlEnvData
;
562 Mem::FillZ(gEpocEnv
, sizeof(EpocSdlEnvData
));
564 gEpocEnv
->iEventQueue
= new CEventQueue();
565 gEpocEnv
->iAppSrv
= new CSdlAppServ();
567 CSDL
* sdl
= new CSDL();
569 gEpocEnv
->iSdl
= sdl
;
574 void CSDL::SetContainerWindowL(RWindow
& aWindow
, RWsSession
& aSession
, CWsScreenDevice
& aDevice
)
576 if(gEpocEnv
->iDsa
== NULL
)
577 gEpocEnv
->iDsa
= CDsa::CreateL(aSession
);
578 gEpocEnv
->iDsa
->ConstructL(aWindow
, aDevice
);
581 int EpocSdlEnv::ApplyGlesDsa()
584 TRAPD(err
, dsa
= gEpocEnv
->iDsa
->CreateGlesDsaL());
585 gEpocEnv
->iDsa
= dsa
;
589 RWindow
* EpocSdlEnv::Window()
591 return gEpocEnv
->iDsa
->Window();
594 void EpocSdlEnv::UpdateWholeScreen(bool val
)
596 gEpocEnv
->iDsa
->m_updateWholeScreen
= val
;
599 bool EpocSdlEnv::GetUpdateWholeScreen()
601 return gEpocEnv
->iDsa
->m_updateWholeScreen
;
604 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation
, const TSize
& aSize
, TDisplayMode aMode
)
606 gEpocEnv
->iWaitingForOrientationChange
= true;
607 gEpocEnv
->iSize
= aSize
;
608 gEpocEnv
->iMode
= aMode
;
610 TRAPD(err
, static_cast<CAknAppUi
*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation
));
613 TThreadId
CSDL::CallMainL(const TMainFunc
& aFunc
, TRequestStatus
* const aStatus
, const CDesC8Array
* const aArg
)
615 ASSERT(gEpocEnv
!= NULL
);
616 gEpocEnv
->iMain
= aFunc
;
617 const TBool args
= aArg
!= NULL
;
619 if(gEpocEnv
->iArgv
!= NULL
)
620 User::Leave(KErrAlreadyExists
);
622 gEpocEnv
->iArgc
= args
? aArg
->Count() + 1 : 0;
623 gEpocEnv
->iArgv
= new char*[gEpocEnv
->iArgc
+ 2];
626 const TFileName processName
= RProcess().FileName();
627 const int len
= processName
.Length();
628 gEpocEnv
->iArgv
[k
] = new char[len
+ 1];
629 Mem::Copy(gEpocEnv
->iArgv
[k
], processName
.Ptr(), len
);
630 gEpocEnv
->iArgv
[k
][len
] = 0;
632 for(int i
= 0; args
&& (i
< aArg
->Count()); i
++)
635 const int len
= aArg
->MdcaPoint(i
).Length();
636 gEpocEnv
->iArgv
[k
] = new char[len
+ 1];
637 Mem::Copy(gEpocEnv
->iArgv
[k
], aArg
->MdcaPoint(i
).Ptr(), len
);
638 gEpocEnv
->iArgv
[k
][len
] = 0;
641 gEpocEnv
->iArgv
[k
+ 1] = NULL
;
643 gEpocEnv
->iAppSrv
->ConstructL();
645 // for handling volume up/down keys
646 CRemConInterfaceSelector
*iSelector
= CRemConInterfaceSelector::NewL();
647 CRemConCoreApiTarget::NewL( *iSelector
, *this );
648 iSelector
->OpenTargetL();
650 gEpocEnv
->iCallerStatus
= aStatus
;
652 *aStatus
= KRequestPending
;
653 gEpocEnv
->iId
= RThread().Id();
654 // when priority is not lowered screen updates much more frequently, which
655 // may be undesired, for example in case of openttd's generating world dialog
656 RThread().SetPriority(EPriorityLess
);
659 return gEpocEnv
->iId
;
662 void CSDL::AppendWsEvent(const TWsEvent
& aEvent
)
664 EpocSdlEnv::EventQueue().Append(aEvent
);
667 void CSDL::SDLPanic(const TDesC
& aInfo
, int aErr
)
669 EpocSdlEnv::PanicMain(aInfo
, aErr
);
672 int CSDL::GetSDLCode(int aScanCode
)
676 if(aScanCode
>= MAX_SCANCODE
)
678 return KeyMap()[aScanCode
];
681 int CSDL::SDLCodesCount() const
686 void CSDL::ResetSDLCodes()
691 int CSDL::SetSDLCode(int aScanCode
, int aSDLCode
)
693 const int current
= GetSDLCode(aScanCode
);
694 if(aScanCode
>= 0 && aScanCode
< MAX_SCANCODE
)
695 KeyMap()[aScanCode
] = static_cast<SDLKey
>(aSDLCode
);
701 EpocSdlEnv::Resume();
706 if(gEpocEnv
->iDsa
!= NULL
)
707 gEpocEnv
->iDsa
->DoStop();
712 if(gEpocEnv
->iWaitingForOrientationChange
)
714 EpocSdlEnv::AllocSurface(gEpocEnv
->iSize
, gEpocEnv
->iMode
);
715 gEpocEnv
->iWaitingForOrientationChange
= false;
719 TSize size
= gEpocEnv
->iDsa
->Window()->Size();
720 SDL_PrivateResize(size
.iWidth
, size
.iHeight
);
727 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId
, TRemConCoreApiButtonAction aButtonAct
)
729 if(aButtonAct
!= ERemConCoreApiButtonClick
)
733 event
.SetType(EEventKey
);
738 case ERemConCoreApiVolumeDown
:
739 event
.Key()->iScanCode
= EStdKeyDecVolume
;
740 event
.SetType(EEventKeyDown
);
741 AppendWsEvent(event
);
742 event
.SetType(EEventKeyUp
);
743 AppendWsEvent(event
);
746 case ERemConCoreApiVolumeUp
:
747 event
.Key()->iScanCode
= EStdKeyIncVolume
;
748 event
.SetType(EEventKeyDown
);
749 AppendWsEvent(event
);
750 event
.SetType(EEventKeyUp
);
751 AppendWsEvent(event
);
759 void* SDL_LoadObject(const char *sofile
)
761 RLibrary
* lib
= new RLibrary();
765 name
.Copy(TPtrC8((const TUint8
*)sofile
));
766 if(KErrNone
== lib
->Load(name
))
772 void* SDL_LoadFunction(void *handle
, const char *name
)
774 TLex8
v((const TUint8
*)(name
));
777 if(KErrNone
!= v
.Val(ord
))
780 const RLibrary
* lib
= reinterpret_cast<RLibrary
*>(handle
);
781 TLibraryFunction f
= lib
->Lookup(ord
);
785 void SDL_UnloadObject(void *handle
)
787 RLibrary
* lib
= reinterpret_cast<RLibrary
*>(handle
);