sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "wsdynamicresbase.h" sl@0: #include "teflogextensions.h" sl@0: #include "globalsettings.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "regionextend.h" sl@0: sl@0: sl@0: #if defined(__X86GCC__) sl@0: extern "C" TInt atexit(void (*function)(void)) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: #endif sl@0: sl@0: CWsDynamicResBase::CWsDynamicResBase(): sl@0: iUtility(this) sl@0: { sl@0: } sl@0: sl@0: CWsDynamicResBase::~CWsDynamicResBase() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Common set up code for all tests. sl@0: sl@0: Creates the session and window group for further windows, plus a simple white sl@0: background to obscure any unwanted stuff behind the test. Sets up the surface sl@0: update session and surface manager, to work with surfaces. Creates a screen sl@0: device for use in the tests. sl@0: */ sl@0: void CWsDynamicResBase::SetupL() sl@0: { sl@0: SetupL(EFalse); sl@0: } sl@0: void CWsDynamicResBase::SetupL(TBool aUseOtherScreenForInfo) sl@0: { sl@0: CWsDynamicResWinBase::SetupL(aUseOtherScreenForInfo); sl@0: sl@0: sl@0: //clean-up if previous test abended sl@0: if (PostTestCleanupInstance().iSharedUtility) sl@0: { sl@0: //Temp removed - may be causing ONB fails! sl@0: // if (PostTestCleanupInstance().iSharedUtility->DestroyAll()) sl@0: // { sl@0: // INFO_PRINTF1(_L("Destroyed some surfaces from previous test.")); sl@0: // sl@0: // } sl@0: } sl@0: if (!PostTestCleanupInstance().iCleanedUpOnExit) sl@0: PostTestCleanupInstance().iCleanedUpOnExit=EFalse; sl@0: sl@0: if (!GCEIsSupported()) sl@0: { sl@0: INFO_PRINTF1(_L("Some Setup skipped: GCE support is not loaded")); sl@0: return; sl@0: } sl@0: sl@0: TRAPD(err_FailedToCreateSurfaceUtility, iUtility = CSurfaceUtility::NewL( PostTestCleanupInstance().iSharedUtility)); sl@0: ASSERT_EQUALS(err_FailedToCreateSurfaceUtility,KErrNone); sl@0: sl@0: sl@0: } sl@0: sl@0: /** sl@0: Common tear down code for all tests. sl@0: sl@0: Windows, group and session created are closed. Screen device is destroyed. sl@0: Surfaces, manager and update session are closed. sl@0: */ sl@0: void CWsDynamicResBase::TearDownL() sl@0: { sl@0: CWsDynamicResWinBase::TearDownL(); sl@0: delete iUtility(); sl@0: PostTestCleanupInstance().iCleanedUpOnExit=ETrue; sl@0: //Pause(1000); sl@0: } sl@0: /** sl@0: * Note that this is not the ideal mechanism. sl@0: * A derived class may thinks its TearDown is safe to do from delete, but in the class it is derived from it may not be safe sl@0: **/ sl@0: void CWsDynamicResBase::TearDownFromDeleteL() sl@0: { sl@0: CWsDynamicResBase::TearDownL(); sl@0: } sl@0: sl@0: //Allocating an instance of surface utility here means all test code instances will share the same instance of the utility class. sl@0: // Owns the singleton sl@0: /*static*/ const CWsDynamicResBase::TPostTestCleanup& CWsDynamicResBase::PostTestCleanupInstance() sl@0: { sl@0: static sl@0: class RPostTestCleanup:public TPostTestCleanup sl@0: { sl@0: public: sl@0: RPostTestCleanup() sl@0: { sl@0: iSharedUtility=NULL; sl@0: iCleanedUpOnExit=ETrue; sl@0: } sl@0: ~RPostTestCleanup() sl@0: { sl@0: // I want to cleanly release the surface utility, but at this point the threads have already been pulled down! sl@0: // if (iSharedUtility) sl@0: // delete iSharedUtility; sl@0: iSharedUtility=NULL; //avoid phoenix behaviour sl@0: } sl@0: } staticInstance; sl@0: return staticInstance; sl@0: } sl@0: sl@0: void CWsDynamicResBase::TPostTestCleanup::CreateSharedUtilityL()const sl@0: { sl@0: if (iSharedUtility==NULL) sl@0: iSharedUtility=CSurfaceUtility::NewL(); sl@0: } sl@0: sl@0: /** sl@0: Pause for the given number of milliseconds. sl@0: sl@0: @param aMilliseconds Time to wait in milliseconds. sl@0: */ sl@0: void CWsDynamicResBase::Pause(TInt aMilliseconds) sl@0: { sl@0: User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000)); sl@0: } sl@0: sl@0: void CWsDynamicResBase::LargerTestWindow(TInt aPercentOfBack) sl@0: { sl@0: TRect newPos=iTestPos; sl@0: TSize backSize=iTestPos.Size(); sl@0: newPos.Grow((aPercentOfBack-100)*backSize.iWidth/200,(aPercentOfBack-100)*backSize.iHeight/200); sl@0: iCenteredFrontWinRect=newPos; sl@0: if (iTestFront.WsHandle()) sl@0: { sl@0: iTestFront.SetExtent(newPos.iTl,newPos.Size()); sl@0: } sl@0: sl@0: } sl@0: sl@0: sl@0: void CWsDynamicResBase::MakeExtraChildWindowL(const RWindowBase& aFromParent,TRect aChildRect,TRgb aChildColor) sl@0: { sl@0: ASSERT(aFromParent.WsHandle()); sl@0: if (!iTestSecondChild.WsHandle()) sl@0: { sl@0: iTestSecondChild=RWindow(iSession); sl@0: ASSERT_EQUALS_X(iTestSecondChild.Construct(aFromParent, ++iWindowHandle), KErrNone); sl@0: iTestSecondChild.SetRequiredDisplayMode(iDisplayMode); sl@0: } sl@0: iTestSecondChild.SetBackgroundColor(aChildColor); sl@0: iTestSecondChild.SetExtent(aChildRect.iTl,aChildRect.Size()); sl@0: iTestSecondChild.Activate(); sl@0: iTestSecondChild.BeginRedraw(); sl@0: iGc->Activate(iCompare); sl@0: iGc->SetBrushColor(iBlue); sl@0: iGc->Clear(); sl@0: iGc->Deactivate(); sl@0: iTestSecondChild.EndRedraw(); sl@0: iTestSecondChild.SetVisible(ETrue); sl@0: } sl@0: sl@0: CWsDynamicResBase::LoopingGcPtr CWsDynamicResBase::LoopBeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor) sl@0: { sl@0: InvalidateRegion(aRegion,aWin); sl@0: return LoopingGcPtr(aRegion,aWin,aColor,GcForWindow(aWin)); sl@0: } sl@0: sl@0: //This gets called each itteration of the while loop, and is used to step the rectangle count! sl@0: void CWsDynamicResBase::LoopingGcPtr::operator ++() sl@0: { sl@0: iPass++; sl@0: if (iPassDisplayMode(); sl@0: screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode); sl@0: CleanupStack::PushL(screenDevice); sl@0: TAny* p=NULL; sl@0: User::LeaveIfError(screenDevice->GetInterface(KSurfaceInterfaceID, p)); sl@0: MSurfaceId* uiSurface = static_cast(p); sl@0: uiSurface->GetSurface(aSurfaceId); sl@0: CleanupStack::PopAndDestroy(screenDevice); sl@0: } sl@0: sl@0: /** sl@0: Common set up code for creating a surface based window. sl@0: sl@0: Given window and surface objects and a color: creates the window and surface, sl@0: sets the window to a default size (the same as the surface), sets the background sl@0: to the bitwise inverse of the given color, sets the surface as the background, sl@0: fills the surface with the color and completes a redraw to prevent an event. sl@0: sl@0: @param aWindow The window object, connected to a session. sl@0: @param aSurface The surface object, to be initialized. sl@0: @param aColor The color to fill the surface with. sl@0: */ sl@0: void CWsDynamicResBase::CommonSurfaceWindowSetupL(RWindow& aWindow, TSurfaceId& aSurface, const TRgb& aColor) sl@0: { sl@0: TInt err = KErrNone; sl@0: sl@0: TRAP(err, aSurface = iUtility->CreateSurfaceL(TSize(KSurfaceWidth, KSurfaceHeight), sl@0: KSurfaceFormat, KSurfaceWidth * KBytesPerPixel)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to create surface: %d"), err); sl@0: ASSERT_EQUALS_X(aWindow.Construct(iGroup, ++iWindowHandle), KErrNone); sl@0: sl@0: aWindow.SetRequiredDisplayMode(iDisplayMode); sl@0: aWindow.SetExtent(TPoint(0, 0), TSize(KSurfaceWidth, KSurfaceHeight)); sl@0: aWindow.SetBackgroundColor(TRgb(aColor.Value() ^ 0xFFFFFF)); sl@0: sl@0: ASSERT_EQUALS_X(aWindow.SetBackgroundSurface(aSurface), KErrNone); sl@0: sl@0: TRAP(err, iUtility->FillSurfaceL(aSurface, aColor)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to fill surface: %d"), err); sl@0: DrawUIContent(aWindow); sl@0: } sl@0: sl@0: /** sl@0: Common set up code for resizing tests. sl@0: sl@0: Similar to the common surface window code, but filling the surface with a grid sl@0: instead of a solid color. The grid lines are always black. Also, the background sl@0: color is always blue. sl@0: */ sl@0: void CWsDynamicResBase::ResizeTestCommonSetupL(RWindow& aWindow, const TRgb& aColor) sl@0: { sl@0: // Session and group created in SetUpL() sl@0: sl@0: TSurfaceId surface; sl@0: TInt err = KErrNone; sl@0: sl@0: TRAP(err, surface = iUtility->CreateSurfaceL(TSize(KSurfaceWidth, KSurfaceHeight), sl@0: KSurfaceFormat, KSurfaceWidth * KBytesPerPixel)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to create surface: %d"), err); sl@0: sl@0: ASSERT_EQUALS_X(aWindow.Construct(iGroup, ++iWindowHandle), KErrNone); sl@0: sl@0: aWindow.SetRequiredDisplayMode(iDisplayMode); sl@0: aWindow.SetExtent(TPoint(0, 0), TSize(KSurfaceWidth, KSurfaceHeight)); sl@0: aWindow.SetBackgroundColor(iBlue); sl@0: ASSERT_EQUALS_X(aWindow.SetBackgroundSurface(surface), KErrNone); sl@0: sl@0: TRAP(err, iUtility->GridFillSurfaceL(surface, aColor, TRgb(0))); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to grid fill surface: %d"), err); sl@0: DrawUIContent(aWindow); sl@0: } sl@0: sl@0: CFbsBitmap* CWsDynamicResBase::RotateBitmapLC(const CFbsBitmap* aSrcBitmap) sl@0: { sl@0: CFbsBitmap* rv=new CFbsBitmap; sl@0: CleanupStack::PushL(rv); sl@0: TSize srcSize=aSrcBitmap->SizeInPixels(); sl@0: rv->Create(TSize(srcSize.iHeight,srcSize.iWidth),EColor16MA); sl@0: TRgb* linestore=new TRgb[srcSize.iHeight]; sl@0: TPtr8 buff((unsigned char*)linestore,srcSize.iHeight*sizeof(TRgb),srcSize.iHeight*sizeof(TRgb)); sl@0: for (TInt col=0;colSizeInPixels().iWidth;col++) sl@0: { sl@0: for (TInt row=0,brow=srcSize.iHeight-1;rowGetPixel(linestore[row],TPoint(col,brow)); sl@0: } sl@0: rv->SetScanLine(buff,col); sl@0: } sl@0: delete[] linestore; sl@0: return rv; sl@0: } sl@0: sl@0: sl@0: // sl@0: // sl@0: // sl@0: // Pattern checking. Is a given pattern still present? sl@0: // To make life interesting, the pattern is stored backwards! sl@0: // The pattern is fibonnacci sequence masked to byte: sl@0: // 1 2 3 5 8 13 21 34 55 89 144 233 121 sl@0: // 98 219 61 24 85 109 194 47 241 32 17 49 66 sl@0: // 115 181 40 221 5 226 231 201 176 121 41 162 sl@0: // sl@0: // sl@0: void Pattern::Fill(void* aTrg,TInt aOffset,TInt aLength) sl@0: { sl@0: unsigned char* ptr=(unsigned char*)aTrg; sl@0: TInt a=0; sl@0: TInt b=1; sl@0: while (--aLength) sl@0: { sl@0: TInt c=a+b; sl@0: *(ptr+aOffset+aLength)=c&0xff; sl@0: a=b; sl@0: b=c; sl@0: } sl@0: } sl@0: TBool Pattern::Check(void* aTrg,TInt aOffset,TInt aLength) sl@0: { sl@0: unsigned char* ptr=(unsigned char*)aTrg; sl@0: TInt a=0; sl@0: TInt b=1; sl@0: while (--aLength) sl@0: { sl@0: TInt c=a+b; sl@0: if (*(ptr+aOffset+aLength)!=c&0xff) sl@0: return EFalse; sl@0: a=b; sl@0: b=c; sl@0: } sl@0: return ETrue; sl@0: } sl@0: TBool Pattern::CheckVal(void* aTrg,TInt aOffset,TInt aLength,char val) sl@0: { sl@0: unsigned char* ptr=(unsigned char*)aTrg; sl@0: while (--aLength) sl@0: { sl@0: if (*(ptr+aOffset+aLength)!=val&0xff) sl@0: return EFalse; sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: //I have removed these only because they use TRegionExtend sl@0: // sl@0: //TInt CWsDynamicResBase::RegionDiffForUiLayer(TInt aUiLayer) sl@0: // { sl@0: // EWsDebugGetUILayerConfig, //return: TSurfaceConfig //Index UI layer via EWsDebugArgLayerMask sl@0: // EWsDebugGetUILayerBase, //return: TRect[] sl@0: // sl@0: // RRegion layerRegion; sl@0: // TInt layerRegionLen=iSession.DebugInfo(EWsDebugGetUILayerBase,iSession.ObjInd(0,aUiLayer),layerRegion); sl@0: // if (layerRegionLen==KErrCancel) sl@0: // return TRegionExtend::EExact; sl@0: // ASSERT_TRUE(layerRegionLen>=0); sl@0: // TBuf8 configBuf(sizeof(TSurfaceConfiguration)); sl@0: // const TSurfaceConfiguration* config; sl@0: // TInt configLen=iSession.DebugInfo(EWsDebugGetUILayerConfig,iSession.ObjInd(0,aUiLayer),configBuf,config); sl@0: // ASSERT_TRUE(configLen>=0); sl@0: // TRect layerExtent; sl@0: // config->GetExtent(layerExtent); sl@0: // TInt retVal=TRegionExtend::Cast(layerRegion).TestDifference(layerExtent.Size()); sl@0: // layerRegion.Close(); sl@0: // return retVal; sl@0: // } sl@0: //CWsDynamicResBase::FastPathMode CWsDynamicResBase::DeduceUiFastPathMode() sl@0: // { sl@0: // TInt blendedRegionState=RegionDiffForUiLayer(0); sl@0: // TInt opaqueRegionState=RegionDiffForUiLayer(1); sl@0: // if (blendedRegionState&TRegionExtend::ENoIntersect) sl@0: // { sl@0: // if (opaqueRegionState&TRegionExtend::ENoIntersect) sl@0: // { sl@0: // return EFpExternalOpaque; //fullscreen fast-path external surface sl@0: // } sl@0: // else sl@0: // if (opaqueRegionState&TRegionExtend::EAdd) sl@0: // { sl@0: // return (FastPathMode)(EFpUiOpaque|EFpUiRegions); //windowed max-opt no blending sl@0: // } sl@0: // else sl@0: // { sl@0: // return EFpUiOpaque; //full-screen fastpath sl@0: // } sl@0: // } sl@0: // else sl@0: // { sl@0: // if (opaqueRegionState&TRegionExtend::ENoIntersect) sl@0: // { sl@0: // if (blendedRegionState&TRegionExtend::EAdd) sl@0: // { sl@0: // return (FastPathMode)(EFpUiBlended|EFpUiRegions); //windowed max-opt no opaque sl@0: // } sl@0: // else sl@0: // { sl@0: // return (EFpUiBlended); //full-screen blended sl@0: // } sl@0: // } sl@0: // else sl@0: // { sl@0: // if ((blendedRegionState|opaqueRegionState)&TRegionExtend::EAdd) sl@0: // { sl@0: // return (FastPathMode)(EFpUiComplex|EFpUiRegions); //moxed blending, opaque and external max optimisation sl@0: // } sl@0: // else sl@0: // { sl@0: // return EFpUiComplex; //Error! blend and opaque both enabled and full-screen! sl@0: // } sl@0: // } sl@0: // sl@0: // } sl@0: // }