Add MMP files to build libOpenVG_sw.lib which uses LINKAS to redirect to libOpenVG.dll (and
the same for libEGL_sw.lib and libOpenVGU_sw.lib).
Only the libEGL_sw.lib redirection isn't activated - this can't happen until there is a merged
libEGL.dll which supports the OpenWF synchronisation and also implements the graphical support functions.
The overall aim is to eliminate the *_sw.dll implementations, at least as a compile-time way of choosing
a software-only implementation.The correct way to choose is to put the right set of libraries into a ROM
with suitable renaming, and in the emulator to use the "switching DLL" technique to pick the right set.
As the Symbian Foundation doesn't have any alternative implementations, we don't need the switching DLLs
and we can build directly to the correct name.
// 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
);
}