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
;
35 CArrayFix
<TSdlCleanupItem
>* iCleanupItems
;
37 bool iWaitingForOrientationChange
;
43 EpocSdlEnvData
* gEpocEnv
;
45 static void RunSingleThread()
47 if(RThread().RequestCount() > 0)
50 if(CActiveScheduler::RunIfReady(err
, CActive::EPriorityIdle
))
52 CActiveScheduler::Current()->WaitForAnyRequest();
57 int Panic(int aErr
, int aLine
)
60 b
.Format(_L("Main at %d"), aLine
);
66 bool CEventQueue::HasData()
69 return !m_queue
.empty();
72 const TWsEvent
CEventQueue::Shift()
74 const TWsEvent event
= m_queue
.front();
80 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation
, void* aItem
) :
81 iOperation(aOperation
), iItem(aItem
), iThread(RThread().Id())
84 #define MAINFUNC(x) TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
93 TMainFunc::TMainFunc()
95 Mem::FillZ(iMainFunc
, sizeof(iMainFunc
));
98 const void* TMainFunc::operator[](int aIndex
) const
100 return iMainFunc
[aIndex
];
103 class CSdlAppServ
: public CActive
114 int Request(int aService
);
116 void SetParam(int aParam
);
121 const TThreadId iMainId
;
125 TRequestStatus
* iStatusPtr
;
128 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh
), iMainId(RThread().Id())
131 void CSdlAppServ::ConstructL()
133 CActiveScheduler::Add(this);
134 iStatus
= KRequestPending
;
135 iStatusPtr
= &iStatus
;
139 CSdlAppServ::~CSdlAppServ()
145 int CSdlAppServ::Request(int aService
)
149 iAppThread
.RequestComplete(iStatusPtr
, KErrNone
);
153 void CSdlAppServ::Init()
155 PANIC_IF_ERROR(iAppThread
.Open(iMainId
));
158 void CSdlAppServ::SetParam(int aParam
)
160 iReturnValue
= aParam
;
163 void CSdlAppServ::RunL()
165 if(iStatus
== KErrNone
)
169 case CSdlAppServ::EAppSrvStopThread
:
170 if(gEpocEnv
->iDsa
!= NULL
)
171 gEpocEnv
->iDsa
->SetSuspend();
174 case EAppSrvDsaStatus
:
175 if(gEpocEnv
->iDsa
!= NULL
)
176 gEpocEnv
->iDsa
->Stop();
177 iReturnValue
= KErrNone
;
181 PANIC(KErrNotSupported
);
185 iStatus
= KRequestPending
;
186 iStatusPtr
= &iStatus
;
191 void CSdlAppServ::DoCancel()
193 TRequestStatus
* s
= &iStatus
;
194 iAppThread
.RequestComplete(s
, KErrCancel
);
197 CEventQueue
& EpocSdlEnv::EventQueue()
199 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
200 return *gEpocEnv
->iEventQueue
;
203 TBool
EpocSdlEnv::IsDsaAvailable()
205 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
206 return gEpocEnv
->iDsa
!= NULL
&& gEpocEnv
->iDsa
->IsDsaAvailable();
209 void EpocSdlEnv::WaitDsaAvailable()
211 gEpocEnv
->iAppSrv
->Request(CSdlAppServ::EAppSrvStopThread
);
214 int EpocSdlEnv::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
216 return gEpocEnv
->iDsa
->AllocSurface(aSize
, aMode
);
219 void EpocSdlEnv::UnlockHwSurface()
221 gEpocEnv
->iDsa
->UnlockHwSurface();
224 TUint8
* EpocSdlEnv::LockHwSurface()
226 return gEpocEnv
->iDsa
->LockHwSurface();
229 void EpocSdlEnv::UpdateSwSurface()
231 gEpocEnv
->iDsa
->UpdateSwSurface();
234 TBool
EpocSdlEnv::AddUpdateRect(TUint8
* aAddress
, const TRect
& aUpdateRect
, const TRect
& aRect
)
236 return gEpocEnv
->iDsa
->AddUpdateRect(aAddress
, aUpdateRect
, aRect
);
239 void EpocSdlEnv::Request(int aService
)
241 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
242 gEpocEnv
->iAppSrv
->Request(aService
);
245 TDisplayMode
EpocSdlEnv::DisplayMode()
247 return gEpocEnv
->iDsa
== NULL
? ENone
: gEpocEnv
->iDsa
->DisplayMode();
250 int EpocSdlEnv::SetPalette(int aFirstcolor
, int aColorCount
, TUint32
* aPalette
)
252 return gEpocEnv
->iDsa
->SetPalette(aFirstcolor
, aColorCount
, aPalette
);
255 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem
& aItem
)
257 TRAPD(err
, gEpocEnv
->iCleanupItems
->AppendL(aItem
));
261 void EpocSdlEnv::RemoveCleanupItem(void* aItem
)
263 for(int i
= 0; i
< gEpocEnv
->iCleanupItems
->Count(); i
++)
265 if(gEpocEnv
->iCleanupItems
->At(i
).iItem
== aItem
)
266 gEpocEnv
->iCleanupItems
->Delete(i
);
270 void EpocSdlEnv::CleanupItems()
272 const TThreadId id
= RThread().Id();
273 int last
= gEpocEnv
->iCleanupItems
->Count() - 1;
276 for(i
= last
; i
>= 0 ; i
--)
278 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
279 if(item
.iThread
== id
)
281 item
.iThread
= TThreadId(0);
282 item
.iOperation(item
.iItem
);
286 last
= gEpocEnv
->iCleanupItems
->Count() - 1;
288 for(i
= last
; i
>= 0 ; i
--)
290 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
291 if(item
.iThread
== TThreadId(0))
293 gEpocEnv
->iCleanupItems
->Delete(i
);
298 void EpocSdlEnv::FreeSurface()
300 Request(CSdlAppServ::EAppSrvDsaStatus
);
301 if(gEpocEnv
->iDsa
!= NULL
)
302 gEpocEnv
->iDsa
->Free();
305 static TBool
CheckSdl()
309 if(sdl
.Open(gEpocEnv
->iId
) == KErrNone
)
311 if(sdl
.ExitType() == EExitPending
)
320 void EpocSdlEnvData::Free()
322 if(RThread().Id() == gEpocEnv
->iId
)
329 __ASSERT_ALWAYS(CheckSdl(), PANIC(KErrNotReady
));
332 void EpocSdlEnvData::Delete()
345 gEpocEnv
->iCleanupItems
= new CArrayFixFlat
<TSdlCleanupItem
>(8);
348 char** argv
= new char*[1];
349 argv
[0] = new char[8];
350 strcpy(argv
[0], "app.exe");
352 TMainFunc iMain
= SDL_main
;
354 /* !! process exits here if there is "exit()" in main! */
356 for(int i
= 0; i
< 6; i
++)
358 void* f
= (void*) iMain
[i
];
364 ret
= ((mainfunc1
)f
)();
372 ret
= ((mainfunc2
)f
)(1, argv
);
376 ((mainfunc2
)f
)(1, argv
);
380 ret
= ((mainfunc3
)f
)(1, argv
, envp
);
384 ((mainfunc3
)f
)(1, argv
, envp
);
403 gEpocEnv
->iAppSrv
->Init();
405 TRAPD(err
, err
= MainL());
407 // Free resources and return
408 EpocSdlEnv::CleanupItems();
410 gEpocEnv
->iCleanupItems
->Reset();
411 delete gEpocEnv
->iCleanupItems
;
412 gEpocEnv
->iCleanupItems
= NULL
;
414 gEpocEnv
->Free(); //free up in thread resources
421 __ASSERT_ALWAYS(gEpocEnv
== NULL
, PANIC(KErrAlreadyExists
));
422 gEpocEnv
= new EpocSdlEnvData
;
423 Mem::FillZ(gEpocEnv
, sizeof(EpocSdlEnvData
));
425 gEpocEnv
->iEventQueue
= new CEventQueue();
426 gEpocEnv
->iAppSrv
= new CSdlAppServ();
428 gEpocEnv
->iSdl
= this;
440 void CSDL::SetContainerWindowL(RWindow
& aWindow
, RWsSession
& aSession
, CWsScreenDevice
& aDevice
)
442 if(gEpocEnv
->iDsa
== NULL
)
443 gEpocEnv
->iDsa
= CDsa::CreateL(aSession
);
444 gEpocEnv
->iDsa
->ConstructL(aWindow
, aDevice
);
447 int EpocSdlEnv::ApplyGlesDsa()
450 TRAPD(err
, dsa
= gEpocEnv
->iDsa
->CreateGlesDsaL());
451 gEpocEnv
->iDsa
= dsa
;
455 RWindow
* EpocSdlEnv::Window()
457 return gEpocEnv
->iDsa
->Window();
460 void EpocSdlEnv::UpdateWholeScreen(bool val
)
462 gEpocEnv
->iDsa
->m_updateWholeScreen
= val
;
465 bool EpocSdlEnv::GetUpdateWholeScreen()
467 return gEpocEnv
->iDsa
->m_updateWholeScreen
;
470 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation
, const TSize
& aSize
, TDisplayMode aMode
)
472 gEpocEnv
->iWaitingForOrientationChange
= true;
473 gEpocEnv
->iSize
= aSize
;
474 gEpocEnv
->iMode
= aMode
;
476 TRAPD(err
, static_cast<CAknAppUi
*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation
));
479 void CSDL::CallMainL()
481 ASSERT(gEpocEnv
!= NULL
);
483 gEpocEnv
->iAppSrv
->ConstructL();
485 // for handling volume up/down keys
486 CRemConInterfaceSelector
*iSelector
= CRemConInterfaceSelector::NewL();
487 CRemConCoreApiTarget::NewL( *iSelector
, *this );
488 iSelector
->OpenTargetL();
490 gEpocEnv
->iId
= RThread().Id();
491 // when priority is not lowered screen updates much more frequently, which
492 // may be undesired, for example in case of openttd's generating world dialog
493 RThread().SetPriority(EPriorityLess
);
497 void CSDL::AppendWsEvent(const TWsEvent
& aEvent
)
499 EpocSdlEnv::EventQueue().Append(aEvent
);
504 if(gEpocEnv
->iWaitingForOrientationChange
)
506 EpocSdlEnv::AllocSurface(gEpocEnv
->iSize
, gEpocEnv
->iMode
);
507 gEpocEnv
->iWaitingForOrientationChange
= false;
511 TSize size
= gEpocEnv
->iDsa
->Window()->Size();
512 SDL_PrivateResize(size
.iWidth
, size
.iHeight
);
516 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId
, TRemConCoreApiButtonAction aButtonAct
)
518 if(aButtonAct
!= ERemConCoreApiButtonClick
)
522 event
.SetType(EEventKey
);
527 case ERemConCoreApiVolumeDown
:
528 event
.Key()->iScanCode
= EStdKeyDecVolume
;
529 event
.SetType(EEventKeyDown
);
530 AppendWsEvent(event
);
531 event
.SetType(EEventKeyUp
);
532 AppendWsEvent(event
);
535 case ERemConCoreApiVolumeUp
:
536 event
.Key()->iScanCode
= EStdKeyIncVolume
;
537 event
.SetType(EEventKeyDown
);
538 AppendWsEvent(event
);
539 event
.SetType(EEventKeyUp
);
540 AppendWsEvent(event
);