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