Move EpocSdlEnv functionality do CSDL.
[SDL.s60v3.git] / src / main / symbian / SDL_main.cpp
blob2d758035dbf7493d047408fb0f7f84816fd938d0
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 CSDL* g_SDL = NULL;
23 class CCurrentAppUi;
24 class CEikonEnv;
25 class CSdlAppServ;
26 class CEventQueue;
28 class EpocSdlEnvData
30 public:
31 void Free();
32 void Delete();
33 CDsa* iDsa;
34 CSdlAppServ* iAppSrv;
35 CArrayFix<TSdlCleanupItem>* iCleanupItems;
38 EpocSdlEnvData* gEpocEnv;
40 static void RunSingleThread()
42 if(RThread().RequestCount() > 0)
44 int err;
45 if(CActiveScheduler::RunIfReady(err, CActive::EPriorityIdle))
47 CActiveScheduler::Current()->WaitForAnyRequest();
52 int Panic(int aErr, int aLine)
54 TBuf<64> b;
55 b.Format(_L("Main at %d"), aLine);
56 User::Panic(b, aErr);
57 return 0;
60 bool CEventQueue::HasData()
62 RunSingleThread();
63 return !m_queue.empty();
66 const TWsEvent CEventQueue::Shift()
68 const TWsEvent event = m_queue.front();
69 m_queue.pop();
70 return event;
74 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, void* aItem) :
75 iOperation(aOperation), iItem(aItem), iThread(RThread().Id())
78 class CSdlAppServ : public CActive
80 public:
81 CSdlAppServ() : CActive(CActive::EPriorityIdle)
83 CActiveScheduler::Add(this);
84 SetActive();
86 ~CSdlAppServ() { Cancel(); }
87 void Request()
89 TRequestStatus* status = &iStatus;
90 User::RequestComplete(status, KErrNone);
93 private:
94 void RunL() {}
95 void DoCancel()
97 TRequestStatus* status = &iStatus;
98 User::RequestComplete(status, KErrCancel);
102 TBool EpocSdlEnv::IsDsaAvailable()
104 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
105 return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
108 int EpocSdlEnv::AllocSurface(const TSize& aSize, TDisplayMode aMode)
110 return gEpocEnv->iDsa->AllocSurface(aSize, aMode);
113 void EpocSdlEnv::UnlockHwSurface()
115 gEpocEnv->iDsa->UnlockHwSurface();
118 TUint8* EpocSdlEnv::LockHwSurface()
120 return gEpocEnv->iDsa->LockHwSurface();
123 void EpocSdlEnv::UpdateSwSurface()
125 gEpocEnv->iDsa->UpdateSwSurface();
128 TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
130 return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
133 TDisplayMode EpocSdlEnv::DisplayMode()
135 return gEpocEnv->iDsa == NULL ? ENone : gEpocEnv->iDsa->DisplayMode();
138 int EpocSdlEnv::SetPalette(int aFirstcolor, int aColorCount, TUint32* aPalette)
140 return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
143 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
145 TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
146 return err;
149 void EpocSdlEnv::RemoveCleanupItem(void* aItem)
151 for(int i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
153 if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
154 gEpocEnv->iCleanupItems->Delete(i);
158 void EpocSdlEnv::CleanupItems()
160 const TThreadId id = RThread().Id();
161 int last = gEpocEnv->iCleanupItems->Count() - 1;
162 int i;
164 for(i = last; i >= 0 ; i--)
166 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
167 if(item.iThread == id)
169 item.iThread = TThreadId(0);
170 item.iOperation(item.iItem);
174 last = gEpocEnv->iCleanupItems->Count() - 1;
176 for(i = last; i >= 0 ; i--)
178 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
179 if(item.iThread == TThreadId(0))
181 gEpocEnv->iCleanupItems->Delete(i);
186 void EpocSdlEnv::FreeSurface()
188 gEpocEnv->iAppSrv->Request();
190 if(gEpocEnv->iDsa != NULL)
192 gEpocEnv->iDsa->Stop();
193 gEpocEnv->iDsa->Free();
197 void EpocSdlEnvData::Free()
199 if(iDsa != NULL)
200 iDsa->Free();
203 void EpocSdlEnvData::Delete()
205 if(iDsa != NULL)
206 iDsa->Free();
208 delete iDsa;
209 delete iAppSrv;
212 static int MainL()
214 gEpocEnv->iCleanupItems = new CArrayFixFlat<TSdlCleanupItem>(8);
216 char** argv = new char*[1];
217 argv[0] = new char[8];
218 strcpy(argv[0], "app.exe");
220 int ret = SDL_main( 1, argv );
222 delete[] argv[0];
223 delete[] argv;
225 return ret;
228 static int DoMain()
230 TRAPD(err, err = MainL());
232 // Free resources and return
233 EpocSdlEnv::CleanupItems();
235 gEpocEnv->iCleanupItems->Reset();
236 delete gEpocEnv->iCleanupItems;
237 gEpocEnv->iCleanupItems = NULL;
239 gEpocEnv->Free(); //free up in thread resources
241 return err;
244 CSDL::CSDL()
245 : m_orientationWait( false )
247 __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists));
248 gEpocEnv = new EpocSdlEnvData;
249 Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData));
251 m_eventQueue = new CEventQueue();
253 gEpocEnv->iAppSrv = new CSdlAppServ();
255 g_SDL = this;
258 CSDL::~CSDL()
260 g_SDL = NULL;
262 delete m_eventQueue;
264 gEpocEnv->Free();
265 gEpocEnv->Delete();
267 delete gEpocEnv;
268 gEpocEnv = NULL;
271 void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice)
273 if(gEpocEnv->iDsa == NULL)
274 gEpocEnv->iDsa = CDsa::CreateL(aSession);
275 gEpocEnv->iDsa->ConstructL(aWindow, aDevice);
278 int EpocSdlEnv::ApplyGlesDsa()
280 CDsa* dsa = NULL;
281 TRAPD(err, dsa = gEpocEnv->iDsa->CreateGlesDsaL());
282 gEpocEnv->iDsa = dsa;
283 return err;
286 RWindow* EpocSdlEnv::Window()
288 return gEpocEnv->iDsa->Window();
291 void EpocSdlEnv::UpdateWholeScreen(bool val)
293 gEpocEnv->iDsa->m_updateWholeScreen = val;
296 bool EpocSdlEnv::GetUpdateWholeScreen()
298 return gEpocEnv->iDsa->m_updateWholeScreen;
301 void CSDL::CallMainL()
303 ASSERT(gEpocEnv != NULL);
305 // for handling volume up/down keys
306 CRemConInterfaceSelector *iSelector = CRemConInterfaceSelector::NewL();
307 CRemConCoreApiTarget::NewL( *iSelector, *this );
308 iSelector->OpenTargetL();
310 // when priority is not lowered screen updates much more frequently, which
311 // may be undesired, for example in case of openttd's generating world dialog
312 RThread().SetPriority(EPriorityLess);
313 DoMain();
316 void CSDL::AppendWsEvent(const TWsEvent& aEvent)
318 m_eventQueue->Append(aEvent);
321 void CSDL::Resize()
323 if(m_orientationWait)
325 EpocSdlEnv::AllocSurface(m_size, m_mode);
326 m_orientationWait = false;
328 else
330 TSize size = gEpocEnv->iDsa->Window()->Size();
331 SDL_PrivateResize(size.iWidth, size.iHeight);
335 void CSDL::SetOrientation(CAknAppUi::TAppUiOrientation orientation, const TSize& aSize, TDisplayMode aMode)
337 m_orientationWait = true;
338 m_size = aSize;
339 m_mode = aMode;
341 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation));
344 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct)
346 if(aButtonAct != ERemConCoreApiButtonClick)
347 return;
349 TWsEvent event;
350 event.SetType(EEventKey);
351 event.SetTimeNow();
353 switch(aOperationId)
355 case ERemConCoreApiVolumeDown:
356 event.Key()->iScanCode = EStdKeyDecVolume;
357 event.SetType(EEventKeyDown);
358 AppendWsEvent(event);
359 event.SetType(EEventKeyUp);
360 AppendWsEvent(event);
361 break;
363 case ERemConCoreApiVolumeUp:
364 event.Key()->iScanCode = EStdKeyIncVolume;
365 event.SetType(EEventKeyDown);
366 AppendWsEvent(event);
367 event.SetType(EEventKeyUp);
368 AppendWsEvent(event);
369 break;
371 default:
372 break;