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>
31 CEventQueue
* iEventQueue
;
34 CArrayFix
<TSdlCleanupItem
>* iCleanupItems
;
36 bool iWaitingForOrientationChange
;
42 EpocSdlEnvData
* gEpocEnv
;
44 static void RunSingleThread()
46 if(RThread().RequestCount() > 0)
49 if(CActiveScheduler::RunIfReady(err
, CActive::EPriorityIdle
))
51 CActiveScheduler::Current()->WaitForAnyRequest();
56 int Panic(int aErr
, int aLine
)
59 b
.Format(_L("Main at %d"), aLine
);
65 bool CEventQueue::HasData()
68 return !m_queue
.empty();
71 const TWsEvent
CEventQueue::Shift()
73 const TWsEvent event
= m_queue
.front();
79 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation
, void* aItem
) :
80 iOperation(aOperation
), iItem(aItem
), iThread(RThread().Id())
83 #define MAINFUNC(x) TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
92 TMainFunc::TMainFunc()
94 Mem::FillZ(iMainFunc
, sizeof(iMainFunc
));
97 const void* TMainFunc::operator[](int aIndex
) const
99 return iMainFunc
[aIndex
];
102 class CSdlAppServ
: public CActive
112 int Request(int aService
);
114 void SetParam(int aParam
);
119 const TThreadId iMainId
;
123 TRequestStatus
* iStatusPtr
;
126 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh
), iMainId(RThread().Id())
129 void CSdlAppServ::ConstructL()
131 CActiveScheduler::Add(this);
132 iStatus
= KRequestPending
;
133 iStatusPtr
= &iStatus
;
137 CSdlAppServ::~CSdlAppServ()
143 int CSdlAppServ::Request(int aService
)
147 iAppThread
.RequestComplete(iStatusPtr
, KErrNone
);
151 void CSdlAppServ::Init()
153 PANIC_IF_ERROR(iAppThread
.Open(iMainId
));
156 void CSdlAppServ::SetParam(int aParam
)
158 iReturnValue
= aParam
;
161 void CSdlAppServ::RunL()
163 if(iStatus
== KErrNone
)
167 case EAppSrvDsaStatus
:
168 if(gEpocEnv
->iDsa
!= NULL
)
169 gEpocEnv
->iDsa
->Stop();
170 iReturnValue
= KErrNone
;
174 PANIC(KErrNotSupported
);
178 iStatus
= KRequestPending
;
179 iStatusPtr
= &iStatus
;
184 void CSdlAppServ::DoCancel()
186 TRequestStatus
* s
= &iStatus
;
187 iAppThread
.RequestComplete(s
, KErrCancel
);
190 CEventQueue
& EpocSdlEnv::EventQueue()
192 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
193 return *gEpocEnv
->iEventQueue
;
196 TBool
EpocSdlEnv::IsDsaAvailable()
198 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
199 return gEpocEnv
->iDsa
!= NULL
&& gEpocEnv
->iDsa
->IsDsaAvailable();
202 int EpocSdlEnv::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
204 return gEpocEnv
->iDsa
->AllocSurface(aSize
, aMode
);
207 void EpocSdlEnv::UnlockHwSurface()
209 gEpocEnv
->iDsa
->UnlockHwSurface();
212 TUint8
* EpocSdlEnv::LockHwSurface()
214 return gEpocEnv
->iDsa
->LockHwSurface();
217 void EpocSdlEnv::UpdateSwSurface()
219 gEpocEnv
->iDsa
->UpdateSwSurface();
222 TBool
EpocSdlEnv::AddUpdateRect(TUint8
* aAddress
, const TRect
& aUpdateRect
, const TRect
& aRect
)
224 return gEpocEnv
->iDsa
->AddUpdateRect(aAddress
, aUpdateRect
, aRect
);
227 void EpocSdlEnv::Request(int aService
)
229 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
230 gEpocEnv
->iAppSrv
->Request(aService
);
233 TDisplayMode
EpocSdlEnv::DisplayMode()
235 return gEpocEnv
->iDsa
== NULL
? ENone
: gEpocEnv
->iDsa
->DisplayMode();
238 int EpocSdlEnv::SetPalette(int aFirstcolor
, int aColorCount
, TUint32
* aPalette
)
240 return gEpocEnv
->iDsa
->SetPalette(aFirstcolor
, aColorCount
, aPalette
);
243 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem
& aItem
)
245 TRAPD(err
, gEpocEnv
->iCleanupItems
->AppendL(aItem
));
249 void EpocSdlEnv::RemoveCleanupItem(void* aItem
)
251 for(int i
= 0; i
< gEpocEnv
->iCleanupItems
->Count(); i
++)
253 if(gEpocEnv
->iCleanupItems
->At(i
).iItem
== aItem
)
254 gEpocEnv
->iCleanupItems
->Delete(i
);
258 void EpocSdlEnv::CleanupItems()
260 const TThreadId id
= RThread().Id();
261 int last
= gEpocEnv
->iCleanupItems
->Count() - 1;
264 for(i
= last
; i
>= 0 ; i
--)
266 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
267 if(item
.iThread
== id
)
269 item
.iThread
= TThreadId(0);
270 item
.iOperation(item
.iItem
);
274 last
= gEpocEnv
->iCleanupItems
->Count() - 1;
276 for(i
= last
; i
>= 0 ; i
--)
278 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
279 if(item
.iThread
== TThreadId(0))
281 gEpocEnv
->iCleanupItems
->Delete(i
);
286 void EpocSdlEnv::FreeSurface()
288 Request(CSdlAppServ::EAppSrvDsaStatus
);
289 if(gEpocEnv
->iDsa
!= NULL
)
290 gEpocEnv
->iDsa
->Free();
293 void EpocSdlEnvData::Free()
299 void EpocSdlEnvData::Delete()
312 gEpocEnv
->iCleanupItems
= new CArrayFixFlat
<TSdlCleanupItem
>(8);
315 char** argv
= new char*[1];
316 argv
[0] = new char[8];
317 strcpy(argv
[0], "app.exe");
319 TMainFunc iMain
= SDL_main
;
321 /* !! process exits here if there is "exit()" in main! */
323 for(int i
= 0; i
< 6; i
++)
325 void* f
= (void*) iMain
[i
];
331 ret
= ((mainfunc1
)f
)();
339 ret
= ((mainfunc2
)f
)(1, argv
);
343 ((mainfunc2
)f
)(1, argv
);
347 ret
= ((mainfunc3
)f
)(1, argv
, envp
);
351 ((mainfunc3
)f
)(1, argv
, envp
);
370 gEpocEnv
->iAppSrv
->Init();
372 TRAPD(err
, err
= MainL());
374 // Free resources and return
375 EpocSdlEnv::CleanupItems();
377 gEpocEnv
->iCleanupItems
->Reset();
378 delete gEpocEnv
->iCleanupItems
;
379 gEpocEnv
->iCleanupItems
= NULL
;
381 gEpocEnv
->Free(); //free up in thread resources
388 __ASSERT_ALWAYS(gEpocEnv
== NULL
, PANIC(KErrAlreadyExists
));
389 gEpocEnv
= new EpocSdlEnvData
;
390 Mem::FillZ(gEpocEnv
, sizeof(EpocSdlEnvData
));
392 gEpocEnv
->iEventQueue
= new CEventQueue();
393 gEpocEnv
->iAppSrv
= new CSdlAppServ();
395 gEpocEnv
->iSdl
= this;
407 void CSDL::SetContainerWindowL(RWindow
& aWindow
, RWsSession
& aSession
, CWsScreenDevice
& aDevice
)
409 if(gEpocEnv
->iDsa
== NULL
)
410 gEpocEnv
->iDsa
= CDsa::CreateL(aSession
);
411 gEpocEnv
->iDsa
->ConstructL(aWindow
, aDevice
);
414 int EpocSdlEnv::ApplyGlesDsa()
417 TRAPD(err
, dsa
= gEpocEnv
->iDsa
->CreateGlesDsaL());
418 gEpocEnv
->iDsa
= dsa
;
422 RWindow
* EpocSdlEnv::Window()
424 return gEpocEnv
->iDsa
->Window();
427 void EpocSdlEnv::UpdateWholeScreen(bool val
)
429 gEpocEnv
->iDsa
->m_updateWholeScreen
= val
;
432 bool EpocSdlEnv::GetUpdateWholeScreen()
434 return gEpocEnv
->iDsa
->m_updateWholeScreen
;
437 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation
, const TSize
& aSize
, TDisplayMode aMode
)
439 gEpocEnv
->iWaitingForOrientationChange
= true;
440 gEpocEnv
->iSize
= aSize
;
441 gEpocEnv
->iMode
= aMode
;
443 TRAPD(err
, static_cast<CAknAppUi
*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation
));
446 void CSDL::CallMainL()
448 ASSERT(gEpocEnv
!= NULL
);
450 gEpocEnv
->iAppSrv
->ConstructL();
452 // for handling volume up/down keys
453 CRemConInterfaceSelector
*iSelector
= CRemConInterfaceSelector::NewL();
454 CRemConCoreApiTarget::NewL( *iSelector
, *this );
455 iSelector
->OpenTargetL();
457 // when priority is not lowered screen updates much more frequently, which
458 // may be undesired, for example in case of openttd's generating world dialog
459 RThread().SetPriority(EPriorityLess
);
463 void CSDL::AppendWsEvent(const TWsEvent
& aEvent
)
465 EpocSdlEnv::EventQueue().Append(aEvent
);
470 if(gEpocEnv
->iWaitingForOrientationChange
)
472 EpocSdlEnv::AllocSurface(gEpocEnv
->iSize
, gEpocEnv
->iMode
);
473 gEpocEnv
->iWaitingForOrientationChange
= false;
477 TSize size
= gEpocEnv
->iDsa
->Window()->Size();
478 SDL_PrivateResize(size
.iWidth
, size
.iHeight
);
482 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId
, TRemConCoreApiButtonAction aButtonAct
)
484 if(aButtonAct
!= ERemConCoreApiButtonClick
)
488 event
.SetType(EEventKey
);
493 case ERemConCoreApiVolumeDown
:
494 event
.Key()->iScanCode
= EStdKeyDecVolume
;
495 event
.SetType(EEventKeyDown
);
496 AppendWsEvent(event
);
497 event
.SetType(EEventKeyUp
);
498 AppendWsEvent(event
);
501 case ERemConCoreApiVolumeUp
:
502 event
.Key()->iScanCode
= EStdKeyIncVolume
;
503 event
.SetType(EEventKeyDown
);
504 AppendWsEvent(event
);
505 event
.SetType(EEventKeyUp
);
506 AppendWsEvent(event
);