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
;
36 CArrayFix
<TSdlCleanupItem
>* iCleanupItems
;
38 TRequestStatus
* iCallerStatus
;
39 bool iWaitingForOrientationChange
;
45 EpocSdlEnvData
* gEpocEnv
;
47 static void RunSingleThread()
49 if(RThread().RequestCount() > 0)
52 if(CActiveScheduler::RunIfReady(err
, CActive::EPriorityIdle
))
54 CActiveScheduler::Current()->WaitForAnyRequest();
59 int Panic(int aErr
, int aLine
)
62 b
.Format(_L("Main at %d"), aLine
);
68 bool CEventQueue::HasData()
71 return !m_queue
.empty();
74 const TWsEvent
CEventQueue::Shift()
76 const TWsEvent event
= m_queue
.front();
82 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation
, void* aItem
) :
83 iOperation(aOperation
), iItem(aItem
), iThread(RThread().Id())
86 #define MAINFUNC(x) TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
95 TMainFunc::TMainFunc()
97 Mem::FillZ(iMainFunc
, sizeof(iMainFunc
));
101 const void* TMainFunc::operator[](int aIndex
) const
103 return iMainFunc
[aIndex
];
106 class CSdlAppServ
: public CActive
117 int Request(int aService
);
119 void SetParam(int aParam
);
124 const TThreadId iMainId
;
128 TRequestStatus
* iStatusPtr
;
131 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh
), iMainId(RThread().Id())
134 void CSdlAppServ::ConstructL()
136 CActiveScheduler::Add(this);
137 iStatus
= KRequestPending
;
138 iStatusPtr
= &iStatus
;
142 CSdlAppServ::~CSdlAppServ()
148 int CSdlAppServ::Request(int aService
)
152 iAppThread
.RequestComplete(iStatusPtr
, KErrNone
);
156 void CSdlAppServ::Init()
158 PANIC_IF_ERROR(iAppThread
.Open(iMainId
));
161 void CSdlAppServ::SetParam(int aParam
)
163 iReturnValue
= aParam
;
166 void CSdlAppServ::RunL()
168 if(iStatus
== KErrNone
)
172 case CSdlAppServ::EAppSrvStopThread
:
173 if(gEpocEnv
->iDsa
!= NULL
)
174 gEpocEnv
->iDsa
->SetSuspend();
177 case EAppSrvDsaStatus
:
178 if(gEpocEnv
->iDsa
!= NULL
)
179 gEpocEnv
->iDsa
->Stop();
180 iReturnValue
= KErrNone
;
184 PANIC(KErrNotSupported
);
188 iStatus
= KRequestPending
;
189 iStatusPtr
= &iStatus
;
194 void CSdlAppServ::DoCancel()
196 TRequestStatus
* s
= &iStatus
;
197 iAppThread
.RequestComplete(s
, KErrCancel
);
200 CEventQueue
& EpocSdlEnv::EventQueue()
202 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
203 return *gEpocEnv
->iEventQueue
;
206 TBool
EpocSdlEnv::IsDsaAvailable()
208 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
209 return gEpocEnv
->iDsa
!= NULL
&& gEpocEnv
->iDsa
->IsDsaAvailable();
212 void EpocSdlEnv::WaitDsaAvailable()
214 gEpocEnv
->iAppSrv
->Request(CSdlAppServ::EAppSrvStopThread
);
217 int EpocSdlEnv::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
219 return gEpocEnv
->iDsa
->AllocSurface(aSize
, aMode
);
222 void EpocSdlEnv::UnlockHwSurface()
224 gEpocEnv
->iDsa
->UnlockHwSurface();
227 TUint8
* EpocSdlEnv::LockHwSurface()
229 return gEpocEnv
->iDsa
->LockHwSurface();
232 void EpocSdlEnv::UpdateSwSurface()
234 gEpocEnv
->iDsa
->UpdateSwSurface();
237 TBool
EpocSdlEnv::AddUpdateRect(TUint8
* aAddress
, const TRect
& aUpdateRect
, const TRect
& aRect
)
239 return gEpocEnv
->iDsa
->AddUpdateRect(aAddress
, aUpdateRect
, aRect
);
242 void EpocSdlEnv::Request(int aService
)
244 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
245 gEpocEnv
->iAppSrv
->Request(aService
);
248 TDisplayMode
EpocSdlEnv::DisplayMode()
250 return gEpocEnv
->iDsa
== NULL
? ENone
: gEpocEnv
->iDsa
->DisplayMode();
253 int EpocSdlEnv::SetPalette(int aFirstcolor
, int aColorCount
, TUint32
* aPalette
)
255 return gEpocEnv
->iDsa
->SetPalette(aFirstcolor
, aColorCount
, aPalette
);
258 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem
& aItem
)
260 TRAPD(err
, gEpocEnv
->iCleanupItems
->AppendL(aItem
));
264 void EpocSdlEnv::RemoveCleanupItem(void* aItem
)
266 for(int i
= 0; i
< gEpocEnv
->iCleanupItems
->Count(); i
++)
268 if(gEpocEnv
->iCleanupItems
->At(i
).iItem
== aItem
)
269 gEpocEnv
->iCleanupItems
->Delete(i
);
273 void EpocSdlEnv::CleanupItems()
275 const TThreadId id
= RThread().Id();
276 int last
= gEpocEnv
->iCleanupItems
->Count() - 1;
279 for(i
= last
; i
>= 0 ; i
--)
281 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
282 if(item
.iThread
== id
)
284 item
.iThread
= TThreadId(0);
285 item
.iOperation(item
.iItem
);
289 last
= gEpocEnv
->iCleanupItems
->Count() - 1;
291 for(i
= last
; i
>= 0 ; i
--)
293 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
294 if(item
.iThread
== TThreadId(0))
296 gEpocEnv
->iCleanupItems
->Delete(i
);
301 void EpocSdlEnv::FreeSurface()
303 Request(CSdlAppServ::EAppSrvDsaStatus
);
304 if(gEpocEnv
->iDsa
!= NULL
)
305 gEpocEnv
->iDsa
->Free();
308 static TBool
CheckSdl()
312 if(sdl
.Open(gEpocEnv
->iId
) == KErrNone
)
314 if(sdl
.ExitType() == EExitPending
)
323 void EpocSdlEnvData::Free()
325 if(RThread().Id() == gEpocEnv
->iId
)
332 __ASSERT_ALWAYS(CheckSdl(), PANIC(KErrNotReady
));
335 void EpocSdlEnvData::Delete()
348 gEpocEnv
->iCleanupItems
= new CArrayFixFlat
<TSdlCleanupItem
>(8);
351 char** argv
= new char*[1];
352 argv
[0] = new char[8];
353 strcpy(argv
[0], "app.exe");
355 /* !! process exits here if there is "exit()" in main! */
357 for(int i
= 0; i
< 6; i
++)
359 void* f
= (void*) gEpocEnv
->iMain
[i
];
365 ret
= ((mainfunc1
)f
)();
373 ret
= ((mainfunc2
)f
)(1, argv
);
377 ((mainfunc2
)f
)(1, argv
);
381 ret
= ((mainfunc3
)f
)(1, argv
, envp
);
385 ((mainfunc3
)f
)(1, argv
, envp
);
404 gEpocEnv
->iAppSrv
->Init();
406 TRAPD(err
, err
= MainL());
408 // Free resources and return
409 EpocSdlEnv::CleanupItems();
411 gEpocEnv
->iCleanupItems
->Reset();
412 delete gEpocEnv
->iCleanupItems
;
413 gEpocEnv
->iCleanupItems
= NULL
;
415 gEpocEnv
->Free(); //free up in thread resources
417 if(gEpocEnv
->iCallerStatus
!= NULL
)
419 User::RequestComplete(gEpocEnv
->iCallerStatus
, err
);
424 return err
== KErrNone
? 0 : err
;
439 __ASSERT_ALWAYS(gEpocEnv
== NULL
, PANIC(KErrAlreadyExists
));
440 gEpocEnv
= new EpocSdlEnvData
;
441 Mem::FillZ(gEpocEnv
, sizeof(EpocSdlEnvData
));
443 gEpocEnv
->iEventQueue
= new CEventQueue();
444 gEpocEnv
->iAppSrv
= new CSdlAppServ();
446 CSDL
* sdl
= new CSDL();
448 gEpocEnv
->iSdl
= sdl
;
453 void CSDL::SetContainerWindowL(RWindow
& aWindow
, RWsSession
& aSession
, CWsScreenDevice
& aDevice
)
455 if(gEpocEnv
->iDsa
== NULL
)
456 gEpocEnv
->iDsa
= CDsa::CreateL(aSession
);
457 gEpocEnv
->iDsa
->ConstructL(aWindow
, aDevice
);
460 int EpocSdlEnv::ApplyGlesDsa()
463 TRAPD(err
, dsa
= gEpocEnv
->iDsa
->CreateGlesDsaL());
464 gEpocEnv
->iDsa
= dsa
;
468 RWindow
* EpocSdlEnv::Window()
470 return gEpocEnv
->iDsa
->Window();
473 void EpocSdlEnv::UpdateWholeScreen(bool val
)
475 gEpocEnv
->iDsa
->m_updateWholeScreen
= val
;
478 bool EpocSdlEnv::GetUpdateWholeScreen()
480 return gEpocEnv
->iDsa
->m_updateWholeScreen
;
483 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation
, const TSize
& aSize
, TDisplayMode aMode
)
485 gEpocEnv
->iWaitingForOrientationChange
= true;
486 gEpocEnv
->iSize
= aSize
;
487 gEpocEnv
->iMode
= aMode
;
489 TRAPD(err
, static_cast<CAknAppUi
*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation
));
492 TThreadId
CSDL::CallMainL(const TMainFunc
& aFunc
, TRequestStatus
* const aStatus
)
494 ASSERT(gEpocEnv
!= NULL
);
495 gEpocEnv
->iMain
= aFunc
;
497 gEpocEnv
->iAppSrv
->ConstructL();
499 // for handling volume up/down keys
500 CRemConInterfaceSelector
*iSelector
= CRemConInterfaceSelector::NewL();
501 CRemConCoreApiTarget::NewL( *iSelector
, *this );
502 iSelector
->OpenTargetL();
504 gEpocEnv
->iCallerStatus
= aStatus
;
506 *aStatus
= KRequestPending
;
507 gEpocEnv
->iId
= RThread().Id();
508 // when priority is not lowered screen updates much more frequently, which
509 // may be undesired, for example in case of openttd's generating world dialog
510 RThread().SetPriority(EPriorityLess
);
513 return gEpocEnv
->iId
;
516 void CSDL::AppendWsEvent(const TWsEvent
& aEvent
)
518 EpocSdlEnv::EventQueue().Append(aEvent
);
523 if(gEpocEnv
->iWaitingForOrientationChange
)
525 EpocSdlEnv::AllocSurface(gEpocEnv
->iSize
, gEpocEnv
->iMode
);
526 gEpocEnv
->iWaitingForOrientationChange
= false;
530 TSize size
= gEpocEnv
->iDsa
->Window()->Size();
531 SDL_PrivateResize(size
.iWidth
, size
.iHeight
);
535 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId
, TRemConCoreApiButtonAction aButtonAct
)
537 if(aButtonAct
!= ERemConCoreApiButtonClick
)
541 event
.SetType(EEventKey
);
546 case ERemConCoreApiVolumeDown
:
547 event
.Key()->iScanCode
= EStdKeyDecVolume
;
548 event
.SetType(EEventKeyDown
);
549 AppendWsEvent(event
);
550 event
.SetType(EEventKeyUp
);
551 AppendWsEvent(event
);
554 case ERemConCoreApiVolumeUp
:
555 event
.Key()->iScanCode
= EStdKeyIncVolume
;
556 event
.SetType(EEventKeyDown
);
557 AppendWsEvent(event
);
558 event
.SetType(EEventKeyUp
);
559 AppendWsEvent(event
);