Remove CBitmapSurface.
[SDL.s60v3.git] / src / main / symbian / SDL_main.cpp
blobf33dbdae208732b53e8d9afd28b500c86d568907
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>
20 #include "ProfileWatcher.h"
22 CSDL* g_SDL = NULL;
24 class CCurrentAppUi;
25 class CEikonEnv;
26 class CSdlAppServ;
27 class CEventQueue;
29 class EpocSdlEnvData
31 public:
32 void Free();
33 void Delete();
34 CDsa* iDsa;
35 CSdlAppServ* iAppSrv;
36 CArrayFix<TSdlCleanupItem>* iCleanupItems;
39 EpocSdlEnvData* gEpocEnv;
41 static void RunSingleThread()
43 if(RThread().RequestCount() > 0)
45 int err;
46 if(CActiveScheduler::RunIfReady(err, CActive::EPriorityIdle))
48 CActiveScheduler::Current()->WaitForAnyRequest();
53 int Panic(int aErr, int aLine)
55 TBuf<64> b;
56 b.Format(_L("Main at %d"), aLine);
57 User::Panic(b, aErr);
58 return 0;
61 bool CEventQueue::HasData()
63 RunSingleThread();
64 return !m_queue.empty();
67 const TWsEvent CEventQueue::Shift()
69 const TWsEvent event = m_queue.front();
70 m_queue.pop();
71 return event;
75 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, void* aItem) :
76 iOperation(aOperation), iItem(aItem), iThread(RThread().Id())
80 ProfileWatcher::ProfileWatcher(MProfileWatcher& observer)
81 : CActive(EPriorityLow)
82 , m_repository(CRepository::NewL(KCRUidProfileEngine))
83 , m_observer(observer)
85 CActiveScheduler::Add(this);
86 m_repository->NotifyRequest(KProEngActiveProfile, iStatus);
87 SetActive();
90 ProfileWatcher::~ProfileWatcher()
92 Cancel();
93 delete m_repository;
96 int ProfileWatcher::GetProfile()
98 int value;
99 m_repository->Get(KProEngActiveProfile, value);
100 return value;
103 void ProfileWatcher::DoCancel()
105 m_repository->NotifyCancel(KProEngActiveProfile);
108 void ProfileWatcher::RunL()
110 int value;
111 if(m_repository->Get(KProEngActiveProfile, value) == KErrNone)
113 m_observer.ProfileChanged(value);
115 m_repository->NotifyRequest(KProEngActiveProfile, iStatus);
116 SetActive();
120 class CSdlAppServ : public CActive
122 public:
123 CSdlAppServ() : CActive(CActive::EPriorityIdle)
125 CActiveScheduler::Add(this);
126 SetActive();
128 ~CSdlAppServ() { Cancel(); }
129 void Request()
131 TRequestStatus* status = &iStatus;
132 User::RequestComplete(status, KErrNone);
135 private:
136 void RunL() {}
137 void DoCancel()
139 TRequestStatus* status = &iStatus;
140 User::RequestComplete(status, KErrCancel);
144 bool EpocSdlEnv::IsDsaAvailable()
146 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
147 return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
150 int EpocSdlEnv::AllocSurface(const TSize& aSize, TDisplayMode aMode)
152 return gEpocEnv->iDsa->AllocSurface(aSize, aMode);
155 void EpocSdlEnv::UnlockHwSurface()
157 gEpocEnv->iDsa->UnlockHwSurface();
160 TUint8* EpocSdlEnv::LockHwSurface()
162 return gEpocEnv->iDsa->LockSurface();
165 void EpocSdlEnv::UpdateSwSurface()
167 gEpocEnv->iDsa->UpdateSwSurface();
170 bool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
172 return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
175 TDisplayMode EpocSdlEnv::DisplayMode()
177 return gEpocEnv->iDsa == NULL ? ENone : gEpocEnv->iDsa->DisplayMode();
180 int EpocSdlEnv::SetPalette(int aFirstcolor, int aColorCount, TUint32* aPalette)
182 return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
185 int EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
187 TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
188 return err;
191 void EpocSdlEnv::RemoveCleanupItem(void* aItem)
193 for(int i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
195 if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
196 gEpocEnv->iCleanupItems->Delete(i);
200 void EpocSdlEnv::CleanupItems()
202 const TThreadId id = RThread().Id();
203 int last = gEpocEnv->iCleanupItems->Count() - 1;
204 int i;
206 for(i = last; i >= 0 ; i--)
208 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
209 if(item.iThread == id)
211 item.iThread = TThreadId(0);
212 item.iOperation(item.iItem);
216 last = gEpocEnv->iCleanupItems->Count() - 1;
218 for(i = last; i >= 0 ; i--)
220 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
221 if(item.iThread == TThreadId(0))
223 gEpocEnv->iCleanupItems->Delete(i);
228 void EpocSdlEnv::FreeSurface()
230 gEpocEnv->iAppSrv->Request();
232 if(gEpocEnv->iDsa != NULL)
234 gEpocEnv->iDsa->Stop();
235 gEpocEnv->iDsa->Free();
239 void EpocSdlEnvData::Free()
241 if(iDsa != NULL)
242 iDsa->Free();
245 void EpocSdlEnvData::Delete()
247 if(iDsa != NULL)
248 iDsa->Free();
250 delete iDsa;
251 delete iAppSrv;
254 static int MainL()
256 gEpocEnv->iCleanupItems = new CArrayFixFlat<TSdlCleanupItem>(8);
258 char** argv = new char*[1];
259 argv[0] = new char[8];
260 strcpy(argv[0], "app.exe");
262 int ret = SDL_main( 1, argv );
264 delete[] argv[0];
265 delete[] argv;
267 return ret;
270 static int DoMain()
272 TRAPD(err, err = MainL());
274 // Free resources and return
275 EpocSdlEnv::CleanupItems();
277 gEpocEnv->iCleanupItems->Reset();
278 delete gEpocEnv->iCleanupItems;
279 gEpocEnv->iCleanupItems = NULL;
281 gEpocEnv->Free(); //free up in thread resources
283 return err;
286 CSDL::CSDL()
287 : m_orientationWait( false )
288 , m_soundPauseReason( SPR_NONE )
289 , m_profileWatcher( new ProfileWatcher(*this) )
291 if(m_profileWatcher->GetProfile() == 1)
293 m_soundPauseReason |= SPR_SILENTPROFILE;
296 __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists));
297 gEpocEnv = new EpocSdlEnvData;
298 Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData));
300 m_eventQueue = new CEventQueue();
302 gEpocEnv->iAppSrv = new CSdlAppServ();
304 g_SDL = this;
307 CSDL::~CSDL()
309 delete m_profileWatcher;
311 g_SDL = NULL;
313 delete m_eventQueue;
315 gEpocEnv->Free();
316 gEpocEnv->Delete();
318 delete gEpocEnv;
319 gEpocEnv = NULL;
322 void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice)
324 if(gEpocEnv->iDsa == NULL)
325 gEpocEnv->iDsa = CDsa::CreateL(aSession);
326 gEpocEnv->iDsa->ConstructL(aWindow, aDevice);
329 int EpocSdlEnv::ApplyGlesDsa()
331 CDsa* dsa = NULL;
332 TRAPD(err, dsa = gEpocEnv->iDsa->CreateGlesDsaL());
333 gEpocEnv->iDsa = dsa;
334 return err;
337 RWindow* EpocSdlEnv::Window()
339 return gEpocEnv->iDsa->Window();
342 void CSDL::CallMainL()
344 ASSERT(gEpocEnv != NULL);
346 // for handling volume up/down keys
347 CRemConInterfaceSelector *iSelector = CRemConInterfaceSelector::NewL();
348 CRemConCoreApiTarget::NewL( *iSelector, *this );
349 iSelector->OpenTargetL();
351 // when priority is not lowered screen updates much more frequently, which
352 // may be undesired, for example in case of openttd's generating world dialog
353 RThread().SetPriority(EPriorityLess);
354 DoMain();
357 void CSDL::AppendWsEvent(const TWsEvent& aEvent)
359 m_eventQueue->Append(aEvent);
362 void CSDL::Resize()
364 if(m_orientationWait)
366 EpocSdlEnv::AllocSurface(m_size, m_mode);
367 m_orientationWait = false;
369 else
371 TSize size = gEpocEnv->iDsa->Window()->Size();
372 SDL_PrivateResize(size.iWidth, size.iHeight);
376 void CSDL::SetOrientation(CAknAppUi::TAppUiOrientation orientation, const TSize& aSize, TDisplayMode aMode)
378 m_orientationWait = true;
379 m_size = aSize;
380 m_mode = aMode;
382 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation));
385 void CSDL::SetFocus(bool focused)
387 if(focused)
389 m_soundPauseReason &= ~SPR_FOCUSLOST;
391 else
393 m_soundPauseReason |= SPR_FOCUSLOST;
397 void CSDL::MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct)
399 if(aButtonAct != ERemConCoreApiButtonClick)
400 return;
402 TWsEvent event;
403 event.SetType(EEventKey);
404 event.SetTimeNow();
406 switch(aOperationId)
408 case ERemConCoreApiVolumeDown:
409 event.Key()->iScanCode = EStdKeyDecVolume;
410 event.SetType(EEventKeyDown);
411 AppendWsEvent(event);
412 event.SetType(EEventKeyUp);
413 AppendWsEvent(event);
414 break;
416 case ERemConCoreApiVolumeUp:
417 event.Key()->iScanCode = EStdKeyIncVolume;
418 event.SetType(EEventKeyDown);
419 AppendWsEvent(event);
420 event.SetType(EEventKeyUp);
421 AppendWsEvent(event);
422 break;
424 default:
425 break;
429 void CSDL::ProfileChanged(int profile)
431 // Check for silent profile
432 if(profile == 1)
434 m_soundPauseReason |= SPR_SILENTPROFILE;
436 else
438 m_soundPauseReason &= ~SPR_SILENTPROFILE;