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 1036