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
105 CSdlAppServ() : CActive(CActive::EPriorityIdle
)
107 CActiveScheduler::Add(this);
110 ~CSdlAppServ() { Cancel(); }
113 TRequestStatus
* status
= &iStatus
;
114 User::RequestComplete(status
, KErrNone
);
121 TRequestStatus
* status
= &iStatus
;
122 User::RequestComplete(status
, KErrCancel
);
126 CEventQueue
& EpocSdlEnv::EventQueue()
128 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
129 return *gEpocEnv
->iEventQueue
;
132 TBool
EpocSdlEnv::IsDsaAvailable()
134 __ASSERT_DEBUG(gEpocEnv
!= NULL
, PANIC(KErrNotReady
));
135 return gEpocEnv
->iDsa
!= NULL
&& gEpocEnv
->iDsa
->IsDsaAvailable();
138 int EpocSdlEnv::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
140 return gEpocEnv
->iDsa
->AllocSurface(aSize
, aMode
);
143 void EpocSdlEnv::UnlockHwSurface()
145 gEpocEnv
->iDsa
->UnlockHwSurface();
148 TUint8
* EpocSdlEnv::LockHwSurface()
150 return gEpocEnv
->iDsa
->LockHwSurface();
153 void EpocSdlEnv::UpdateSwSurface()
155 gEpocEnv
->iDsa
->UpdateSwSurface();
158 TBool
EpocSdlEnv::AddUpdateRect(TUint8
* aAddress
, const TRect
& aUpdateRect
, const TRect
& aRect
)
160 return gEpocEnv
->iDsa
->AddUpdateRect(aAddress
, aUpdateRect
, aRect
);
163 TDisplayMode
EpocSdlEnv::DisplayMode()
165 return gEpocEnv
->iDsa
== NULL
? ENone
: gEpocEnv
->iDsa
->DisplayMode();
168 int EpocSdlEnv::SetPalette(int aFirstcolor
, int aColorCount
, TUint32
* aPalette
)
170 return gEpocEnv
->iDsa
->SetPalette(aFirstcolor
, aColorCount
, aPalette
);
173 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem
& aItem
)
175 TRAPD(err
, gEpocEnv
->iCleanupItems
->AppendL(aItem
));
179 void EpocSdlEnv::RemoveCleanupItem(void* aItem
)
181 for(int i
= 0; i
< gEpocEnv
->iCleanupItems
->Count(); i
++)
183 if(gEpocEnv
->iCleanupItems
->At(i
).iItem
== aItem
)
184 gEpocEnv
->iCleanupItems
->Delete(i
);
188 void EpocSdlEnv::CleanupItems()
190 const TThreadId id
= RThread().Id();
191 int last
= gEpocEnv
->iCleanupItems
->Count() - 1;
194 for(i
= last
; i
>= 0 ; i
--)
196 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
197 if(item
.iThread
== id
)
199 item
.iThread
= TThreadId(0);
200 item
.iOperation(item
.iItem
);
204 last
= gEpocEnv
->iCleanupItems
->Count() - 1;
206 for(i
= last
; i
>= 0 ; i
--)
208 TSdlCleanupItem
& item
= gEpocEnv
->iCleanupItems
->At(i
);
209 if(item
.iThread
== TThreadId(0))
211 gEpocEnv
->iCleanupItems
->Delete(i
);
216 void EpocSdlEnv::FreeSurface()
218 gEpocEnv
->iAppSrv
->Request();
220 if(gEpocEnv
->iDsa
!= NULL
)
222 gEpocEnv
->iDsa
->Stop();
223 gEpocEnv
->iDsa
->Free();
227 void EpocSdlEnvData::Free()
233 void EpocSdlEnvData::Delete()
246 gEpocEnv
->iCleanupItems
= new CArrayFixFlat
<TSdlCleanupItem
>(8);
249 char** argv
= new char*[1];
250 argv
[0] = new char[8];
251 strcpy(argv
[0], "app.exe");
253 TMainFunc iMain
= SDL_main
;
255 /* !! process exits here if there is "exit()" in main! */
257 for(int i
= 0; i
< 6; i
++)
259 void* f
= (void*) iMain
[i
];
265 ret
= ((mainfunc1
)f
)();
273 ret
= ((mainfunc2
)f
)(1, argv
);
277 ((mainfunc2
)f
)(1, argv
);
281 ret
= ((mainfunc3
)f
)(1, argv
, envp
);
285 ((mainfunc3
)f
)(1, argv
, envp
);
304 TRAPD(err
, err
= MainL());
306 // Free resources and return
307 EpocSdlEnv::CleanupItems();
309 gEpocEnv
->iCleanupItems
->Reset();
310 delete gEpocEnv
->iCleanupItems
;
311 gEpocEnv
->iCleanupItems
= NULL
;
313 gEpocEnv
->Free(); //free up in thread resources
320 __ASSERT_ALWAYS(gEpocEnv
== NULL
, PANIC(KErrAlreadyExists
));
321 gEpocEnv
= new EpocSdlEnvData
;
322 Mem::FillZ(gEpocEnv
, sizeof(EpocSdlEnvData
));
324 gEpocEnv
->iEventQueue
= new CEventQueue();
325 gEpocEnv
->iAppSrv
= new CSdlAppServ();
327 gEpocEnv
->iSdl
= this;
339 void CSDL::SetContainerWindowL(RWindow
& aWindow
, RWsSession
& aSession
, CWsScreenDevice
& aDevice
)
341 if(gEpocEnv
->iDsa
== NULL
)
342 gEpocEnv
->iDsa
= CDsa::CreateL(aSession
);
343 gEpocEnv
->iDsa
->ConstructL(aWindow
, aDevice
);
346 int EpocSdlEnv::ApplyGlesDsa()
349 TRAPD(err
, dsa
= gEpocEnv
->iDsa
->CreateGlesDsaL());
350 gEpocEnv
->iDsa
= dsa
;
354 RWindow
* EpocSdlEnv::Window()
356 return gEpocEnv
->iDsa
->Window();
359 void EpocSdlEnv::UpdateWholeScreen(bool val
)
361 gEpocEnv
->iDsa
->m_updateWholeScreen
= val
;
364 bool EpocSdlEnv::GetUpdateWholeScreen()
366 return gEpocEnv
->iDsa
->m_updateWholeScreen
;
369 void EpocSdlEnv::SetOrientation(CAknAppUi::TAppUiOrientation orientation
, const TSize
& aSize
, TDisplayMode aMode
)
371 gEpocEnv
->iWaitingForOrientationChange
= true;
372 gEpocEnv
->iSize
= aSize
;
373 gEpocEnv
->iMode
= aMode
;
375 TRAPD(err
, static_cast<CAknAppUi
*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation
));
378 void CSDL::CallMainL()
380 ASSERT(gEpocEnv
!= NULL
);
382 // for handling volume up/down keys
383 CRemConInterfaceSelector
*iSelector
= CRemConInterfaceSelector::NewL();
384 CRemConCoreApiTarget::NewL( *iSelector
, *this );
385 iSelector
->OpenTargetL();
387 // when priority is not lowered screen updates much more frequently, which
388 // may be undesired, for example in case of openttd's generating world dialog
389 RThread().SetPriority(EPriorityLess
);
393 void CSDL::AppendWsEvent(const TWsEvent
& aEvent
)
395 EpocSdlEnv::EventQueue().Append(aEvent
);
400 if(gEpocEnv
->iWaitingForOrientationChange
)
402 EpocSdlEnv::AllocSurface(gEpocEnv
->iSize
, gEpocEnv
->iMode
);
403 gEpocEnv
->iWaitingForOrientationChange
= false;
407 TSize size
= gEpocEnv
->iDsa
->Window()->Size();
408 SDL_PrivateResize(size
.iWidth
, size
.iHeight
);
412 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId
, TRemConCoreApiButtonAction aButtonAct
)
414 if(aButtonAct
!= ERemConCoreApiButtonClick
)
418 event
.SetType(EEventKey
);
423 case ERemConCoreApiVolumeDown
:
424 event
.Key()->iScanCode
= EStdKeyDecVolume
;
425 event
.SetType(EEventKeyDown
);
426 AppendWsEvent(event
);
427 event
.SetType(EEventKeyUp
);
428 AppendWsEvent(event
);
431 case ERemConCoreApiVolumeUp
:
432 event
.Key()->iScanCode
= EStdKeyIncVolume
;
433 event
.SetType(EEventKeyDown
);
434 AppendWsEvent(event
);
435 event
.SetType(EEventKeyUp
);
436 AppendWsEvent(event
);