sl@0: // Copyright (c) 2008-2010 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: /** sl@0: @file sl@0: */ sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "teflogextensions.h" sl@0: #include "t_wsdynamicreswinbase.h" sl@0: #include "globalsettings.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #if (!defined(K_DISPLAY_CH_MAJOR_VERSION_NUMBER) && !defined(K_DISPLAY_CH_MINOR_VERSION_NUMBER)) sl@0: #define MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER sl@0: #endif sl@0: sl@0: _LIT(KMonospaceTestFontTypefaceName,"Arial"); sl@0: const TInt KMaxFontSize = 150; sl@0: TBool CWsDynamicResWinBase::iTransparencyEnabled=EFalse; sl@0: sl@0: CWsDynamicResWinBase::CWsDynamicResWinBase(): sl@0: iDoTearDown(EFalse), sl@0: iSession(TGlobalSettings::Instance().iScreen) sl@0: { sl@0: } sl@0: sl@0: void CWsDynamicResWinBase::SetupL() sl@0: { sl@0: SetupL(EFalse); sl@0: } sl@0: CActiveScheduler CWsDynamicResWinBase::iScheduler; sl@0: sl@0: void CWsDynamicResWinBase::SetupL(TBool aUseOtherScreenForInfo) sl@0: { sl@0: if (CActiveScheduler::Current()!=&iScheduler) sl@0: { sl@0: new (&iScheduler) CActiveScheduler; sl@0: CActiveScheduler::Install(&iScheduler); sl@0: } sl@0: iDoTearDown=ETrue; sl@0: iRed.SetInternal(0xFFFF0000); sl@0: iGreen.SetInternal(0xFF00FF00); sl@0: iBlue.SetInternal(0xFF0000FF); sl@0: iCyan.SetInternal(0xFF00FFFF); sl@0: iMagenta.SetInternal(0xFFFF00FF); sl@0: iYellow.SetInternal(0xFFFFFF00); sl@0: iWhite.SetInternal(0xFFFFFFFF); sl@0: iLastGceHoleColor.SetInternal(0); sl@0: TITLE_BACKGROUND=iCyan; sl@0: COMPARE_BACKGROUND=iBlue; sl@0: sl@0: ASSERT_EQUALS_X(iSession.Connect(), KErrNone); sl@0: sl@0: {//Stolen from TAuto CloseAllPanicWindows() sl@0: TInt idFocus = iSession.GetFocusWindowGroup(); sl@0: TWsEvent event; sl@0: event.SetType(EEventKey); //EEventKeyDown sl@0: TKeyEvent *keyEvent = event.Key(); sl@0: keyEvent->iCode = EKeyEscape; sl@0: keyEvent->iScanCode = EStdKeyEscape; sl@0: keyEvent->iModifiers = 0; sl@0: TInt theLimit = 50; sl@0: while(idFocus != NULL && (theLimit-- > 0)) sl@0: { sl@0: iSession.SendEventToAllWindowGroups(event); sl@0: TInt idNewFocus = iSession.GetFocusWindowGroup(); sl@0: if (idNewFocus!=idFocus) sl@0: { sl@0: INFO_PRINTF1(_L("A window was closed [probably a panic box from the previous test].")); sl@0: } sl@0: idFocus=idNewFocus; sl@0: } sl@0: } sl@0: TInt err = KErrNone; sl@0: sl@0: TRAP(err, iScreenDevice = new (ELeave) CWsScreenDevice(iSession)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to create screen device: %d"), err); sl@0: ASSERT_EQUALS_X(iScreenDevice->Construct(TGlobalSettings::Instance().iScreen), KErrNone); sl@0: iDisplayMode = iScreenDevice->DisplayMode(); // Get default display mode sl@0: sl@0: CheckAndConnectScreen(); sl@0: sl@0: TRAP(err, iGc = new (ELeave) CWindowGc(iScreenDevice)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to create graphics context: %d"), err); sl@0: ASSERT_EQUALS_X(iGc->Construct(), KErrNone); sl@0: sl@0: iGroup = RWindowGroup(iSession); sl@0: ASSERT_EQUALS_X(iGroup.Construct(++iWindowHandle,iScreenDevice), KErrNone); sl@0: iGroup.SetOrdinalPositionErr(0, KPasswordWindowGroupPriority - 1); // Added code ---- Fastpath sl@0: iSession.Flush(); sl@0: sl@0: if (aUseOtherScreenForInfo) sl@0: { sl@0: if (iSession.NumberOfScreens()>1) sl@0: { //Create server objects for info windows to appear on alternate screen sl@0: TInt alternateScreenNum=iSession.NumberOfScreens()-1; sl@0: if (TGlobalSettings::Instance().iScreen==alternateScreenNum) sl@0: { //Alternate screen is last screen, or first screen if that is being tested. sl@0: alternateScreenNum=0; sl@0: } sl@0: sl@0: TRAP(err, iInfoScreenDevice = new (ELeave) CWsScreenDevice(iSession)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to create second screen device: %d"), err); sl@0: ASSERT_EQUALS_X(iInfoScreenDevice->Construct(alternateScreenNum), KErrNone); sl@0: sl@0: TRAP(err, iInfoGc = new (ELeave) CWindowGc(iInfoScreenDevice)); sl@0: PRINT_ON_ERROR2_L(err, _L("Failed to create second graphics context: %d"), err); sl@0: ASSERT_EQUALS_X(iInfoGc->Construct(), KErrNone); sl@0: sl@0: iInfoGroupInstance = RWindowGroup(iSession); sl@0: ASSERT_EQUALS_X(iInfoGroupInstance.Construct(++iWindowHandle,iInfoScreenDevice), KErrNone); sl@0: iInfoGroup=&iInfoGroupInstance; sl@0: } sl@0: else sl@0: { //If alternate screen is not available then no text or compare windows should be created! sl@0: iInfoScreenDevice=iScreenDevice; //it is "convenient" for the device to still be good. sl@0: iInfoGc=NULL; sl@0: iInfoGroup=NULL; sl@0: } sl@0: } sl@0: else sl@0: { // sl@0: iInfoScreenDevice=iScreenDevice; sl@0: iInfoGc=iGc; sl@0: iInfoGroup=&iGroup; sl@0: } sl@0: sl@0: if (iInfoGroup && iInfoGc) sl@0: { sl@0: // Add a plain background window to obscure anything else that sl@0: // happens to be behind the test. Setting this window's display mode is also sl@0: // used to set the screen device display mode, and hence the composition sl@0: // mode: alpha or chroma key. sl@0: iBackground = RBlankWindow(iSession); sl@0: ASSERT_EQUALS_X(iBackground.Construct(*iInfoGroup, ++iWindowHandle), KErrNone); sl@0: sl@0: iBackground.SetOrdinalPosition(100); // Behind anything else in this group. sl@0: iBackground.SetColor(TRgb(iWhite)); sl@0: //iBackground.SetExtent(TPoint(-1000,-1000),TSize(3000,3000)); sl@0: iBackground.Activate(); sl@0: iBackground.SetVisible(ETrue); sl@0: } sl@0: iSession.Flush(); sl@0: sl@0: RWindow testTrans(iSession); sl@0: ASSERT_EQUALS_X(testTrans.Construct(iGroup, ++iWindowHandle), KErrNone); sl@0: iTransparencyEnabled=(testTrans.SetTransparencyFactor(iWhite)==KErrNone); sl@0: if (iTransparencyEnabled) sl@0: { sl@0: TTestName testName; sl@0: testName.Format(_L("Screen %i, depth %i: Found Trans Man"), sl@0: TGlobalSettings::Instance().iScreen sl@0: ); sl@0: UpdateTitleWindowL(testName,KMaxInfoLines-1); sl@0: } sl@0: else sl@0: { sl@0: TTestName testName; sl@0: testName.Format(_L("Screen %i, depth %i: No Trans Man"), sl@0: TGlobalSettings::Instance().iScreen sl@0: ); sl@0: UpdateTitleWindowL(testName,KMaxInfoLines-1); sl@0: } sl@0: testTrans.Close(); sl@0: } sl@0: sl@0: sl@0: void CWsDynamicResWinBase::CheckAndConnectScreen() sl@0: { sl@0: if (TGlobalSettings::Instance().iDisconnected) //set from script file to match wsini keyword SIMULATE_STARTUP_DISCONNECTED sl@0: { sl@0: //Verify that the display really is disconnected sl@0: ASSERT_TRUE_X(iScreenDevice != NULL); sl@0: MDisplayControl* interface = static_cast(iScreenDevice->GetInterface(MDisplayControl::ETypeId)); sl@0: ASSERT_TRUE_X(interface != NULL); sl@0: RArray resolutions; sl@0: const TInt err = interface->GetResolutions(resolutions); sl@0: ASSERT_EQUALS_X(err, KErrDisconnected); sl@0: resolutions.Close(); sl@0: } sl@0: sl@0: #ifndef MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER sl@0: //make sure display is attached to screen (only if I/F is available at compile time...) sl@0: TInt displayState = ENormalResolution; sl@0: UserSvr::HalFunction(EHalGroupDisplay | (TGlobalSettings::Instance().iScreen<<16), EDisplayHalSetDisplayState, &displayState, NULL); sl@0: Pause(200); sl@0: #endif sl@0: sl@0: if (TGlobalSettings::Instance().iDisconnected) sl@0: { sl@0: //Verify that the display now is connected sl@0: MDisplayControl* interface = static_cast(iScreenDevice->GetInterface(MDisplayControl::ETypeId)); sl@0: RArray resolutions; sl@0: const TInt err = interface->GetResolutions(resolutions); sl@0: ASSERT_EQUALS_X(err, KErrNone); sl@0: const_cast(TGlobalSettings::Instance()).iDisconnected = EFalse; sl@0: resolutions.Close(); 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 CWsDynamicResWinBase::TearDownL() sl@0: { sl@0: iDoTearDown=EFalse; sl@0: if (iInfoGc!=iGc) sl@0: delete iInfoGc; sl@0: delete iGc; sl@0: if (iInfoScreenDevice!=iScreenDevice) sl@0: delete iInfoScreenDevice; sl@0: delete iScreenDevice; sl@0: sl@0: iGroup.Close(); sl@0: if (iInfoGroupInstance.WsHandle()) sl@0: iInfoGroupInstance.Close(); sl@0: iSession.Flush(); sl@0: iSession.Close(); 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 CWsDynamicResWinBase::TearDownFromDeleteL() sl@0: { sl@0: CWsDynamicResWinBase::TearDownL(); //Explicitly call the non-derived implementation. sl@0: } sl@0: sl@0: CWsDynamicResWinBase::~CWsDynamicResWinBase() sl@0: { sl@0: if (iDoTearDown) sl@0: TearDownFromDeleteL(); //This mechanism is not entirely clean to use. 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 CWsDynamicResWinBase::Pause(TInt aMilliseconds) sl@0: { sl@0: User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000)); sl@0: } sl@0: // This handles any non-member uses of the extended ASSERT_XXX macros sl@0: void TefUnitFailLeaveL() sl@0: { sl@0: sl@0: User::Leave(KErrTEFUnitFail); sl@0: } sl@0: /** sl@0: * side-effect: log the state info just before I leave! sl@0: * Note that this only logs intentional assertion failures. sl@0: * Fails due to panics or throws won't log this info. sl@0: **/ sl@0: void CWsDynamicResWinBase::TefUnitFailLeaveL() sl@0: { sl@0: for (TInt line=0;line aTitle,TRefByValue aDetail) sl@0: { sl@0: iTestName=aTitle; sl@0: iTestInfo[0]=aDetail; sl@0: sl@0: TRect screenSize(iInfoScreenDevice->SizeInPixels()); sl@0: TPoint oneThird(screenSize.iBr.iX/3,screenSize.iBr.iY/3); sl@0: TRect winSize(0,0,oneThird.iX,oneThird.iY); sl@0: sl@0: if (oneThird.iX>oneThird.iY) sl@0: { sl@0: oneThird.iY=0; sl@0: winSize.iBr.iY=screenSize.iBr.iY; sl@0: } sl@0: else sl@0: { sl@0: oneThird.iX=0; sl@0: winSize.iBr.iX=screenSize.iBr.iX; sl@0: } sl@0: winSize.Shrink(5,5); sl@0: sl@0: if (iInfoGc) sl@0: { sl@0: iTitle=RWindow(iSession); sl@0: ASSERT_EQUALS_X(iTitle.Construct(*iInfoGroup, ++iWindowHandle), KErrNone); sl@0: iTitle.SetBackgroundColor(iCyan); sl@0: iTitle.SetExtent(winSize.iTl,winSize.Size()); sl@0: iTitle.Activate(); sl@0: sl@0: RepaintTitleWindowL(); sl@0: iTitle.SetVisible(ETrue); sl@0: sl@0: winSize.Move(oneThird); sl@0: iCompare=RWindow(iSession); sl@0: ASSERT_EQUALS_X(iCompare.Construct(*iInfoGroup, ++iWindowHandle), KErrNone); sl@0: iCompare.SetBackgroundColor(COMPARE_BACKGROUND); sl@0: iCompare.SetExtent(winSize.iTl,winSize.Size()); sl@0: iCompare.Activate(); sl@0: iCompare.BeginRedraw(); sl@0: ActivateWithWipe(iInfoGc,iCompare,COMPARE_BACKGROUND); sl@0: sl@0: TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize); sl@0: CFont *font=NULL; sl@0: ASSERT_EQUALS(iScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone); sl@0: iInfoGc->UseFont(font); sl@0: iInfoGc->DrawText(_L("Simulation"),winSize.Size(),winSize.Size().iHeight-5,iGc->ECenter); sl@0: sl@0: iInfoGc->Deactivate(); sl@0: iCompare.EndRedraw(); sl@0: iCompare.SetVisible(ETrue); sl@0: if (iScreenDevice!=iInfoScreenDevice) sl@0: { sl@0: winSize.Move(-oneThird); sl@0: } sl@0: else sl@0: { sl@0: winSize.Move(oneThird); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: winSize=iScreenDevice->SizeInPixels(); sl@0: } sl@0: sl@0: iTestPos=winSize; sl@0: iTestPointCentre=winSize.Center(); sl@0: iCenteredFrontWinRect=winSize; sl@0: iCenteredFrontWinRect.Shrink(winSize.Size().iWidth/3,winSize.Size().iHeight/3); sl@0: sl@0: } sl@0: /** Makes the compare window larger by covering the test window area as well. sl@0: * Copes with vertically aligned screens, but will be naughty if called multiple times!!! sl@0: * @param aGoLarger If set false, resets the size back. sl@0: **/ sl@0: void CWsDynamicResWinBase::LargerCompareWindow(TBool aGoLarger) sl@0: { sl@0: TPoint currPos=iCompare.AbsPosition(); sl@0: TSize currSize=iCompare.Size(); sl@0: if (currPos.iX>=1; sl@0: } sl@0: else sl@0: { sl@0: if (aGoLarger) sl@0: currSize.iWidth<<=1; sl@0: else sl@0: currSize.iWidth>>=1; sl@0: } sl@0: iCompare.SetSize(currSize); sl@0: } sl@0: sl@0: sl@0: /** Puts a line of text on the LHS window. sl@0: * Repaints the window. The line of text will also be shown in the log if the test fails. sl@0: * @param aDetail The text to display sl@0: * @param aIndex The row number to display at sl@0: **/ sl@0: void CWsDynamicResWinBase::UpdateTitleWindowL(TRefByValue aDetail,TInt aIndex) sl@0: { sl@0: ASSERT(aIndex>=0 && aIndexActivate(aWin); sl@0: aGc->SetBrushColor(aColor); sl@0: aGc->SetBrushStyle(CGraphicsContext::ESolidBrush); sl@0: if (aColor!=TRgb(0,0) && !iTransparencyEnabled) //presume that all redraw-stored windows will draw background sl@0: { sl@0: aGc->Clear(); sl@0: return ETrue; //window was cleared sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: CWindowGc* CWsDynamicResWinBase::GcForWindow(RWindow& aWin) sl@0: { sl@0: if (aWin.WsHandle()==NULL) sl@0: return NULL; //can't activate uninitialised window. sl@0: CWindowGc* gc=iGc; sl@0: if (iGc!=iInfoGc) sl@0: if (&aWin==&iCompare || &aWin==&iTitle) sl@0: gc=iInfoGc; sl@0: else if (iInfoGroup && aWin.WindowGroupId()==iInfoGroup->WindowGroupId()) sl@0: gc=iInfoGc; sl@0: return gc; sl@0: } sl@0: /** Activates an appropriate predefined GC on the specified window and wipes the background if necessary. sl@0: * @param aWin The window to wipe sl@0: * @param aColor The colour to wipe with (if necessary) sl@0: * @return the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live" sl@0: **/ sl@0: CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,RWindow& aWin,TRgb aColor) sl@0: { sl@0: CWindowGc* gc=GcForWindow(aWin); sl@0: iSession.Flush(); sl@0: if (gc==NULL) sl@0: return gc; //can't activate uninitialised window. sl@0: if (aInvalidate) sl@0: aWin.Invalidate(); sl@0: iSession.Flush(); sl@0: aWin.BeginRedraw(); sl@0: iSession.Flush(); sl@0: ActivateWithWipe(gc,aWin,aColor); sl@0: return gc; sl@0: } sl@0: sl@0: /** Activates an appropriate predefined GC on the specified window and wipes the background if necessary. sl@0: * @param aWin The window to wipe sl@0: * @param aColor The colour to wipe with (if necessary) sl@0: * @return the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live" sl@0: **/ sl@0: CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,TRect aRect,RWindow& aWin,TRgb aColor) sl@0: { sl@0: if (aWin.WsHandle()==NULL) sl@0: return NULL; //can't activate uninitialised window. sl@0: if (aInvalidate) sl@0: aWin.Invalidate(aRect); sl@0: aWin.BeginRedraw(aRect); sl@0: CWindowGc* gc=iGc; sl@0: if (iGc!=iInfoGc) sl@0: if (&aWin==&iCompare || &aWin==&iTitle) sl@0: gc=iInfoGc; sl@0: else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId()) sl@0: gc=iInfoGc; sl@0: ActivateWithWipe(gc,aWin,aColor); sl@0: return gc; sl@0: } sl@0: sl@0: TBool CWsDynamicResWinBase::InvalidateRegion(const TRegion& aRegion,RWindow& aWin) sl@0: { sl@0: if (aWin.WsHandle()==NULL) sl@0: return false; //can't activate uninitialised window. sl@0: for (TInt ii = 0; ii < aRegion.Count(); ii++) sl@0: { sl@0: aWin.Invalidate(aRegion[ii]); sl@0: } sl@0: return true; sl@0: } sl@0: sl@0: CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor) sl@0: { sl@0: if (!InvalidateRegion(aRegion,aWin)) sl@0: return NULL; //can't activate uninitialised window. sl@0: sl@0: aWin.BeginRedraw(); sl@0: CWindowGc* gc=iGc; sl@0: if (iGc!=iInfoGc) sl@0: if (&aWin==&iCompare || &aWin==&iTitle) sl@0: gc=iInfoGc; sl@0: else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId()) sl@0: gc=iInfoGc; sl@0: ActivateWithWipe(gc,aWin,aColor); sl@0: return gc; sl@0: } sl@0: sl@0: sl@0: /** Paints the LHS window with rows of text. sl@0: * sl@0: **/ sl@0: void CWsDynamicResWinBase::RepaintTitleWindowL() sl@0: { sl@0: if (iTitle.WsHandle()) sl@0: { sl@0: iTitle.Invalidate(); sl@0: sl@0: iTitle.BeginRedraw(); sl@0: ActivateWithWipe(iInfoGc,iTitle,TITLE_BACKGROUND); sl@0: iInfoGc->SetUnderlineStyle(EUnderlineOn); sl@0: TSize winSize=iTitle.Size(); sl@0: TRect textRect(winSize); sl@0: textRect.iBr.iY/=4; sl@0: TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize); sl@0: CFont *font=NULL; sl@0: ASSERT_EQUALS(iInfoScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone); sl@0: iInfoGc->UseFont(font); sl@0: iInfoGc->DrawText(iTestName,textRect,textRect.iBr.iY/2,iGc->ECenter); sl@0: iInfoGc->SetUnderlineStyle(EUnderlineOff); sl@0: textRect.iTl.iY=textRect.iBr.iY; sl@0: TInt rowHeight=winSize.iHeight*3/(4*(KMaxInfoLines+1)); sl@0: textRect.iBr.iY+=rowHeight; sl@0: for (TInt index=0;indexDrawText(iTestInfo[index],textRect,textRect.Size().iHeight*3/4,iInfoGc->ECenter); sl@0: } sl@0: textRect.Move(0,rowHeight); sl@0: } sl@0: iInfoGc->DiscardFont(); sl@0: iInfoGc->Deactivate(); sl@0: iTitle.EndRedraw(); sl@0: iInfoScreenDevice->ReleaseFont(font); sl@0: sl@0: iSession.Flush(); sl@0: iSession.Finish(); sl@0: } sl@0: } sl@0: sl@0: /** Useful test culled from other GCE test classes. sl@0: * sl@0: * sl@0: * sl@0: **/ sl@0: TBool CWsDynamicResWinBase::DisplayHasAlpha() const sl@0: { sl@0: return (iDisplayMode == EColor16MA || iDisplayMode == EColor16MAP); sl@0: } sl@0: /** Test using an indipendent method that GCE version of WServ is running sl@0: * This method can only be called after the testcase is started sl@0: * sl@0: * @return true if WServ version is GCE technology, false if legacy technology sl@0: **/ sl@0: TBool CWsDynamicResWinBase::GCEIsSupported() const sl@0: { sl@0: CFbsDrawDevice* screenDevice=NULL; sl@0: TDisplayMode displayMode=iScreenDevice->DisplayMode(); sl@0: TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode)); sl@0: TBool rv=EFalse; sl@0: if(err == KErrNone) sl@0: { sl@0: TAny* p=NULL; sl@0: rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone); sl@0: delete screenDevice; sl@0: } sl@0: return rv; sl@0: } sl@0: /** Test using an indipendent method that GCE version of WServ is running sl@0: * This method can be called at any time, even by external code, but creates temporary window session objects sl@0: * sl@0: * @return true if WServ version is GCE technology, false if legacy technology sl@0: **/ sl@0: TBool CWsDynamicResWinBase::GCEIsSupportedStatic() sl@0: { sl@0: CFbsDrawDevice* screenDevice=NULL; sl@0: RWsSession session; sl@0: if (session.Connect()!=KErrNone) sl@0: { sl@0: return EFalse; sl@0: } sl@0: TDisplayMode displayMode=ENone; sl@0: {CWsScreenDevice screen(session); sl@0: if (screen.Construct(TGlobalSettings::Instance().iScreen)!=KErrNone) sl@0: { sl@0: return EFalse; sl@0: } sl@0: displayMode=screen.DisplayMode(); sl@0: }//screen destroyed sl@0: TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode)); sl@0: TBool rv=EFalse; sl@0: if(err == KErrNone) sl@0: { sl@0: TAny* p=NULL; sl@0: rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone); sl@0: delete screenDevice; sl@0: } sl@0: return rv; sl@0: }//session destroyed sl@0: /** sl@0: Use the full-screen background window to select a display mode that doesn't use sl@0: alpha (anything other than EColor16MA or EColor16MAP). Record the mode for use sl@0: in setting all other windows. sl@0: @return ETrue if an appropriate mode was selected, EFalse otherwise. sl@0: */ sl@0: TBool CWsDynamicResWinBase::SelectChromaCompositionMode() sl@0: { sl@0: // Request EColor64K, but as long as the actual mode doesn't use alpha, it sl@0: // doesn't matter too much which one is used. sl@0: if (iInfoGc==iGc) sl@0: { sl@0: iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(EColor64K); sl@0: iSession.Flush(); // Force switching to the display mode. sl@0: } sl@0: return !DisplayHasAlpha(); sl@0: } sl@0: /** Returns the colour used by WServ to paint holes in UI layer to reveal the GCE behind. sl@0: * The window should have a surface attached. sl@0: * If the method is called after the surface has been detached or the window was removed then sl@0: * the previous recorded hole color is returned. sl@0: **/ sl@0: TRgb CWsDynamicResWinBase::GceHoleColor( RWindowBase& aWin)const sl@0: { sl@0: if (aWin.WsHandle()==NULL) sl@0: { sl@0: return iLastGceHoleColor; sl@0: } sl@0: TRgb retVal=aWin.KeyColor(); sl@0: if (retVal==TRgb(0,0)) sl@0: { sl@0: return iLastGceHoleColor; sl@0: } sl@0: else sl@0: { sl@0: iLastGceHoleColor=retVal; sl@0: return retVal; sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Use the full-screen background window to select a display mode that can use sl@0: alpha (either EColor16MA or EColor16MAP). Record the mode for use in setting all sl@0: other windows. sl@0: @return ETrue if an appropriate mode was selected, EFalse otherwise. sl@0: */ sl@0: TBool CWsDynamicResWinBase::SelectAlphaCompositionMode(TDisplayMode aMode) sl@0: { sl@0: // Request EColor16MA, but as long as the actual mode can use alpha, it sl@0: // doesn't matter too much which one is used. sl@0: if (iInfoGc==iGc) sl@0: { sl@0: iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(aMode); sl@0: iSession.Flush(); // Force switching to the display mode. sl@0: } sl@0: return DisplayHasAlpha(); sl@0: } sl@0: sl@0: /** sl@0: * Interesting UI pattern used by other GCE tests. sl@0: * sl@0: * sl@0: **/ sl@0: void CWsDynamicResWinBase::DrawUIContent(RWindow& aWindow) sl@0: { sl@0: aWindow.BeginRedraw(); sl@0: CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc; sl@0: sl@0: gc->Activate(aWindow); sl@0: sl@0: TBool hasAlpha = DisplayHasAlpha(); sl@0: sl@0: // Draw a red-green graduated box in the central portion of the window, sl@0: // with alpha if available. sl@0: TPoint start; sl@0: TPoint end; sl@0: TInt halfW = KSurfaceWidth / 2; sl@0: TInt quarterW = halfW / 2; sl@0: TInt halfH = KSurfaceHeight / 2; sl@0: TInt quarterH = halfH / 2; sl@0: sl@0: // Set constant ordinals for non-alpha case. sl@0: start.iX = quarterW; sl@0: end.iX = quarterW + halfW; sl@0: sl@0: for (TInt yy = 0; yy < halfH; yy++) sl@0: { sl@0: TInt yval = yy * 255 / (halfH - 1); sl@0: start.iY = yy + quarterH; sl@0: end.iY = start.iY; sl@0: sl@0: if (hasAlpha) sl@0: { sl@0: for (TInt xx = 0; xx < halfW; xx++) sl@0: { sl@0: TInt xval = xx * 255 / (halfW - 1); sl@0: start.iX = xx + quarterW; sl@0: end.iX = start.iX + 1; sl@0: gc->SetPenColor(TRgb(yval, 255 - yval, 0, xval)); sl@0: gc->DrawLine(start, end); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: gc->SetPenColor(TRgb(yval, 255 - yval, 0)); sl@0: gc->DrawLine(start, end); sl@0: } sl@0: } sl@0: sl@0: gc->Deactivate(); sl@0: aWindow.EndRedraw(); sl@0: } sl@0: sl@0: /** sl@0: * Causes the given window to be redrawn. sl@0: * Doesn't draw anything except the background wipe, when the transparency manager hasn't sl@0: * sl@0: **/ sl@0: void CWsDynamicResWinBase::DrawPlainUI(RWindow& aWindow,TBool aInvalidate,TRgb aWipeColor) sl@0: { sl@0: if (CWindowGc* gc=BeginActivateWithWipe(aInvalidate,aWindow,aWipeColor)) sl@0: { sl@0: //actually does nothing! sl@0: gc->Deactivate(); sl@0: aWindow.EndRedraw(); sl@0: } sl@0: } sl@0: /** sl@0: * Interesting UI pattern used by other GCE tests. sl@0: * sl@0: * sl@0: **/ sl@0: void CWsDynamicResWinBase::DrawCross(RWindow& aWindow, TRgb aColor, TInt aThickness) sl@0: { sl@0: aWindow.BeginRedraw(); sl@0: CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc; sl@0: gc->Activate(aWindow); sl@0: sl@0: // Draw a red diagonal cross in the window. sl@0: gc->SetPenColor(aColor); sl@0: gc->SetPenSize(TSize(aThickness, aThickness)); sl@0: gc->DrawLine(TPoint(0, 0), TPoint(KSurfaceWidth, KSurfaceHeight)); sl@0: gc->DrawLine(TPoint(KSurfaceWidth, 0), TPoint(0, KSurfaceHeight)); sl@0: sl@0: gc->Deactivate(); sl@0: aWindow.EndRedraw(); sl@0: } sl@0: sl@0: /** sl@0: * Checks the RGB value sl@0: * sl@0: * sl@0: **/ sl@0: void CWsDynamicResWinBase::TestPixelL(TPoint aPt, TRgb aColor, TBool aMatch) sl@0: { sl@0: TRect screenArea(iScreenDevice->SizeInPixels()); sl@0: if (aPt.iX < screenArea.iTl.iX) sl@0: { sl@0: aPt.iX = screenArea.iTl.iX; sl@0: } sl@0: else if (aPt.iX >= screenArea.iBr.iX) sl@0: { sl@0: aPt.iX = screenArea.iBr.iX - 1; sl@0: } sl@0: if (aPt.iY < screenArea.iTl.iY) sl@0: { sl@0: aPt.iY = screenArea.iTl.iY; sl@0: } sl@0: else if (aPt.iY >= screenArea.iBr.iY) sl@0: { sl@0: aPt.iY = screenArea.iBr.iY - 1; sl@0: } sl@0: sl@0: TRgb pixel; sl@0: iScreenDevice->GetPixel(pixel, aPt); sl@0: if (aMatch) sl@0: { sl@0: ASSERT_EQUALS_X(pixel.Internal(), aColor.Internal()); sl@0: } sl@0: else sl@0: { sl@0: ASSERT_NOT_EQUALS_X(pixel.Internal(), aColor.Internal()); sl@0: } sl@0: } sl@0: sl@0: struct CountColour sl@0: { sl@0: TRgb iColor; sl@0: TInt iCount; sl@0: TBool operator < (const CountColour& aRhs)const sl@0: { return iColor.Value()& aColors) sl@0: { sl@0: //I am sure one of the find methods would do this, but life is too short! sl@0: TInt existingIndex; sl@0: for (existingIndex=0;existingIndexDisplayMode(); sl@0: switch (displayMode) sl@0: { sl@0: case EColor4K: sl@0: aInnerColor=aInnerColor.Color4K(aInnerColor.Color4K()); sl@0: aOuterColor=aOuterColor.Color4K(aOuterColor.Color4K()); sl@0: break; sl@0: case EColor64K: sl@0: aInnerColor=aInnerColor.Color64K(aInnerColor.Color64K()); sl@0: aOuterColor=aOuterColor.Color64K(aOuterColor.Color64K()); sl@0: break; sl@0: case EColor16M: sl@0: case EColor16MU: sl@0: case EColor16MA: sl@0: case EColor16MAP: sl@0: break; sl@0: default: sl@0: ASSERT_EQUALS(EColor16MA,displayMode); //Can't quantise color for this display mode! sl@0: } sl@0: sl@0: RArray innerColors; sl@0: innerColors.AppendL(aInnerColor); sl@0: RArray outerColors; sl@0: outerColors.AppendL(aOuterColor); sl@0: TInt cornerSize=aExpectedCornerSize>=0?aExpectedCornerSize:-aExpectedCornerSize; sl@0: //Check outside first! sl@0: TRgb pixelVal; sl@0: for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY-1);pixelPos.iXGetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,outerColors); sl@0: } sl@0: for(TPoint pixelPos(aRect.iTl.iX,aRect.iBr.iY);pixelPos.iX<=aRect.iBr.iX;pixelPos.iX++) sl@0: { sl@0: iScreenDevice->GetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,outerColors); sl@0: } sl@0: for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY);pixelPos.iY<=aRect.iBr.iY;pixelPos.iY++) sl@0: { sl@0: iScreenDevice->GetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,outerColors); sl@0: } sl@0: for(TPoint pixelPos(aRect.iBr.iX,aRect.iTl.iY-1);pixelPos.iYGetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,outerColors); sl@0: } sl@0: TInt cornerStart=1; sl@0: if (cornerSize) sl@0: { sl@0: cornerStart=cornerSize; sl@0: if (aExpectedCornerSize>0) sl@0: { sl@0: iScreenDevice->GetPixel(pixelVal, aRect.iTl); sl@0: LogColorL(pixelVal,outerColors); sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX,aRect.iBr.iY-1)); sl@0: LogColorL(pixelVal,outerColors); sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iTl.iY)); sl@0: LogColorL(pixelVal,outerColors); sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1)); sl@0: LogColorL(pixelVal,outerColors); sl@0: } sl@0: } sl@0: sl@0: //test inside edges (excluding 4 corner pixels - do them seperately) sl@0: for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iTl.iY);pixelPos.iXGetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,innerColors); sl@0: } sl@0: for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iBr.iY-1);pixelPos.iXGetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,innerColors); sl@0: } sl@0: for(TPoint pixelPos(aRect.iTl.iX,aRect.iTl.iY+cornerStart);pixelPos.iYGetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,innerColors); sl@0: } sl@0: for(TPoint pixelPos(aRect.iBr.iX-1,aRect.iTl.iY+cornerStart);pixelPos.iYGetPixel(pixelVal, pixelPos); sl@0: LogColorL(pixelVal,innerColors); sl@0: } sl@0: //the 4 corner cells - not checking the whole corner area... sl@0: if (aExpectedCornerSize>=0) sl@0: { sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iTl.iY+cornerSize)); sl@0: LogColorL(pixelVal,innerColors); sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iBr.iY-1-cornerSize)); sl@0: LogColorL(pixelVal,innerColors); sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iBr.iY-1-cornerSize)); sl@0: LogColorL(pixelVal,innerColors); sl@0: iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iTl.iY+cornerSize)); sl@0: LogColorL(pixelVal,innerColors); sl@0: } sl@0: //OK... that has tested all the pixels, now check the result sl@0: if (innerColors.Count()>aOtherInnerColors+1) sl@0: return EFalse; sl@0: if (outerColors.Count()>aOtherOuterColors+1) sl@0: return EFalse; sl@0: for (TInt index=1;indexendy) sl@0: { //swap // s e sl@0: starty-=endy; // s-e sl@0: endy+=starty; // s sl@0: starty=endy-starty; // e sl@0: } sl@0: if (startx>endx) sl@0: { //swap // s e sl@0: startx-=endx; // s-e sl@0: endx+=startx; // s sl@0: startx=endx-startx; // e sl@0: } sl@0: TSize fullSize=aFullRect.Size(); sl@0: return TRect( aFullRect.iTl.iX+fullSize.iWidth*startx/5, sl@0: aFullRect.iTl.iY+fullSize.iHeight*starty/5, sl@0: aFullRect.iTl.iX+fullSize.iWidth*(endx+1)/5, sl@0: aFullRect.iTl.iY+fullSize.iHeight*(endy+1)/5 sl@0: ); sl@0: }