3975
|
1 /*
|
|
2 SDL_Main.cpp
|
|
3 Symbian OS services for SDL
|
|
4
|
|
5 Markus Mertama
|
|
6 */
|
|
7
|
|
8
|
|
9 #include "epoc_sdl.h"
|
|
10
|
|
11 #include"sdlepocapi.h"
|
|
12 #include <e32base.h>
|
|
13 #include <estlib.h>
|
|
14 #include <stdio.h>
|
|
15 #include <badesca.h>
|
|
16
|
|
17 #include "vectorbuffer.h"
|
|
18 #include <w32std.h>
|
|
19 #include <aknappui.h>
|
|
20 #include <aknapp.h>
|
|
21 #include "SDL_epocevents_c.h"
|
|
22 #include "SDL_keysym.h"
|
|
23 #include "dsa.h"
|
|
24
|
|
25
|
|
26 #ifdef SYMBIANC
|
|
27 #include <reent.h>
|
|
28 #endif
|
|
29
|
|
30 //Markus Mertama
|
|
31
|
|
32
|
|
33 extern SDLKey* KeyMap();
|
|
34 extern void ResetKeyMap();
|
|
35
|
|
36 class CCurrentAppUi;
|
|
37
|
|
38 //const TUid KSDLUid = { 0xF01F3D69 };
|
|
39
|
|
40 NONSHARABLE_CLASS(EnvUtils)
|
|
41 {
|
|
42 public:
|
|
43 static void DisableKeyBlocking();
|
|
44 static TBool Rendezvous(RThread& aThread, TRequestStatus& aStatus);
|
|
45 };
|
|
46
|
|
47 TInt Panic(TInt aErr, TInt aLine)
|
|
48 {
|
|
49 TBuf<64> b;
|
|
50 b.Format(_L("Main at %d"), aLine);
|
|
51 User::Panic(b, aErr);
|
|
52 return 0;
|
|
53 }
|
|
54
|
|
55
|
|
56 NONSHARABLE_CLASS(CCurrentAppUi) : public CAknAppUi
|
|
57 {
|
|
58 public:
|
|
59 static CCurrentAppUi* Cast(CEikAppUi* aUi);
|
|
60 void DisableKeyBlocking();
|
|
61 };
|
|
62
|
|
63
|
|
64 CCurrentAppUi* CCurrentAppUi::Cast(CEikAppUi* aUi)
|
|
65 {
|
|
66 return static_cast<CCurrentAppUi*>(aUi);
|
|
67 }
|
|
68
|
|
69 void CCurrentAppUi::DisableKeyBlocking()
|
|
70 {
|
|
71 SetKeyBlockMode(ENoKeyBlock);
|
|
72 }
|
|
73
|
|
74
|
|
75 class CEventQueue : public CBase, public MEventQueue
|
|
76 {
|
|
77 public:
|
|
78 static CEventQueue* NewL();
|
|
79 ~CEventQueue();
|
|
80 public:
|
|
81 TInt Append(const TWsEvent& aEvent);
|
|
82 const TWsEvent& Shift();
|
|
83 void Lock();
|
|
84 void Unlock();
|
|
85 TBool HasData();
|
|
86 private:
|
|
87 TVector<TWsEvent, 64> iVector;
|
|
88 RCriticalSection iCS;
|
|
89 };
|
|
90
|
|
91 CEventQueue* CEventQueue::NewL()
|
|
92 {
|
|
93 CEventQueue* q = new (ELeave) CEventQueue();
|
|
94 CleanupStack::PushL(q);
|
|
95 User::LeaveIfError(q->iCS.CreateLocal());
|
|
96 CleanupStack::Pop();
|
|
97 return q;
|
|
98 }
|
|
99
|
|
100 CEventQueue::~CEventQueue()
|
|
101 {
|
|
102 iCS.Close();
|
|
103 }
|
|
104
|
|
105 TInt CEventQueue::Append(const TWsEvent& aEvent)
|
|
106 {
|
|
107 iCS.Wait();
|
|
108 const TInt err = iVector.Append(aEvent);
|
|
109 iCS.Signal();
|
|
110 return err;
|
|
111 }
|
|
112
|
|
113
|
|
114 TBool CEventQueue::HasData()
|
|
115 {
|
|
116 return iVector.Size() > 0;
|
|
117 }
|
|
118
|
|
119
|
|
120 void CEventQueue::Lock()
|
|
121 {
|
|
122 iCS.Wait();
|
|
123 }
|
|
124
|
|
125 void CEventQueue::Unlock()
|
|
126 {
|
|
127 iCS.Signal();
|
|
128 }
|
|
129
|
|
130 const TWsEvent& CEventQueue::Shift()
|
|
131 {
|
|
132 const TWsEvent& event = iVector.Shift();
|
|
133 return event;
|
|
134 }
|
|
135
|
|
136
|
|
137 TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem) :
|
|
138 iOperation(aOperation), iItem(aItem), iThread(RThread().Id())
|
|
139 {
|
|
140 }
|
|
141
|
|
142 class CEikonEnv;
|
|
143 class CSdlAppServ;
|
|
144
|
|
145
|
|
146 NONSHARABLE_CLASS(EpocSdlEnvData)
|
|
147 {
|
|
148 public:
|
|
149 void Free();
|
|
150 CEventQueue* iEventQueue;
|
|
151 TMainFunc iMain;
|
|
152 TInt iEpocEnvFlags;
|
|
153 int iArgc;
|
|
154 char** iArgv;
|
|
155 CDsa* iDsa;
|
|
156 CSdlAppServ* iAppSrv;
|
|
157 TThreadId iId;
|
|
158 CArrayFix<TSdlCleanupItem>* iCleanupItems;
|
|
159 CEikAppUi* iAppUi;
|
|
160 CSDL* iSdl;
|
|
161 };
|
|
162
|
|
163
|
|
164 EpocSdlEnvData* gEpocEnv;
|
|
165
|
|
166 #define MAINFUNC(x) EXPORT_C TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;}
|
|
167
|
|
168 MAINFUNC(1)
|
|
169 MAINFUNC(2)
|
|
170 MAINFUNC(3)
|
|
171 MAINFUNC(4)
|
|
172 MAINFUNC(5)
|
|
173 MAINFUNC(6)
|
|
174
|
|
175 EXPORT_C TMainFunc::TMainFunc()
|
|
176 {
|
|
177 Mem::FillZ(iMainFunc, sizeof(iMainFunc));
|
|
178 }
|
|
179
|
|
180
|
|
181 const void* TMainFunc::operator[](TInt aIndex) const
|
|
182 {
|
|
183 return iMainFunc[aIndex];
|
|
184 }
|
|
185
|
|
186
|
|
187 NONSHARABLE_CLASS(CSdlAppServ) : public CActive
|
|
188 {
|
|
189 public:
|
|
190 enum
|
|
191 {
|
|
192 EAppSrvNoop = CDsa::ELastDsaRequest,
|
|
193 EAppSrvWindowWidth,
|
|
194 EAppSrvWindowHeight,
|
|
195 EAppSrvWindowDisplayMode,
|
|
196 EAppSrvWindowPointerCursorMode,
|
|
197 EAppSrvDsaStatus,
|
|
198 EAppSrvStopThread,
|
|
199 EAppSrvWaitDsa
|
|
200 };
|
|
201 CSdlAppServ();
|
|
202 void ConstructL();
|
|
203 ~CSdlAppServ();
|
|
204 TInt Request(TInt aService);
|
|
205 TInt RequestValue(TInt aService);
|
|
206 void Init();
|
|
207 void PanicMain(TInt aReason);
|
|
208 void PanicMain(const TDesC& aInfo, TInt aReason);
|
|
209 void SetObserver(MSDLObserver* aObserver);
|
|
210 TInt ObserverEvent(TInt aEvent, TInt aParam);
|
|
211 void SetParam(TInt aParam);
|
|
212 void HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread);
|
|
213 MSDLObserver* Observer();
|
|
214 private:
|
|
215 void RunL();
|
|
216 void DoCancel();
|
|
217 private:
|
|
218 const TThreadId iMainId;
|
|
219 RThread iAppThread;
|
|
220 TInt iService;
|
|
221 TInt iReturnValue;
|
|
222 RSemaphore iSema;
|
|
223 MSDLObserver* iObserver;
|
|
224 TRequestStatus* iStatusPtr;
|
|
225 };
|
|
226
|
|
227 CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh), iMainId(RThread().Id())
|
|
228 {
|
|
229 }
|
|
230
|
|
231
|
|
232
|
|
233 MSDLObserver* CSdlAppServ::Observer()
|
|
234 {
|
|
235 return iObserver;
|
|
236 }
|
|
237
|
|
238
|
|
239 void CSdlAppServ::SetObserver(MSDLObserver* aObserver)
|
|
240 {
|
|
241 iObserver = aObserver;
|
|
242 }
|
|
243
|
|
244 TInt CSdlAppServ::ObserverEvent(TInt aEvent, TInt aParam)
|
|
245 {
|
|
246 if(iObserver != NULL)
|
|
247 {
|
|
248 if(RThread().Id() == gEpocEnv->iId)
|
|
249 {
|
|
250 return iObserver->SdlThreadEvent(aEvent, aParam);
|
|
251 }
|
|
252 else if(RThread().Id() == iMainId)
|
|
253 {
|
|
254 return iObserver->SdlEvent(aEvent, aParam);
|
|
255 }
|
|
256 PANIC(KErrNotSupported);
|
|
257 }
|
|
258 return 0;
|
|
259 }
|
|
260
|
|
261 void CSdlAppServ::PanicMain(TInt aReason)
|
|
262 {
|
|
263 iAppThread.Panic(RThread().Name(), aReason);
|
|
264 }
|
|
265
|
|
266 void CSdlAppServ::PanicMain(const TDesC& aInfo, TInt aReason)
|
|
267 {
|
|
268 iAppThread.Panic(aInfo, aReason);
|
|
269 }
|
|
270
|
|
271 void CSdlAppServ::ConstructL()
|
|
272 {
|
|
273 CActiveScheduler::Add(this);
|
|
274 User::LeaveIfError(iSema.CreateLocal(1));
|
|
275 iStatus = KRequestPending;
|
|
276 iStatusPtr = &iStatus;
|
|
277 SetActive();
|
|
278 }
|
|
279
|
|
280 CSdlAppServ::~CSdlAppServ()
|
|
281 {
|
|
282 Cancel();
|
|
283 if(iSema.Handle() != NULL)
|
|
284 iSema.Signal();
|
|
285 iSema.Close();
|
|
286 iAppThread.Close();
|
|
287 }
|
|
288
|
|
289 TInt CSdlAppServ::Request(TInt aService)
|
|
290 {
|
|
291 if(RThread().Id() != iAppThread.Id())
|
|
292 {
|
|
293 iSema.Wait();
|
|
294 iService = aService;
|
|
295 iAppThread.RequestComplete(iStatusPtr, KErrNone);
|
|
296 return KErrNone;
|
|
297 }
|
|
298 return KErrBadHandle;
|
|
299 }
|
|
300
|
|
301 TInt CSdlAppServ::RequestValue(TInt aService)
|
|
302 {
|
|
303 Request(aService);
|
|
304 Request(EAppSrvNoop);
|
|
305 return iReturnValue;
|
|
306 }
|
|
307
|
|
308 void CSdlAppServ::Init()
|
|
309 {
|
|
310 PANIC_IF_ERROR(iAppThread.Open(iMainId));
|
|
311 }
|
|
312
|
|
313 void CSdlAppServ::SetParam(TInt aParam)
|
|
314 {
|
|
315 iReturnValue = aParam;
|
|
316 }
|
|
317
|
|
318 void CSdlAppServ::HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread)
|
|
319 {
|
|
320 if(iObserver != NULL && aMainThread)
|
|
321 {
|
|
322 switch(aService)
|
|
323 {
|
|
324 case MSDLObserver::EEventScreenSizeChanged:
|
|
325 if(aReturnValue == MSDLObserver::EScreenSizeChangedDefaultPalette)
|
|
326 EpocSdlEnv::LockPalette(EFalse);
|
|
327 break;
|
|
328 }
|
|
329 }
|
|
330 if(!aMainThread && aService == MSDLObserver::EEventSuspend)
|
|
331 {
|
|
332 if(iObserver == NULL ||
|
|
333 (gEpocEnv->iDsa->Stopped() && aReturnValue != MSDLObserver::ESuspendNoSuspend))
|
|
334 {
|
|
335 EpocSdlEnv::Suspend();
|
|
336 }
|
|
337 }
|
|
338 }
|
|
339
|
|
340 void CSdlAppServ::RunL()
|
|
341 {
|
|
342 if(iStatus == KErrNone)
|
|
343 {
|
|
344 switch(iService)
|
|
345 {
|
|
346 case CSdlAppServ::EAppSrvWaitDsa:
|
|
347 EpocSdlEnv::SetWaitDsa();
|
|
348 iReturnValue = EpocSdlEnv::IsDsaAvailable();
|
|
349 // }
|
|
350 // gEpocEnv->iDsa->Stop();
|
|
351 // gEpocEnv->iDsa->RestartL();
|
|
352 break;
|
|
353 case CSdlAppServ::EAppSrvStopThread:
|
|
354 gEpocEnv->iDsa->SetSuspend();
|
|
355 break;
|
|
356 case EpocSdlEnv::EDisableKeyBlocking:
|
|
357 EnvUtils::DisableKeyBlocking();
|
|
358 break;
|
|
359
|
|
360 case EAppSrvWindowPointerCursorMode:
|
|
361 iReturnValue = gEpocEnv->iDsa != NULL ?
|
|
362 gEpocEnv->iDsa->Session().PointerCursorMode() : KErrNotReady;
|
|
363 break;
|
|
364 case EAppSrvDsaStatus:
|
|
365 gEpocEnv->iDsa->Stop();
|
|
366 iReturnValue = KErrNone;
|
|
367 break;
|
|
368 case CDsa::ERequestUpdate:
|
|
369 gEpocEnv->iDsa->UnlockHWSurfaceRequestComplete();
|
|
370 break;
|
|
371 case EAppSrvNoop:
|
|
372 break;
|
|
373 case MSDLObserver::EEventResume:
|
|
374 case MSDLObserver::EEventSuspend:
|
|
375 case MSDLObserver::EEventScreenSizeChanged:
|
|
376 case MSDLObserver::EEventWindowReserved:
|
|
377 case MSDLObserver::EEventKeyMapInit:
|
|
378 case MSDLObserver::EEventWindowNotAvailable:
|
|
379 case MSDLObserver::EEventMainExit:
|
|
380 iReturnValue = ObserverEvent(iService, iReturnValue);
|
|
381 HandleObserverValue(iService, iReturnValue, ETrue);
|
|
382 break;
|
|
383 default:
|
|
384 PANIC(KErrNotSupported);
|
|
385 }
|
|
386 iStatus = KRequestPending;
|
|
387 iStatusPtr = &iStatus;
|
|
388 SetActive();
|
|
389 }
|
|
390 iSema.Signal();
|
|
391 }
|
|
392
|
|
393 void CSdlAppServ::DoCancel()
|
|
394 {
|
|
395 iSema.Wait();
|
|
396 TRequestStatus* s = &iStatus;
|
|
397 iAppThread.RequestComplete(s, KErrCancel);
|
|
398 }
|
|
399
|
|
400
|
|
401
|
|
402 MEventQueue& EpocSdlEnv::EventQueue()
|
|
403 {
|
|
404 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
405 return *gEpocEnv->iEventQueue;
|
|
406 }
|
|
407
|
|
408
|
|
409 TBool EpocSdlEnv::Flags(TInt aFlag)
|
|
410 {
|
|
411 const TInt flag = gEpocEnv->iEpocEnvFlags & aFlag;
|
|
412 return flag == aFlag;
|
|
413 }
|
|
414
|
|
415 TInt EpocSdlEnv::Argc()
|
|
416 {
|
|
417 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
418 return gEpocEnv->iArgc;
|
|
419 }
|
|
420
|
|
421
|
|
422 char** EpocSdlEnv::Argv()
|
|
423 {
|
|
424 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
425 return gEpocEnv->iArgv;
|
|
426 }
|
|
427
|
|
428
|
|
429 TBool EpocSdlEnv::IsDsaAvailable()
|
|
430 {
|
|
431 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
432 return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable();
|
|
433 }
|
|
434
|
|
435
|
|
436 void EpocSdlEnv::WaitDsaAvailable()
|
|
437 {
|
|
438 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0);
|
|
439 gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread);
|
|
440 if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
|
|
441 {
|
|
442 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0);
|
|
443 }
|
|
444 }
|
|
445
|
|
446 void EpocSdlEnv::Suspend()
|
|
447 {
|
|
448 if(gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop))
|
|
449 {
|
|
450 // gEpocEnv->iDsa->ReleaseStop();
|
|
451 gEpocEnv->iDsa->SetSuspend();
|
|
452 RThread().Suspend();
|
|
453 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0);
|
|
454 }
|
|
455 }
|
|
456
|
|
457 void EpocSdlEnv::SetWaitDsa()
|
|
458 {
|
|
459 if(!IsDsaAvailable())
|
|
460 {
|
|
461 RThread th;
|
|
462 th.Open(gEpocEnv->iId);
|
|
463 th.Suspend();
|
|
464 th.Close();
|
|
465 gEpocEnv->iDsa->SetSuspend();
|
|
466 }
|
|
467 }
|
|
468
|
|
469 void EpocSdlEnv::Resume()
|
|
470 {
|
|
471 gEpocEnv->iDsa->Resume();
|
|
472 RThread th;
|
|
473 th.Open(gEpocEnv->iId);
|
|
474 th.Resume();
|
|
475 th.Close();
|
|
476
|
|
477 const TInt value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, 0);
|
|
478 gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue);
|
|
479 }
|
|
480
|
|
481
|
|
482 TInt EpocSdlEnv::AllocSwSurface(const TSize& aSize, TDisplayMode aMode)
|
|
483 {
|
|
484 return gEpocEnv->iDsa->AllocSurface(EFalse, aSize, aMode);
|
|
485 }
|
|
486
|
|
487 TInt EpocSdlEnv::AllocHwSurface(const TSize& aSize, TDisplayMode aMode)
|
|
488 {
|
|
489 return gEpocEnv->iDsa->AllocSurface(ETrue, aSize, aMode);
|
|
490 }
|
|
491
|
|
492
|
|
493 void EpocSdlEnv::UnlockHwSurface()
|
|
494 {
|
|
495 gEpocEnv->iDsa->UnlockHwSurface();
|
|
496 }
|
|
497
|
|
498 TUint8* EpocSdlEnv::LockHwSurface()
|
|
499 {
|
|
500 return gEpocEnv->iDsa->LockHwSurface();
|
|
501 }
|
|
502
|
|
503
|
|
504 void EpocSdlEnv::UpdateSwSurface()
|
|
505 {
|
|
506 gEpocEnv->iDsa->UpdateSwSurface();
|
|
507 }
|
|
508
|
|
509 TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect)
|
|
510 {
|
|
511 return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect);
|
|
512 }
|
|
513
|
|
514 void EpocSdlEnv::Request(TInt aService)
|
|
515 {
|
|
516 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
517 gEpocEnv->iAppSrv->Request(aService);
|
|
518 }
|
|
519
|
|
520
|
|
521 TSize EpocSdlEnv::WindowSize(const TSize& aRequestedSize)
|
|
522 {
|
|
523 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
524 if(EpocSdlEnv::Flags(CSDL::EAllowImageResize) && gEpocEnv->iDsa->WindowSize() != aRequestedSize)
|
|
525 {
|
|
526 TRAP_IGNORE(gEpocEnv->iDsa->CreateZoomerL(aRequestedSize));
|
|
527 }
|
|
528 return gEpocEnv->iDsa->WindowSize();
|
|
529 }
|
|
530
|
|
531 TSize EpocSdlEnv::WindowSize()
|
|
532 {
|
|
533 __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady));
|
|
534 return gEpocEnv->iDsa->WindowSize();
|
|
535 }
|
|
536
|
|
537 TDisplayMode EpocSdlEnv::DisplayMode()
|
|
538 {
|
|
539 return gEpocEnv->iDsa->DisplayMode();
|
|
540 }
|
|
541
|
|
542 TPointerCursorMode EpocSdlEnv::PointerMode()
|
|
543 {
|
|
544 return static_cast<TPointerCursorMode>
|
|
545 (gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode));
|
|
546 }
|
|
547
|
|
548 TInt EpocSdlEnv::SetPalette(TInt aFirstcolor, TInt aColorCount, TUint32* aPalette)
|
|
549 {
|
|
550 return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette);
|
|
551 }
|
|
552
|
|
553 void EpocSdlEnv::PanicMain(TInt aErr)
|
|
554 {
|
|
555 gEpocEnv->iAppSrv->PanicMain(aErr);
|
|
556 }
|
|
557
|
|
558
|
|
559 TInt EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem)
|
|
560 {
|
|
561 TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem));
|
|
562 return err;
|
|
563 }
|
|
564
|
|
565 void EpocSdlEnv::RemoveCleanupItem(TAny* aItem)
|
|
566 {
|
|
567 for(TInt i = 0; i < gEpocEnv->iCleanupItems->Count(); i++)
|
|
568 {
|
|
569 if(gEpocEnv->iCleanupItems->At(i).iItem == aItem)
|
|
570 gEpocEnv->iCleanupItems->Delete(i);
|
|
571 }
|
|
572 }
|
|
573
|
|
574 void EpocSdlEnv::CleanupItems()
|
|
575 {
|
|
576 const TThreadId id = RThread().Id();
|
|
577 TInt last = gEpocEnv->iCleanupItems->Count() - 1;
|
|
578 TInt i;
|
|
579 for(i = last; i >= 0 ; i--)
|
|
580 {
|
|
581 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
|
|
582 if(item.iThread == id)
|
|
583 {
|
|
584 item.iThread = TThreadId(0);
|
|
585 item.iOperation(item.iItem);
|
|
586 }
|
|
587 }
|
|
588 last = gEpocEnv->iCleanupItems->Count() - 1;
|
|
589 for(i = last; i >= 0 ; i--)
|
|
590 {
|
|
591 TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i);
|
|
592 if(item.iThread == TThreadId(0))
|
|
593 {
|
|
594 gEpocEnv->iCleanupItems->Delete(i);
|
|
595 }
|
|
596 }
|
|
597 }
|
|
598
|
|
599 void EpocSdlEnv::FreeSurface()
|
|
600 {
|
|
601 Request(CSdlAppServ::EAppSrvDsaStatus);
|
|
602 gEpocEnv->iDsa->Free();
|
|
603 }
|
|
604
|
|
605 void EpocSdlEnv::LockPalette(TBool aLock)
|
|
606 {
|
|
607 gEpocEnv->iDsa->LockPalette(aLock);
|
|
608 }
|
|
609
|
|
610 void EpocSdlEnv::ObserverEvent(TInt aService, TInt aParam)
|
|
611 {
|
|
612 const TBool sdlThread = RThread().Id() == gEpocEnv->iId;
|
|
613 const TInt valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam);
|
|
614 gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread);
|
|
615 if(sdlThread)
|
|
616 {
|
|
617 gEpocEnv->iAppSrv->SetParam(aParam);
|
|
618 const TInt valuet = gEpocEnv->iAppSrv->RequestValue(aService);
|
|
619 gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse);
|
|
620 }
|
|
621 }
|
|
622
|
|
623
|
|
624 TPoint EpocSdlEnv::WindowCoordinates(const TPoint& aPoint)
|
|
625 {
|
|
626 return gEpocEnv->iDsa->WindowCoordinates(aPoint);
|
|
627 }
|
|
628
|
|
629 void EpocSdlEnv::PanicMain(const TDesC& aInfo, TInt aErr)
|
|
630 {
|
|
631 gEpocEnv->iAppSrv->PanicMain(aInfo, aErr);
|
|
632 }
|
|
633 //Dsa is a low priority ao, it has to wait if its pending event, but ws
|
|
634 //event has been prioritized before it
|
|
635 //this is not called from app thread!
|
|
636 void EpocSdlEnv::WaitDeviceChange()
|
|
637 {
|
|
638 LockPalette(ETrue);
|
|
639 gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa);
|
|
640 const TSize sz = WindowSize();
|
|
641 const TInt param = reinterpret_cast<TInt>(&sz);
|
|
642 ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param);
|
|
643
|
|
644 // RThread().Suspend();
|
|
645 }
|
|
646
|
|
647 LOCAL_C TBool CheckSdl()
|
|
648 {
|
|
649 TInt isExit = ETrue;
|
|
650 RThread sdl;
|
|
651 if(sdl.Open(gEpocEnv->iId) == KErrNone)
|
|
652 {
|
|
653 if(sdl.ExitType() == EExitPending)
|
|
654 {
|
|
655 isExit = EFalse;
|
|
656 }
|
|
657 sdl.Close();
|
|
658 }
|
|
659 return isExit;
|
|
660 }
|
|
661
|
|
662 void EpocSdlEnvData::Free()
|
|
663 {
|
|
664 if(RThread().Id() == gEpocEnv->iId)
|
|
665 {
|
|
666 iDsa->Free();
|
|
667 return;
|
|
668 }
|
|
669
|
|
670 __ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrNotReady));
|
|
671
|
|
672 for(TInt i = 0; i < iArgc; i++)
|
|
673 User::Free( iArgv[i] );
|
|
674
|
|
675 User::Free(iArgv);
|
|
676
|
|
677
|
|
678 delete iEventQueue;
|
|
679
|
|
680 if(iDsa != NULL)
|
|
681 iDsa->Free();
|
|
682
|
|
683 delete iDsa;
|
|
684 delete iAppSrv;
|
|
685 }
|
|
686
|
|
687 _LIT(KSDLMain, "SDLMain");
|
|
688
|
|
689 LOCAL_C int MainL()
|
|
690 {
|
|
691 gEpocEnv->iCleanupItems = new (ELeave) CArrayFixFlat<TSdlCleanupItem>(8);
|
|
692
|
|
693 char** envp=0;
|
|
694 /* !! process exits here if there is "exit()" in main! */
|
|
695 int ret = 0;
|
|
696 for(TInt i = 0; i < 6; i++)
|
|
697 {
|
|
698 void* f = (void*) gEpocEnv->iMain[i];
|
|
699 if(f != NULL)
|
|
700 {
|
|
701 switch(i)
|
|
702 {
|
|
703 case 0:
|
|
704 ret = ((mainfunc1)f)();
|
|
705 return ret;
|
|
706 case 3:
|
|
707 ((mainfunc1)f)();
|
|
708 return ret;
|
|
709 case 1:
|
|
710 ret = ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
|
|
711 return ret;
|
|
712 case 4:
|
|
713 ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv());
|
|
714 return ret;
|
|
715 case 2:
|
|
716 ret = ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
|
|
717 return ret;
|
|
718 case 5:
|
|
719 ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp);
|
|
720 return ret;
|
|
721 }
|
|
722 }
|
|
723 }
|
|
724 PANIC(KErrNotFound);
|
|
725 return 0;
|
|
726 }
|
|
727
|
|
728 LOCAL_C TInt DoMain(TAny* /*aParam*/)
|
|
729 {
|
|
730
|
|
731
|
|
732 CTrapCleanup* cleanup = CTrapCleanup::New();
|
|
733
|
|
734 TBool fbsconnected = EFalse;
|
|
735 if(RFbsSession::GetSession() == NULL)
|
|
736 {
|
|
737 PANIC_IF_ERROR(RFbsSession::Connect());
|
|
738 fbsconnected = ETrue;
|
|
739 }
|
|
740
|
|
741 gEpocEnv->iAppSrv->Init();
|
|
742
|
|
743 #ifdef SYMBIANC
|
|
744 // Create stdlib
|
|
745 _REENT;
|
|
746 #endif
|
|
747
|
|
748 // Call stdlib main
|
|
749 int ret = 0;
|
|
750
|
|
751 //completes waiting rendesvous
|
|
752 RThread::Rendezvous(KErrNone);
|
|
753
|
|
754 TRAPD(err, err = MainL());
|
|
755
|
|
756 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventMainExit, err);
|
|
757
|
|
758 // Free resources and return
|
|
759
|
|
760 EpocSdlEnv::CleanupItems();
|
|
761
|
|
762 gEpocEnv->iCleanupItems->Reset();
|
|
763 delete gEpocEnv->iCleanupItems;
|
|
764 gEpocEnv->iCleanupItems = NULL;
|
|
765
|
|
766 gEpocEnv->Free(); //free up in thread resources
|
|
767
|
|
768 #ifdef SYMBIANC
|
|
769 _cleanup(); //this is normally called at exit, I call it here
|
|
770 #endif
|
|
771
|
|
772 if(fbsconnected)
|
|
773 RFbsSession::Disconnect();
|
|
774
|
|
775 #ifdef SYMBIANC
|
|
776 CloseSTDLIB();
|
|
777 #endif
|
|
778
|
|
779 // delete as;
|
|
780 delete cleanup;
|
|
781
|
|
782 return err == KErrNone ? ret : err;;
|
|
783 }
|
|
784
|
|
785
|
|
786
|
|
787 EXPORT_C CSDL::~CSDL()
|
|
788 {
|
|
789 gEpocEnv->Free();
|
|
790 User::Free(gEpocEnv);
|
|
791 gEpocEnv->iSdl = NULL;
|
|
792 }
|
|
793
|
|
794 EXPORT_C CSDL* CSDL::NewL(TInt aFlags)
|
|
795 {
|
|
796 __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists));
|
|
797 gEpocEnv = (EpocSdlEnvData*) User::AllocL(sizeof(EpocSdlEnvData));
|
|
798 Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData));
|
|
799
|
|
800 gEpocEnv->iEpocEnvFlags = aFlags;
|
|
801 gEpocEnv->iEventQueue = CEventQueue::NewL();
|
|
802
|
|
803 gEpocEnv->iAppSrv = new (ELeave) CSdlAppServ();
|
|
804 gEpocEnv->iAppSrv->ConstructL();
|
|
805
|
|
806 CSDL* sdl = new (ELeave) CSDL();
|
|
807
|
|
808 gEpocEnv->iSdl = sdl;
|
|
809
|
|
810 return sdl;
|
|
811 }
|
|
812
|
|
813 /*
|
|
814 EXPORT_C void CSDL::ReInitL(TFlags aFlags)
|
|
815 {
|
|
816 const TFlags prevFlags = gEpocEnv->iEpocEnvFlags;
|
|
817 gEpocEnv->iEpocEnvFlags = aFlags;
|
|
818 TInt err = KErrNone;
|
|
819 if(((prevFlags & EDrawModeDSB) != (aFlags & EDrawModeDSB)) && gEpocEnv->iDsa)
|
|
820 {
|
|
821 delete gEpocEnv->iDsa;
|
|
822 gEpocEnv->iDsa = NULL;
|
|
823 gEpocEnv->iDsa = CDsa::RecreateL(EpocSdlEnv::Flags(CSDL::EDrawModeDSB));
|
|
824 }
|
|
825 }
|
|
826 */
|
|
827
|
|
828
|
|
829 EXPORT_C void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice)
|
|
830 {
|
|
831 if(gEpocEnv->iDsa == NULL)
|
|
832 gEpocEnv->iDsa = CDsa::CreateL(aSession);
|
|
833 gEpocEnv->iDsa->ConstructL(aWindow, aDevice);
|
|
834 }
|
|
835
|
|
836
|
|
837 EXPORT_C TThreadId CSDL::CallMainL(const TMainFunc& aFunc, TRequestStatus* const aStatus, const CDesC8Array* const aArg, TInt aFlags, TInt aStackSize)
|
|
838 {
|
|
839 ASSERT(gEpocEnv != NULL);
|
|
840 gEpocEnv->iMain = aFunc;
|
|
841 const TBool args = aArg != NULL;
|
|
842
|
|
843 gEpocEnv->iArgc = aArg->Count() + 1;
|
|
844 gEpocEnv->iArgv = (char**) User::AllocL(sizeof(char*) * (gEpocEnv->iArgc + 1));
|
|
845
|
|
846 TInt k = 0;
|
|
847 const TFileName processName = RProcess().FileName();
|
|
848 const TInt len = processName.Length();
|
|
849 gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1);
|
|
850 Mem::Copy(gEpocEnv->iArgv[k], processName.Ptr(), len);
|
|
851 gEpocEnv->iArgv[k][len] = 0;
|
|
852
|
|
853 for(TInt i = 0; args && (i < aArg->Count()); i++)
|
|
854 {
|
|
855 k++;
|
|
856 const TInt len = aArg->MdcaPoint(i).Length();
|
|
857 gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1);
|
|
858 Mem::Copy(gEpocEnv->iArgv[k], aArg->MdcaPoint(i).Ptr(), len);
|
|
859 gEpocEnv->iArgv[k][len] = 0;
|
|
860 }
|
|
861
|
|
862 gEpocEnv->iArgv[gEpocEnv->iArgc] = NULL;
|
|
863
|
|
864 RThread thread;
|
|
865 User::LeaveIfError(thread.Create(KSDLMain, DoMain, aStackSize, NULL, NULL));
|
|
866
|
|
867 if(aStatus != NULL)
|
|
868 {
|
|
869 thread.Logon(*aStatus);
|
|
870 }
|
|
871
|
|
872 gEpocEnv->iId = thread.Id();
|
|
873 thread.SetPriority(EPriorityLess);
|
|
874 if((aFlags & CSDL::ERequestResume) == 0)
|
|
875 {
|
|
876 thread.Resume();
|
|
877 }
|
|
878 thread.Close();
|
|
879 return gEpocEnv->iId;
|
|
880 }
|
|
881
|
|
882 EXPORT_C TInt CSDL::AppendWsEvent(const TWsEvent& aEvent)
|
|
883 {
|
|
884 return EpocSdlEnv::EventQueue().Append(aEvent);
|
|
885 }
|
|
886
|
|
887 EXPORT_C void CSDL::SDLPanic(const TDesC& aInfo, TInt aErr)
|
|
888 {
|
|
889 EpocSdlEnv::PanicMain(aInfo, aErr);
|
|
890 }
|
|
891
|
|
892 EXPORT_C TInt CSDL::GetSDLCode(TInt aScanCode)
|
|
893 {
|
|
894 if(aScanCode < 0)
|
|
895 return MAX_SCANCODE;
|
|
896 if(aScanCode >= MAX_SCANCODE)
|
|
897 return -1;
|
|
898 return KeyMap()[aScanCode];
|
|
899 }
|
|
900
|
|
901 EXPORT_C TInt CSDL::SDLCodesCount() const
|
|
902 {
|
|
903 return MAX_SCANCODE;
|
|
904 }
|
|
905
|
|
906 EXPORT_C void CSDL::ResetSDLCodes()
|
|
907 {
|
|
908 ResetKeyMap();
|
|
909 }
|
|
910
|
|
911 EXPORT_C void CSDL::SetOrientation(TOrientationMode aMode)
|
|
912 {
|
|
913 gEpocEnv->iDsa->SetOrientation(aMode);
|
|
914 }
|
|
915
|
|
916 EXPORT_C TInt CSDL::SetSDLCode(TInt aScanCode, TInt aSDLCode)
|
|
917 {
|
|
918 const TInt current = GetSDLCode(aScanCode);
|
|
919 if(aScanCode >= 0 && aScanCode < MAX_SCANCODE)
|
|
920 KeyMap()[aScanCode] = static_cast<SDLKey>(aSDLCode);
|
|
921 return current;
|
|
922 }
|
|
923
|
|
924
|
|
925 EXPORT_C MSDLObserver* CSDL::Observer()
|
|
926 {
|
|
927 return gEpocEnv->iAppSrv->Observer();
|
|
928 }
|
|
929
|
|
930 EXPORT_C void CSDL::SetObserver(MSDLObserver* aObserver)
|
|
931 {
|
|
932 gEpocEnv->iAppSrv->SetObserver(aObserver);
|
|
933 }
|
|
934
|
|
935 EXPORT_C void CSDL::Resume()
|
|
936 {
|
|
937 EpocSdlEnv::Resume();
|
|
938 }
|
|
939
|
|
940 EXPORT_C void CSDL::Suspend()
|
|
941 {
|
|
942 gEpocEnv->iDsa->DoStop();
|
|
943 }
|
|
944
|
|
945 EXPORT_C CSDL::CSDL()
|
|
946 {
|
|
947 }
|
|
948
|
|
949 EXPORT_C void CSDL::DisableKeyBlocking(CAknAppUi& aAppUi) const
|
|
950 {
|
|
951 gEpocEnv->iAppUi = &aAppUi;
|
|
952 EnvUtils::DisableKeyBlocking();
|
|
953 }
|
|
954
|
|
955 EXPORT_C TInt CSDL::SetBlitter(MBlitter* aBlitter)
|
|
956 {
|
|
957 if(gEpocEnv && gEpocEnv->iDsa)
|
|
958 {
|
|
959 gEpocEnv->iDsa->SetBlitter(aBlitter);
|
|
960 return KErrNone;
|
|
961 }
|
|
962 return KErrNotReady;
|
|
963 }
|
|
964
|
|
965
|
|
966 EXPORT_C TInt CSDL::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
|
|
967 {
|
|
968 if(gEpocEnv && gEpocEnv->iDsa)
|
|
969 {
|
|
970 return gEpocEnv->iDsa->AppendOverlay(aOverlay, aPriority);
|
|
971 }
|
|
972 return KErrNotReady;
|
|
973 }
|
|
974
|
|
975 EXPORT_C TInt CSDL::RemoveOverlay(MOverlay& aOverlay)
|
|
976 {
|
|
977 if(gEpocEnv && gEpocEnv->iDsa)
|
|
978 {
|
|
979 return gEpocEnv->iDsa->RemoveOverlay(aOverlay);
|
|
980 }
|
|
981 return KErrNotReady;
|
|
982 }
|
|
983
|
|
984 EXPORT_C TInt CSDL::RedrawRequest()
|
|
985 {
|
|
986 if(gEpocEnv && gEpocEnv->iDsa)
|
|
987 {
|
|
988 return gEpocEnv->iDsa->RedrawRequest();
|
|
989 }
|
|
990 return KErrNotReady;
|
|
991 }
|
|
992
|
|
993 /*
|
|
994 EXPORT_C CSDL* CSDL::Current()
|
|
995 {
|
|
996 return gEpocEnv != NULL ? gEpocEnv->iSdl : NULL;
|
|
997 }
|
|
998
|
|
999
|
|
1000 EXPORT_C TInt CSDL::SetVolume(TInt aVolume)
|
|
1001 {
|
|
1002 return EpocSdlEnv::SetVolume(aVolume);
|
|
1003 }
|
|
1004
|
|
1005 EXPORT_C TInt CSDL::Volume() const
|
|
1006 {
|
|
1007 return EpocSdlEnv::Volume();
|
|
1008 }
|
|
1009
|
|
1010 EXPORT_C TInt CSDL::MaxVolume() const
|
|
1011 {
|
|
1012 return EpocSdlEnv::MaxVolume();
|
|
1013 }
|
|
1014 */
|
|
1015
|
|
1016 void EnvUtils::DisableKeyBlocking()
|
|
1017 {
|
|
1018 if(gEpocEnv->iAppUi != NULL)
|
|
1019 return CCurrentAppUi::Cast(gEpocEnv->iAppUi)->DisableKeyBlocking();
|
|
1020 }
|
|
1021
|
|
1022 TBool EnvUtils::Rendezvous(RThread& aThread, TRequestStatus& aStatus)
|
|
1023 {
|
|
1024 if(gEpocEnv->iId != TThreadId(0) &&
|
|
1025 aThread.Open(gEpocEnv->iId) &&
|
|
1026 aThread.ExitType() == EExitPending)
|
|
1027 {
|
|
1028 aThread.Rendezvous(aStatus);
|
|
1029 return ETrue;
|
|
1030 }
|
|
1031 return EFalse;
|
|
1032 }
|
|
1033
|
|
1034
|
|
1035
|