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
;
38 CArrayFix
<TSdlCleanupItem
>* iCleanupItems
;
40 TRequestStatus
* iCallerStatus
;
41 bool iWaitingForOrientationChange
;
47 EpocSdlEnvData
* gEpocEnv
;
49 static void RunSingleThread()
51 int count
= RThread().RequestCount();
55 if(CActiveScheduler::RunIfReady(err
, CActive::EPriorityIdle
))
57 CActiveScheduler::Current()->WaitForAnyRequest();
62 int Panic(int aErr
, int aLine
)
65 b
.Format(_L("Main at %d"), aLine
);
71 bool CEventQueue::HasData()
74 return !m_queue
.empty();
77 const TWsEvent
CEventQueue::Shift()
79 const TWsEvent event
= m_queue
.front();
85 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation
, void* aItem
) :
86 iOperation(aOperation
), iItem(aItem
), iThread(RThread().Id())
89 #define MAINFUNC(x) TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
98 TMainFunc::TMainFunc()
100 Mem::FillZ(iMainFunc
, sizeof(iMainFunc
));
104 const void* TMainFunc::operator[](int aIndex
) const
106 return iMainFunc
[aIndex
];
110 class CSdlAppServ
: public CActive
115 EAppSrvNoop
= CDsa::ELastDsaRequest
,
118 EAppSrvWindowDisplayMode
,
126 int Request(int aService
);
127 int RequestValue(int aService
);
129 void SetParam(int aParam
);
134 const TThreadId iMainId
;
138 TRequestStatus
* iStatusPtr
;
141 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh
), iMainId(RThread().Id())
144 void CSdlAppServ::ConstructL()
146 CActiveScheduler::Add(this);
147 iStatus
= KRequestPending
;
148 iStatusPtr
= &iStatus
;
152 CSdlAppServ::~CSdlAppServ()
158 int CSdlAppServ::Request(int aService
)
162 iAppThread
.RequestComplete(iStatusPtr
, KErrNone
);
166 int CSdlAppServ::RequestValue(int aService
)
169 Request(EAppSrvNoop
);
173 void CSdlAppServ::Init()
175 PANIC_IF_ERROR(iAppThread
.Open(iMainId
));
178 void CSdlAppServ::SetParam(int aParam
)
180 iReturnValue
= aParam
;
183 void CSdlAppServ::RunL()
185 if(iStatus
== KErrNone
)
189 case CSdlAppServ::EAppSrvWaitDsa
:
190 EpocSdlEnv::SetWaitDsa();
191 iReturnValue
= EpocSdlEnv::IsDsaAvailable();
194 case CSdlAppServ::EAppSrvStopThread
:
195 if(gEpocEnv
->iDsa
!= NULL
)
196 gEpocEnv
->iDsa
->SetSuspend();
199 case EAppSrvDsaStatus
:
200 if(gEpocEnv
->iDsa
!= NULL
)
201 gEpocEnv
->iDsa
->Stop();
202 iReturnValue
= KErrNone
;
209 PANIC(KErrNotSupported
);
213 iStatus
= KRequestPending
;
214 iStatusPtr
= &iStatus
;
219 void CSdlAppServ::DoCancel()
221 TRequestStatus
* s
= &iStatus
;
222 iAppThread
.RequestComplete(s
, KErrCancel
);
225 CEventQueue
& EpocSdlEnv::EventQueue()
227 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
228 return *gEpocEnv
->iEventQueue
;
231 int EpocSdlEnv::Argc()
233 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
234 return gEpocEnv
->iArgc
;
237 char** EpocSdlEnv::Argv()
239 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
240 return gEpocEnv
->iArgv
;
243 TBool
EpocSdlEnv::IsDsaAvailable()
245 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
246 return gEpocEnv
->iDsa
!= NULL
&& gEpocEnv
->iDsa
->IsDsaAvailable();
249 void EpocSdlEnv::WaitDsaAvailable()
251 gEpocEnv
->iAppSrv
->Request(CSdlAppServ::EAppSrvStopThread
);
254 int EpocSdlEnv::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
256 return gEpocEnv
->iDsa
->AllocSurface(aSize
, aMode
);
259 void EpocSdlEnv::UnlockHwSurface()
261 gEpocEnv
->iDsa
->UnlockHwSurface();
264 TUint8
* EpocSdlEnv::LockHwSurface()
266 return gEpocEnv
->iDsa
->LockHwSurface();
269 void EpocSdlEnv::UpdateSwSurface()
271 gEpocEnv
->iDsa
->UpdateSwSurface();
274 TBool
EpocSdlEnv::AddUpdateRect(TUint8
* aAddress
, const TRect
& aUpdateRect
, const TRect
& aRect
)
276 return gEpocEnv
->iDsa
->AddUpdateRect(aAddress
, aUpdateRect
, aRect
);
279 void EpocSdlEnv::Request(int aService
)
281 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
282 gEpocEnv
->iAppSrv
->Request(aService
);
285 TDisplayMode
EpocSdlEnv::DisplayMode()
287 return gEpocEnv
->iDsa
== NULL
? ENone
: gEpocEnv
->iDsa
->DisplayMode();
290 int EpocSdlEnv::SetPalette(int aFirstcolor
, int aColorCount
, TUint32
* aPalette
)
292 return gEpocEnv
->iDsa
->SetPalette(aFirstcolor
, aColorCount
, aPalette
);
295 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem
& aItem
)
297 TRAPD(err
, gEpocEnv
->iCleanupItems
->AppendL(aItem
));
301 void EpocSdlEnv::RemoveCleanupItem(void* aItem
)
303 for(int i
= 0; i
< gEpocEnv
->iCleanupItems
->Count(); i
++)
305 if(gEpocEnv
->iCleanupItems
->At(i
).iItem
== aItem
)
306 gEpocEnv
->iCleanupItems
->Delete(i
);
310 void EpocSdlEnv::CleanupItems()
312 const TThreadId id
= RThread().Id();
313 int last
= gEpocEnv
->iCleanupItems
->Count() - 1;
316 for(i
= last
; i
>= 0 ; i
--)
318 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
319 if(item
.iThread
== id
)
321 item
.iThread
= TThreadId(0);
322 item
.iOperation(item
.iItem
);
326 last
= gEpocEnv
->iCleanupItems
->Count() - 1;
328 for(i
= last
; i
>= 0 ; i
--)
330 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
331 if(item
.iThread
== TThreadId(0))
333 gEpocEnv
->iCleanupItems
->Delete(i
);
338 void EpocSdlEnv::FreeSurface()
340 Request(CSdlAppServ::EAppSrvDsaStatus
);
341 if(gEpocEnv
->iDsa
!= NULL
)
342 gEpocEnv
->iDsa
->Free();
345 //Dsa is a low priority ao, it has to wait if its pending event, but ws
346 //event has been prioritized before it
347 //this is not called from app thread!
348 void EpocSdlEnv::WaitDeviceChange()
350 gEpocEnv
->iAppSrv
->RequestValue(CSdlAppServ::EAppSrvWaitDsa
);
353 static TBool
CheckSdl()
357 if(sdl
.Open(gEpocEnv
->iId
) == KErrNone
)
359 if(sdl
.ExitType() == EExitPending
)
368 void EpocSdlEnvData::Free()
370 if(RThread().Id() == gEpocEnv
->iId
)
377 __ASSERT_ALWAYS(iArgv
== NULL
|| CheckSdl(), PANIC(KErrNotReady
));
380 void EpocSdlEnvData::Delete()
382 for(int i
= 0; i
<= iArgc
; i
++)
404 gEpocEnv
->iCleanupItems
= new CArrayFixFlat
<TSdlCleanupItem
>(8);
407 /* !! process exits here if there is "exit()" in main! */
409 for(int i
= 0; i
< 6; i
++)
411 void* f
= (void*) gEpocEnv
->iMain
[i
];
417 ret
= ((mainfunc1
)f
)();
425 ret
= ((mainfunc2
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
429 ((mainfunc2
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
433 ret
= ((mainfunc3
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp
);
437 ((mainfunc3
)f
)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp
);
448 gEpocEnv
->iAppSrv
->Init();
450 TRAPD(err
, err
= MainL());
452 // Free resources and return
453 EpocSdlEnv::CleanupItems();
455 gEpocEnv
->iCleanupItems
->Reset();
456 delete gEpocEnv
->iCleanupItems
;
457 gEpocEnv
->iCleanupItems
= NULL
;
459 gEpocEnv
->Free(); //free up in thread resources
461 if(gEpocEnv
->iCallerStatus
!= NULL
)
463 User::RequestComplete(gEpocEnv
->iCallerStatus
, err
);
468 return err
== KErrNone
? 0 : err
;
483 __ASSERT_ALWAYS(gEpocEnv
== NULL
, PANIC(KErrAlreadyExists
));
484 gEpocEnv
= new EpocSdlEnvData
;
485 Mem::FillZ(gEpocEnv
, sizeof(EpocSdlEnvData
));
487 gEpocEnv
->iEventQueue
= new CEventQueue();
488 gEpocEnv
->iAppSrv
= new CSdlAppServ();
490 CSDL
* sdl
= new CSDL();
492 gEpocEnv
->iSdl
= sdl
;
497 void CSDL::SetContainerWindowL(RWindow
& aWindow
, RWsSession
& aSession
, CWsScreenDevice
& aDevice
)
499 if(gEpocEnv
->iDsa
== NULL
)
500 gEpocEnv
->iDsa
= CDsa::CreateL(aSession
);
501 gEpocEnv
->iDsa
->ConstructL(aWindow
, aDevice
);
504 int EpocSdlEnv::ApplyGlesDsa()
507 TRAPD(err
, dsa
= gEpocEnv
->iDsa
->CreateGlesDsaL());
508 gEpocEnv
->iDsa
= dsa
;
512 RWindow
* EpocSdlEnv::Window()
514 return gEpocEnv
->iDsa
->Window();
517 void EpocSdlEnv::UpdateWholeScreen(bool val
)
519 gEpocEnv
->iDsa
->m_updateWholeScreen
= val
;
522 bool EpocSdlEnv::GetUpdateWholeScreen()
524 return gEpocEnv
->iDsa
->m_updateWholeScreen
;
527 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation
, const TSize
& aSize
, TDisplayMode aMode
)
529 gEpocEnv
->iWaitingForOrientationChange
= true;
530 gEpocEnv
->iSize
= aSize
;
531 gEpocEnv
->iMode
= aMode
;
533 TRAPD(err
, static_cast<CAknAppUi
*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation
));
536 TThreadId
CSDL::CallMainL(const TMainFunc
& aFunc
, TRequestStatus
* const aStatus
, const CDesC8Array
* const aArg
)
538 ASSERT(gEpocEnv
!= NULL
);
539 gEpocEnv
->iMain
= aFunc
;
540 const TBool args
= aArg
!= NULL
;
542 gEpocEnv
->iArgc
= args
? aArg
->Count() + 1 : 0;
543 gEpocEnv
->iArgv
= new char*[gEpocEnv
->iArgc
+ 2];
546 const TFileName processName
= RProcess().FileName();
547 const int len
= processName
.Length();
548 gEpocEnv
->iArgv
[k
] = new char[len
+ 1];
549 memcpy(gEpocEnv
->iArgv
[k
], processName
.Ptr(), len
);
550 gEpocEnv
->iArgv
[k
][len
] = 0;
552 for(int i
= 0; args
&& (i
< aArg
->Count()); i
++)
555 const int len
= aArg
->MdcaPoint(i
).Length();
556 gEpocEnv
->iArgv
[k
] = new char[len
+ 1];
557 memcpy(gEpocEnv
->iArgv
[k
], aArg
->MdcaPoint(i
).Ptr(), len
);
558 gEpocEnv
->iArgv
[k
][len
] = 0;
561 gEpocEnv
->iArgv
[k
+ 1] = NULL
;
563 gEpocEnv
->iAppSrv
->ConstructL();
565 // for handling volume up/down keys
566 CRemConInterfaceSelector
*iSelector
= CRemConInterfaceSelector::NewL();
567 CRemConCoreApiTarget::NewL( *iSelector
, *this );
568 iSelector
->OpenTargetL();
570 gEpocEnv
->iCallerStatus
= aStatus
;
572 *aStatus
= KRequestPending
;
573 gEpocEnv
->iId
= RThread().Id();
574 // when priority is not lowered screen updates much more frequently, which
575 // may be undesired, for example in case of openttd's generating world dialog
576 RThread().SetPriority(EPriorityLess
);
579 return gEpocEnv
->iId
;
582 void CSDL::AppendWsEvent(const TWsEvent
& aEvent
)
584 EpocSdlEnv::EventQueue().Append(aEvent
);
589 if(gEpocEnv
->iWaitingForOrientationChange
)
591 EpocSdlEnv::AllocSurface(gEpocEnv
->iSize
, gEpocEnv
->iMode
);
592 gEpocEnv
->iWaitingForOrientationChange
= false;
596 TSize size
= gEpocEnv
->iDsa
->Window()->Size();
597 SDL_PrivateResize(size
.iWidth
, size
.iHeight
);
601 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId
, TRemConCoreApiButtonAction aButtonAct
)
603 if(aButtonAct
!= ERemConCoreApiButtonClick
)
607 event
.SetType(EEventKey
);
612 case ERemConCoreApiVolumeDown
:
613 event
.Key()->iScanCode
= EStdKeyDecVolume
;
614 event
.SetType(EEventKeyDown
);
615 AppendWsEvent(event
);
616 event
.SetType(EEventKeyUp
);
617 AppendWsEvent(event
);
620 case ERemConCoreApiVolumeUp
:
621 event
.Key()->iScanCode
= EStdKeyIncVolume
;
622 event
.SetType(EEventKeyDown
);
623 AppendWsEvent(event
);
624 event
.SetType(EEventKeyUp
);
625 AppendWsEvent(event
);