Reduce CSdlAppServ usability to nil.
[SDL.s60v3.git] / src / main / symbian / SDL_main.cpp
blob974dda3e439be053c31b54a2aba233de9253a53a
1 extern "C" {
2 #include "SDL_events_c.h"
4 #include "epoc_sdl.h"
5 #include "sdlepocapi.h"
6 #include <e32base.h>
7 #include <estlib.h>
8 #include <stdio.h>
9 #include <badesca.h>
10 #include <w32std.h>
11 #include <aknappui.h>
12 #include <aknapp.h>
13 #include "SDL_epocevents_c.h"
14 #include "SDL_keysym.h"
15 #include "dsa.h"
16 #include "SDL_loadso.h"
17 #include <remconcoreapitargetobserver.h>
18 #include <remconinterfaceselector.h>
19 #include <remconcoreapitarget.h>
21 class CCurrentAppUi;
22 class CEikonEnv;
23 class CSdlAppServ;
24 class CEventQueue;
26 class EpocSdlEnvData
28 public:
29 void Free();
30 void Delete();
31 CEventQueue* iEventQueue;
32 CDsa* iDsa;
33 CSdlAppServ* iAppSrv;
34 CArrayFix<TSdlCleanupItem>* iCleanupItems;
35 CSDL* iSdl;
36 bool iWaitingForOrientationChange;
38 TSize iSize;
39 TDisplayMode iMode;
42 EpocSdlEnvData* gEpocEnv;
44 static void RunSingleThread()
46 if(RThread().RequestCount() > 0)
48 int err;
49 if(CActiveScheduler::RunIfReady(err, CActive::EPriorityIdle))
51 CActiveScheduler::Current()->WaitForAnyRequest();
56 int Panic(int aErr, int aLine)
58 TBuf<64> b;
59 b.Format(_L("Main at %d"), aLine);
60 User::Panic(b, aErr);
61 return 0;
65 bool CEventQueue::HasData()
67 RunSingleThread();
68 return !m_queue.empty();
71 const TWsEvent CEventQueue::Shift()
73 const TWsEvent event = m_queue.front();
74 m_queue.pop();
75 return event;
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;}
85 MAINFUNC(1)
86 MAINFUNC(2)
87 MAINFUNC(3)
88 MAINFUNC(4)
89 MAINFUNC(5)
90 MAINFUNC(6)
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
104 public:
105 CSdlAppServ() : CActive(CActive::EPriorityIdle)
107 CActiveScheduler::Add(this);
108 SetActive();
110 ~CSdlAppServ() { Cancel(); }
111 void Request()
113 TRequestStatus* status = &iStatus;
114 User::RequestComplete(status, KErrNone);
117 private:
118 void RunL() {}
119 void DoCancel()
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));
176 return err;
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;
192 int i;
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()
229 if(iDsa != NULL)
230 iDsa->Free();
233 void EpocSdlEnvData::Delete()
235 delete iEventQueue;
237 if(iDsa != NULL)
238 iDsa->Free();
240 delete iDsa;
241 delete iAppSrv;
244 static int MainL()
246 gEpocEnv->iCleanupItems = new CArrayFixFlat<TSdlCleanupItem>(8);
248 char** envp = 0;
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! */
256 int ret = 0;
257 for(int i = 0; i < 6; i++)
259 void* f = (void*) iMain[i];
260 if(f != NULL)
262 switch(i)
264 case 0:
265 ret = ((mainfunc1)f)();
266 break;
268 case 3:
269 ((mainfunc1)f)();
270 break;
272 case 1:
273 ret = ((mainfunc2)f)(1, argv);
274 break;
276 case 4:
277 ((mainfunc2)f)(1, argv);
278 break;
280 case 2:
281 ret = ((mainfunc3)f)(1, argv, envp);
282 break;
284 case 5:
285 ((mainfunc3)f)(1, argv, envp);
286 break;
288 default:
289 break;
292 delete[] argv[0];
293 delete[] argv;
294 return ret;
298 PANIC(KErrNotFound);
299 return 0;
302 static int DoMain()
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
315 return err;
318 CSDL::CSDL()
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;
330 CSDL::~CSDL()
332 gEpocEnv->Free();
333 gEpocEnv->Delete();
335 delete gEpocEnv;
336 gEpocEnv = NULL;
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()
348 CDsa* dsa = NULL;
349 TRAPD(err, dsa = gEpocEnv->iDsa->CreateGlesDsaL());
350 gEpocEnv->iDsa = dsa;
351 return err;
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);
390 DoMain();
393 void CSDL::AppendWsEvent(const TWsEvent& aEvent)
395 EpocSdlEnv::EventQueue().Append(aEvent);
398 void CSDL::Resize()
400 if(gEpocEnv->iWaitingForOrientationChange)
402 EpocSdlEnv::AllocSurface(gEpocEnv->iSize, gEpocEnv->iMode);
403 gEpocEnv->iWaitingForOrientationChange = false;
405 else
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)
415 return;
417 TWsEvent event;
418 event.SetType(EEventKey);
419 event.SetTimeNow();
421 switch(aOperationId)
423 case ERemConCoreApiVolumeDown:
424 event.Key()->iScanCode = EStdKeyDecVolume;
425 event.SetType(EEventKeyDown);
426 AppendWsEvent(event);
427 event.SetType(EEventKeyUp);
428 AppendWsEvent(event);
429 break;
431 case ERemConCoreApiVolumeUp:
432 event.Key()->iScanCode = EStdKeyIncVolume;
433 event.SetType(EEventKeyDown);
434 AppendWsEvent(event);
435 event.SetType(EEventKeyUp);
436 AppendWsEvent(event);
437 break;
439 default:
440 break;