--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/tauto/AUTO.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,2543 @@
+// Copyright (c) 1995-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:
+// Automatically test the window server
+//
+//
+
+
+#include <e32std.h>
+#include <w32std.h>
+#include <e32svr.h>
+#include <hal.h>
+#include "../tlib/testbase.h"
+#include <stdlib.h>
+#include "AUTO.H"
+
+LOCAL_D const TUint KPanicThreadHeapSize=0x8000;
+
+GLREF_C TInt ProcPriTestOtherProcess(TAny *aScreenNumber);
+GLREF_C TInt ProcToKill(TAny *aScreenNumber);
+GLREF_C TInt ProcDirect(TAny *aScreenNumber);
+GLREF_C TInt ProcMultiDisplay(TAny *aScreenNumber);
+
+_LIT(Priority,"ProcPriTest");
+_LIT(ToKill,"ProcToKill");
+_LIT(Direct,"ProcDirect");
+_LIT(MultiDisplay,"ProcMultiDisplay");
+
+CProcess::TInitialFunction CProcess::iFunctions[]=
+ {
+ TInitialFunction(Priority,ProcPriTestOtherProcess),
+ TInitialFunction(ToKill,ProcToKill),
+ TInitialFunction(Direct,ProcDirect),
+ TInitialFunction(MultiDisplay,ProcMultiDisplay)
+ };
+
+GLDEF_D TestWindow *BaseWin;
+GLDEF_D TestWindow *TestWin;
+GLDEF_D TestClient *TheClient=NULL;
+GLDEF_D CWindowGc *TheGc;
+TInt CTestBase::iMaxGrays=0;
+TInt CTestBase::iScreenNo=0;
+TInt CTestBase::iMaxColors=0;
+TInt CTestBase::iNumberTestsPass=0;
+TInt CTestBase::iNumberTests=0;
+TRect CTestBase::iNormalPointerCursorArea;
+TPartialRedrawType CTestBase::iRedrawType=EPartialRedraw_Unknown;
+TInt CTestBase::iNumberOfGrpWndsOnPrimaryScreenWithZeroPriority = 0;
+TInt CTestDriver::iTestNum=0;
+
+GLDEF_D TInt TheTestResult=ETestPassed; // start with passed to anticipate empty test table
+
+const TInt KBorderWinWidth = 5;
+
+_LIT(Auto,"AUTO ");
+
+TInt64 TTestRects::iSeed=0;
+TRect TTestRects::iList[]={
+// 0-5
+ TRect(2,2,2,2),
+ TRect(2,2,2,2),
+ TRect(2,2,2,2),
+ TRect(2,2,2,2),
+ TRect(2,2,2,2),
+// 5-13
+ TRect(0,0,0,0),
+ TRect(2,0,2,0),
+ TRect(4,0,4,0),
+ TRect(0,2,0,2),
+ TRect(2,2,2,2),
+ TRect(4,2,4,2),
+ TRect(0,4,0,4),
+ TRect(2,4,2,4),
+ TRect(4,4,4,4),
+// 13-22
+ TRect(0,0,1,1),
+ TRect(1,0,3,1),
+ TRect(3,0,4,1),
+ TRect(0,1,1,3),
+ TRect(1,1,3,3),
+ TRect(3,1,4,3),
+ TRect(0,3,1,4),
+ TRect(1,3,3,4),
+ TRect(3,3,4,4),
+// 23-31
+ TRect(0,0,2,0),
+ TRect(2,0,4,0),
+ TRect(0,0,4,0),
+ TRect(0,2,2,2),
+ TRect(2,2,4,2),
+ TRect(0,2,4,2),
+ TRect(0,4,2,4),
+ TRect(2,4,4,4),
+ TRect(0,4,4,4),
+// 32-40
+ TRect(0,0,0,2),
+ TRect(0,2,0,4),
+ TRect(0,0,0,4),
+ TRect(2,0,2,2),
+ TRect(2,2,2,4),
+ TRect(2,0,2,4),
+ TRect(4,0,4,2),
+ TRect(4,2,4,4),
+ TRect(4,0,4,4),
+// 41-44
+ TRect(0,0,2,2),
+ TRect(2,0,4,2),
+ TRect(0,2,2,4),
+ TRect(2,2,4,4),
+// 45-48
+ TRect(0,0,3,3),
+ TRect(1,0,4,3),
+ TRect(0,1,3,4),
+ TRect(1,1,4,4),
+// 49
+ TRect(0,0,4,4),
+// 40-53
+ TRect(1,2,2,2),
+ TRect(2,2,3,2),
+ TRect(2,1,2,2),
+ TRect(2,2,3,2),
+// 54-59
+ TRect(1,2,3,2),
+ TRect(2,1,2,3),
+ TRect(1,1,2,2),
+ TRect(1,2,2,3),
+ TRect(2,2,3,3),
+ TRect(2,1,3,2),
+// 60-63
+ TRect(1,1,3,2),
+ TRect(1,1,2,3),
+ TRect(1,2,3,3),
+ TRect(2,1,3,3)};
+
+#if defined(__WINS__)
+void FindNonMatchingPixelL(TPoint aPt1,TPoint aPt2,TSize aSize)
+// This function is purely for use when debugging to find the first non-matching pixel
+// when a check of two on screen rects has failed.
+ {
+ HBufC8* buf1=HBufC8::NewMaxLC(2*aSize.iWidth);
+ HBufC8* buf2=HBufC8::NewMaxLC(2*aSize.iWidth);
+ TPtr8 ptr1=buf1->Des();
+ TPtr8 ptr2=buf2->Des();
+ TInt row=0;
+ TBool ret = true;
+ for (;row<aSize.iHeight;++row)
+ {
+ TheClient->iScreen->GetScanLine(ptr1,aPt1,aSize.iWidth,EColor64K);
+ TheClient->iScreen->GetScanLine(ptr2,aPt2,aSize.iWidth,EColor64K);
+ if (ptr1!=ptr2)
+ break;
+ ++aPt1.iY;
+ ++aPt2.iY;
+ }
+ TRgb color1,color2;
+ if (row<aSize.iHeight)
+ {
+ for (TInt col=0;col<aSize.iWidth;++col)
+ {
+ TheClient->iScreen->GetPixel(color1,aPt1);
+ TheClient->iScreen->GetPixel(color2,aPt2);
+ if (color1!=color2)
+ { // Break here to find first pixel that didn't match.
+ TBuf<256> buf;
+ _LIT(KFindNonMatchingPixelFmt,"First non matching pixel (%d,%d)");
+ buf.Format(KFindNonMatchingPixelFmt,col,row);
+ TheClient->iWs.LogMessage(buf);
+ break;
+
+ }
+ ++aPt1.iX;
+ ++aPt2.iX;
+ }
+ }
+ CleanupStack::PopAndDestroy(2);
+ }
+
+void FindNonMatchingPixel(TPoint aPt1,TPoint aPt2,TSize aSize)
+ {
+ TRAPD(ignore,FindNonMatchingPixelL(aPt1,aPt2,aSize));
+ }
+#endif
+
+void AutoPanic(TInt aPanic)
+ {
+ User::Panic(_L("Auto"),aPanic);
+ }
+
+void CleanUpWindow(TAny *aWindow)
+ {
+ ((RWindowTreeNode *)aWindow)->Close();
+ }
+
+void PushWindowL(RWindowTreeNode *aWindow)
+ {
+ CleanupStack::PushL(TCleanupItem(CleanUpWindow,aWindow));
+ }
+
+
+TBool OpacityAndAlphaSupportedL()
+ {
+ // If opacity is not implemented, EFalse will be returned
+ if(TransparencySupportedL()!=KErrNone)
+ return EFalse;
+
+ const TRgb KTransparencyColor(0,0,0);
+ RWindow winb(TheClient->iWs);
+ CleanupClosePushL(winb);
+ RWindow wint(TheClient->iWs);
+ CleanupClosePushL(wint);
+ User::LeaveIfError(winb.Construct(*TheClient->iGroup->GroupWin(), ENullWsHandle));
+ User::LeaveIfError(wint.Construct(*TheClient->iGroup->GroupWin(), ENullWsHandle));
+ winb.SetExtent(TPoint(0,0), TSize(50,50));
+ wint.SetExtent(TPoint(0,0), TSize(50,50));
+ winb.SetRequiredDisplayMode(EColor256);
+ wint.SetRequiredDisplayMode(EColor256);
+ wint.SetTransparencyFactor(KTransparencyColor);
+ winb.SetBackgroundColor(TRgb(0,0,255));
+ wint.SetBackgroundColor(TRgb(255,0,0));
+ winb.Activate();
+ wint.Activate();
+
+ wint.BeginRedraw();
+ TheClient->iGc->Activate(wint);
+ TheClient->iGc->SetOpaque(ETrue);
+ TheClient->iGc->SetPenStyle(CGraphicsContext::ENullPen);
+ TheClient->iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ TheClient->iGc->SetBrushColor(TRgb(0,255,0));
+ TheClient->iGc->DrawRect(TRect(TPoint(0,0), TSize(50,50)));
+ TheClient->iGc->SetOpaque(EFalse);
+ TheClient->iGc->Deactivate();
+ wint.EndRedraw();
+ TheClient->Flush();
+
+ // The window should be all green, if opacity is working, or all blue if it isn't.
+ // If the window has any other colour, then something has broken.
+ TRgb color;
+ TheClient->iScreen->GetPixel(color,TPoint(25,25));
+ if (color.Red()>0 || ((color.Green()==0) == (color.Blue()==0)))
+ User::Leave(KErrGeneral);
+ TBool ret=(color.Green()>0);
+
+ CleanupStack::PopAndDestroy(2,&winb); // wint
+ return ret;
+ }
+
+TInt TransparencySupportedL()
+ {
+ // Creates a window and enables alpha transparency, if this feature
+ // is not enabled, KErrNotSupported will be returned
+ RWindow win(TheClient->iWs);
+ User::LeaveIfError(win.Construct(*TheClient->iGroup->GroupWin(), ENullWsHandle));
+ win.SetExtent(TPoint(0,0), TSize(50,50));
+ TInt ret=win.SetTransparencyAlphaChannel();
+ win.Close();
+ return ret;
+ }
+
+TInt CheckScalingSupportedOrNot()
+ {
+ TBool scalingSupported=EFalse;
+ TSizeMode originalModeData=TheClient->iScreen->GetCurrentScreenModeAttributes();
+ TSizeMode tempData=originalModeData;
+ tempData.iScreenScale=TSize(2,2);
+ TheClient->iScreen->SetCurrentScreenModeAttributes(tempData);
+ TSize scale=TheClient->iScreen->GetCurrentScreenModeScale();
+ if (scale.iWidth==2 && scale.iHeight==2)
+ {
+ scalingSupported=ETrue;
+ }
+ TheClient->iScreen->SetCurrentScreenModeAttributes(originalModeData);
+ TheClient->Flush();
+ return scalingSupported;
+ }
+
+TBool CheckNonZeroOriginsSupportedOrNot()
+ {
+ TBool nonZeroOriginsSupported=EFalse;
+ TSizeMode sizeMode1=TheClient->iScreen->GetCurrentScreenModeAttributes();
+ TSizeMode sizeMode2=sizeMode1;
+ sizeMode2.iOrigin=TPoint(30,30);
+ TheClient->iScreen->SetCurrentScreenModeAttributes(sizeMode2);
+ TPoint origin=TheClient->iScreen->GetCurrentScreenModeScaledOrigin();
+ if (origin.iX==30 && origin.iY==30)
+ {
+ nonZeroOriginsSupported=ETrue;
+ }
+ TheClient->iScreen->SetCurrentScreenModeAttributes(sizeMode1);
+ TheClient->Flush();
+ return nonZeroOriginsSupported;
+ }
+
+TPoint PhysicalToLogical(TPoint aPhysicalPtMinusOrigin,TSize aScale)
+ {
+ TPoint logicalPt(aPhysicalPtMinusOrigin);
+ if (aScale.iWidth!=1)
+ {
+ logicalPt.iX=(logicalPt.iX>= 0 ? logicalPt.iX/aScale.iWidth : (logicalPt.iX-(aScale.iWidth-1))/aScale.iWidth);
+ }
+ if (aScale.iHeight!=1)
+ {
+ logicalPt.iY=(logicalPt.iY>= 0 ? logicalPt.iY/aScale.iHeight : (logicalPt.iY-(aScale.iHeight-1))/aScale.iHeight);
+ }
+ return logicalPt;
+ }
+
+//
+// Log window, logs testing //
+//
+
+LogWindow::LogWindow() : CTWin(), iTestTitle(KNullDesC), iSubTitle(KNullDesC), iMessage(KNullDesC)
+ {}
+
+void LogWindow::ConstructL(CTWinBase &parent)
+ {
+ CTWin::ConstructL(parent);
+ iTitleHeight=iFont->HeightInPixels()+4;
+ }
+
+void LogWindow::DrawSubTitle()
+ {
+ iGc->DrawText(iSubTitle, TRect(2,iTitleHeight*2,iSize.iWidth-2,iTitleHeight*3),iFont->AscentInPixels(), CGraphicsContext::ECenter);
+ }
+
+void LogWindow::DrawMessage()
+ {
+ iGc->DrawText(iMessage, TRect(1,iTitleHeight*4,iSize.iWidth-2,iTitleHeight*5),iFont->AscentInPixels(), CGraphicsContext::ECenter);
+ }
+
+void LogWindow::Draw()
+ {
+ iGc->SetPenColor(TRgb::Gray16(8));
+ iGc->SetPenColor(TRgb::Gray16(0));
+ DrawBorder();
+ iGc->DrawLine(TPoint(0,iTitleHeight),TPoint(iSize.iWidth,iTitleHeight));
+ iGc->DrawText(iTestTitle, TPoint((iSize.iWidth-iFont->TextWidthInPixels(iTestTitle))/2,iFont->AscentInPixels()+2));
+ DrawSubTitle();
+ DrawMessage();
+ }
+
+/**
+This function is not used at the moment but I leave it in in case I need it when I improve the logging in
+the log window.
+*/
+void LogWindow::LogTest(const TDesC &aTitle,TInt aNum)
+ {
+ _LIT(Test,"Test %d,%S");
+ iTestTitle.Format(Test,aNum,&aTitle);
+ TLogMessageText buf;
+ _LIT(AutoNewTest,"AUTO New Test: ");
+ buf.Append(AutoNewTest);
+ buf.Append(iTestTitle);
+ TheClient->LogMessage(buf);
+ iMessage.Zero();
+ iWin.Invalidate();
+ }
+
+/**
+This function is not used at the moment but I leave it in in case I need it when I improve the logging in
+the log window.
+*/
+const TDesC& LogWindow::LogSubTest(const TDesC &aTitle,TInt aNum)
+ {
+ _LIT(SubTest,"Sub-Test[%d], %S");
+ iSubTitle.Format(SubTest,aNum,&aTitle);
+ TLogMessageText buf;
+ buf.Append(Auto);
+ buf.Append(iSubTitle);
+ TheClient->LogMessage(buf);
+ iMessage.Zero();
+ iGc->Activate(iWin);
+ iGc->UseFont((CFont *)iFont);
+ iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ DrawSubTitle();
+ DrawMessage();
+ iGc->Deactivate();
+ TheClient->iWs.Flush();
+ return iSubTitle;
+ }
+
+const TDesC& LogWindow::LogMessage(TBool aLog,const TDesC& aText,TInt aNum)
+ {
+ if (aNum!=EDummyValue)
+ {
+ _LIT(StringInt,"%S %d");
+ iMessage.Format(StringInt,&aText,aNum);
+ }
+ else
+ {
+ _LIT(String,"%S");
+ iMessage.Format(String,&aText);
+ }
+ iGc->Activate(iWin);
+ iGc->UseFont((CFont *)iFont);
+ iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ DrawMessage();
+ iGc->Deactivate();
+ if (aLog)
+ {
+ TLogMessageText buf;
+ buf.Append(Auto);
+ buf.Append(iMessage);
+ TheClient->LogMessage(buf);
+ }
+ TheClient->iWs.Flush();
+ return iMessage;
+ }
+
+
+//
+// Test window, simple window used to do test graphics in //
+//
+TestWindow::TestWindow() : CTWin()
+ {
+ }
+
+TestWindow::~TestWindow()
+ {
+ delete iBorderWin;
+ }
+
+void TestWindow::SetUpL(TPoint pos,TSize size,CTWinBase *parent, CWindowGc &aGc)
+ {
+ iBorderWin=new(ELeave) CBorderWindow();
+ iBorderWin->SetUpL(pos,size,parent,aGc);
+ TRAPD(err, CTWin::ConstructL(*iBorderWin));
+ if (err==KErrNone)
+ {
+ SetExt(TPoint(2,2),TSize(size.iWidth-4,size.iHeight-4));
+ if (err==KErrNone)
+ {
+ Activate();
+ AssignGC(aGc);
+ return;
+ }
+ }
+ delete this;
+ User::Leave(err);
+ }
+
+void TestWindow::Draw()
+ {
+ iGc->Clear();
+ }
+
+void TestWindow::ClearWin()
+ {
+ TheGc->Activate(*Win());
+ TheGc->Clear();
+ TheGc->Deactivate();
+ }
+
+void TestWindow::SetBorderExt(TPoint aPos, TSize aSize)
+ {
+ iBorderWin->SetExt(aPos, aSize);
+ }
+
+CBorderWindow* TestWindow::GetBorderWin()
+ {
+ return iBorderWin;
+ }
+//
+CBorderWindow::CBorderWindow() : CTWin()
+ {
+ }
+
+void CBorderWindow::ConstructL(CTWinBase &parent)
+ {
+ CTWin::ConstructL(parent);
+ }
+
+void CBorderWindow::Draw()
+ {
+ iGc->SetBrushColor(TRgb::Gray16(0));
+ iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ iGc->SetPenStyle(CGraphicsContext::ENullPen);
+ iGc->DrawRect(TRect(Size()));
+ }
+
+//
+
+TestWindowGroup::TestWindowGroup(CTClient *aClient) : CTWindowGroup(aClient)
+ {
+ }
+
+void TestWindowGroup::BecomeOwning()
+ {
+ iGroupWin.DefaultOwningWindow();
+ }
+
+void TestWindowGroup::KeyL(const TKeyEvent &aKey,const TTime &aTime)
+ {
+ if (aKey.iModifiers&EModifierFunc)
+ {
+ switch(aKey.iCode)
+ {
+ case 'f':
+ TheClient->Driver()->iTest->TriggerFail();
+ break;
+ }
+ }
+ else if (iCurWin)
+ iCurWin->WinKeyL(aKey,aTime);
+ }
+
+void TestWindowGroup::KeyDownL(const TKeyEvent &aKey,const TTime &aTime)
+ {
+ if (iCurWin)
+ iCurWin->KeyDownL(aKey,aTime);
+ }
+
+void TestWindowGroup::KeyUpL(const TKeyEvent &aKey,const TTime &aTime)
+ {
+ if (iCurWin)
+ iCurWin->KeyUpL(aKey,aTime);
+ }
+
+//
+
+TestClient::TestClient()
+ {}
+
+void TestClient::ConstructL()
+ {
+ CTClient::ConstructL();
+
+ iGroup=new(ELeave) TestWindowGroup(this);
+ iGroup->ConstructL();
+
+ iScreen->GetScreenSizeModeList(&iScreenModes);
+ iScreen->SetScreenMode(iScreenModes[0]);
+ TSize screenSize=iScreen->SizeInPixels();
+
+ TInt winWidth=(screenSize.iWidth/3)-10;
+ TInt winHeight=screenSize.iHeight-10;
+ iStdLogWindow=new(ELeave) LogWindow();
+ iStdLogWindow->SetUpL(TPoint(5,5),TSize(winWidth,winHeight),iGroup,*iGc);
+ BaseWin=new(ELeave) TestWindow();
+ BaseWin->SetUpL(TPoint(screenSize.iWidth/3+5,5),TSize(winWidth,winHeight),iGroup,*iGc);
+ TestWin=new(ELeave) TestWindow();
+ TestWin->SetUpL(TPoint(screenSize.iWidth/3*2+5,5),TSize(winWidth,winHeight),iGroup,*iGc);
+
+ iDriver = CTestDriver::CreateL(iScreenNumber); // virtual constructor
+
+ TheGc=new(ELeave) CWindowGc(iScreen);
+ User::LeaveIfError(TheGc->Construct());
+
+ _LIT(KTestLog,"WSERV Auto Test Log");
+ LogMessage(KTestLog());
+ LogAvailableScreenModeL();
+
+ //This class was designed to be created once and reused by all the tests, now it is created for each test,
+ //this needs to be changed back so tests like the following are only done once.
+ TestWsSetBufferSizeL();
+ TestWsSetMaxBufferSizeL();
+ }
+
+inline CTestDriver* TestClient::Driver()
+ {
+ return iDriver;
+ }
+
+TBool TestClient::WaitForEvent()
+ {
+ if (iEventHandler->iStatus!=KRequestPending)
+ return ETrue;
+ else if (iRedrawEventHandler->iStatus!=KRequestPending)
+ return EFalse;
+ User::WaitForRequest(iEventHandler->iStatus,iRedrawEventHandler->iStatus);
+ TRequestStatus* status=&iEventHandler->iStatus;
+ TBool ret=ETrue;
+ if (iEventHandler->iStatus==KRequestPending)
+ {
+ status=&iRedrawEventHandler->iStatus;
+ ret=EFalse;
+ }
+ TInt reason=status->Int();
+ *status=KRequestPending;
+ User::RequestComplete(status,reason);
+ return ret;
+ }
+
+TBool TestClient::IsEventWaiting()
+ {
+ return (iEventHandler->iStatus!=KRequestPending || iRedrawEventHandler->iStatus!=KRequestPending);
+ }
+
+TestClient::~TestClient()
+ {
+ iScreenModes.Close();
+ delete iDriver;
+ delete TheGc;
+ delete iStdLogWindow;
+ delete BaseWin;
+ delete TestWin;
+ }
+
+void TestClient::LogAvailableScreenModeL()
+ {
+ _LIT(KColorModes,"Color Modes: ");
+ _LIT(KComma,", ");
+ _LIT(KColor,"Color");
+ _LIT(KGrey,"Grey");
+ CArrayFixFlat<TInt>* modeList=new(ELeave) CArrayFixFlat<TInt>(15);
+ iWs.GetColorModeList(modeList);
+ TLogMessageText buf,buf2;
+ buf.Append(KColorModes);
+ TDisplayMode mode;
+ TInt ii=0;
+ FOREVER
+ {
+ mode=STATIC_CAST(TDisplayMode,(*modeList)[ii]);
+ buf.AppendNum((*modeList)[ii]);
+ buf2.Append(TDisplayModeUtils::IsDisplayModeColor(mode)?KColor():KGrey());
+ buf2.AppendNum(TDisplayModeUtils::NumDisplayModeColors(mode));
+ if (mode==EColor16MU)
+ buf2.Append('U');
+ if (++ii==modeList->Count())
+ break;
+ buf.Append(KComma);
+ buf2.Append(KComma);
+ }
+ LogMessage(buf);
+ LogMessage(buf2);
+ delete modeList;
+ }
+
+void TestClient::TestWsSetBufferSizeL()
+ {
+ RWsSession ws;
+ User::LeaveIfError(ws.Connect());
+ ws.SetBufferSizeL(256); // default buffer size 640
+ ws.SetBufferSizeL(0x8000); // 16K is max buffer size
+ ws.SetBufferSizeL(0x4000);
+ ws.Close();
+ }
+
+void TestClient::TestWsSetMaxBufferSizeL()
+ {
+ RWsSession ws;
+ User::LeaveIfError(ws.Connect());
+ // allow buffer to grow bigger than the default 640 bytes
+ const TInt KBigMessageSize = 800;
+ ws.SetMaxBufferSizeL(KBigMessageSize + 8); // big message + command header length
+
+ // send the big message to the wserv
+ TBuf8<KBigMessageSize> bigMessage;
+
+ // LogMessage needs a pointer to a TInt with the message size at the start of the buffer
+ const TInt szLength = sizeof(TInt);
+ TInt length = KBigMessageSize - szLength; // length in Unicode characters
+ bigMessage.Append((TUint8*) &length, szLength);
+
+ _LIT(KLetterA, "a");
+ do
+ {
+ bigMessage.Append((TUint8*) KLetterA().Ptr(), 2);
+ }
+ while (bigMessage.Length() < KBigMessageSize);
+
+ // send to Wserv, note that the message is too long to be logged
+ ws.TestWrite(ws.WsHandle(), EWsClOpLogMessage, bigMessage.Ptr(), KBigMessageSize);
+ ws.Flush();
+
+ ws.Close();
+ }
+
+void TestClient::SetTestClientScreenMode(TInt aMode)
+ {
+ iScreen->SetAppScreenMode(aMode);
+ iScreen->SetScreenMode(aMode);
+ UpdateTestClientScreenMode();
+ }
+
+void TestClient::UpdateTestClientScreenMode()
+ {
+ TSize screenSize=iScreen->SizeInPixels();
+
+ // Sets new positions and dimensions for the three window and their controlling border windows
+
+ if (screenSize.iHeight > screenSize.iWidth) // Portrait mode
+ {
+ TInt winWidth=screenSize.iWidth - (KBorderWinWidth * 2);
+ TInt winHeight=(screenSize.iHeight/3) - (KBorderWinWidth * 2);
+
+ iStdLogWindow->SetExt(TPoint(KBorderWinWidth,KBorderWinWidth),TSize(winWidth,winHeight));
+ BaseWin->SetBorderExt(TPoint(KBorderWinWidth,screenSize.iHeight/3+KBorderWinWidth),TSize(winWidth,winHeight));
+ BaseWin->SetExt(TPoint(2,2),TSize(winWidth - (KBorderWinWidth - 1),winHeight - (KBorderWinWidth - 1)));
+ TestWin->SetBorderExt(TPoint(KBorderWinWidth,screenSize.iHeight/3*2+KBorderWinWidth),TSize(winWidth,winHeight));
+ TestWin->SetExt(TPoint(2,2),TSize(winWidth - (KBorderWinWidth - 1),winHeight - (KBorderWinWidth - 1)));
+ }
+ else // Landscape modes
+ {
+ TInt winWidth=(screenSize.iWidth/3) - (KBorderWinWidth * 2);
+ TInt winHeight=screenSize.iHeight - (KBorderWinWidth * 2);
+
+ iStdLogWindow->SetExt(TPoint(KBorderWinWidth,KBorderWinWidth),TSize(winWidth,winHeight));
+ BaseWin->SetBorderExt(TPoint(screenSize.iWidth/3 + KBorderWinWidth,KBorderWinWidth),TSize(winWidth,winHeight));
+ BaseWin->SetExt(TPoint(2,2),TSize(winWidth - (KBorderWinWidth - 1),winHeight - (KBorderWinWidth - 1)));
+ TestWin->SetBorderExt(TPoint(screenSize.iWidth/3*2+KBorderWinWidth,KBorderWinWidth),TSize(winWidth,winHeight));
+ TestWin->SetExt(TPoint(2,2),TSize(winWidth - (KBorderWinWidth - 1),winHeight - (KBorderWinWidth - 1)));
+ }
+
+ // Remove shading artefacts from window resizing operations
+ TestWin->Win()->Invalidate();
+ TestWin->Win()->BeginRedraw();
+ TestWin->ClearWin();
+ TestWin->Win()->EndRedraw();
+
+ BaseWin->Win()->Invalidate();
+ BaseWin->Win()->BeginRedraw();
+ BaseWin->ClearWin();
+ BaseWin->Win()->EndRedraw();
+
+ TheClient->iWs.Flush();
+ }
+
+
+//
+// TestDriver, drives the test code //
+//
+CTestDriver* CTestDriver::CreateL(TInt aScreenNumber)
+ {
+ CTestDriver* self = NULL;
+ if (aScreenNumber==KDefaultScreen)
+ self = new (ELeave) CTestDriverPrimary(aScreenNumber);
+ else
+ self = new (ELeave) CTestDriverSecondary(aScreenNumber);
+
+ return self;
+ }
+
+CTestDriver::CTestDriver(TInt aScreenNumber)
+ : iScreenNumber(aScreenNumber)
+ {
+ iStartTime.HomeTime();
+ HAL::Get(HALData::EDisplayNumberOfScreens, iNumberOfScreens);
+ }
+
+CTestDriver::~CTestDriver()
+ {
+ }
+
+void CTestDriver::DestroyTest()
+ {
+ delete iTest;
+ iTest=NULL;
+ }
+
+void CTestDriver::TestComplete2()
+ {
+ ++iTestNum;
+ if (iTestNum==iTestSize)
+ {
+ TBuf<64> timeBuf;
+ TTime endTime;
+ endTime.HomeTime();
+ TTimeIntervalMicroSeconds elapseTime=endTime.MicroSecondsFrom(iStartTime);
+ TInt64 elapseTime2=elapseTime.Int64()/1000;
+ TUint diffi = I64LOW(elapseTime2);
+ _LIT(TestPass,"PASSED");
+ _LIT(TestFail,"FAILED");
+ TInt noOfTests=CTestBase::iNumberTests;
+ TInt noOfTestsPass=CTestBase::iNumberTestsPass;
+ _LIT(TimeBuf,"Elapse Time %d:%02d.%03d %S");
+ timeBuf.Format(TimeBuf,diffi/60000,(diffi/1000)%60,diffi%1000000,&(noOfTests==noOfTestsPass?TestPass:TestFail));
+ TBuf<60> testReport;
+ _LIT(Checks,"Checks");
+ _LIT(Fails,"Fails");
+ _LIT(TestReport,"Tests:%d %S:%d");
+ TInt testNumber=(noOfTests==noOfTestsPass? noOfTestsPass : noOfTests-noOfTestsPass);
+ testReport.Format(TestReport,iTestNum,&(noOfTests==noOfTestsPass?Checks():Fails()),testNumber);
+ if (noOfTests!=noOfTestsPass)
+ {
+ _LIT(NumTests,"/%d");
+ testReport.AppendFormat(NumTests,noOfTests);
+ }
+
+ TBuf<60> logTestReport;
+ _LIT(LogReport," %S:%d/%d");
+ logTestReport.Format(LogReport,&Checks,noOfTestsPass,noOfTests);
+ TLogMessageText buf;
+ _LIT(Finished,"AUTO Testing Complete, ");
+ buf.Append(Finished);
+ buf.Append(timeBuf);
+ buf.Append(logTestReport);
+ TheClient->LogMessage(buf);
+
+ TheTestResult = noOfTests==noOfTestsPass? ETestPassed : ETestFailed;
+ DoDisplayDialog(timeBuf,testReport);
+ }
+ }
+
+//
+// Test driver for primary screen (has digitiser/pointer)
+//
+CTestDriverPrimary::CTestDriverPrimary(TInt aScreenNumber) : CTestDriver(aScreenNumber)
+ {
+ TInt i;
+ TInt numOfEntries = 1;
+ for (i=0; i<numOfEntries; ++i)
+ {
+ ++iTestSize;
+ }
+
+ // omit multi display test (last entry in test table)
+ // for single screen platform
+ //
+ if (iNumberOfScreens==1)
+ --iTestSize;
+
+ }
+
+void CTestDriverPrimary::DoDisplayDialog(TDesC& timeBuf,TDesC& testReport)
+ {
+ DisplayDialog(_L("Auto tests complete"),timeBuf, testReport);
+ }
+
+//
+// Test driver for secondary screens
+//
+CTestDriverSecondary::CTestDriverSecondary(TInt aScreenNumber) : CTestDriver(aScreenNumber)
+ {
+ TInt i;
+ TInt numOfEntries = 1;
+ for (i=0; i<numOfEntries; ++i)
+ {
+ ++iTestSize;
+ }
+ }
+
+void CTestDriverSecondary::DoDisplayDialog(TDesC& timeBuf,TDesC& testReport)
+ {
+ if (TheTestResult==ETestFailed)
+ DisplayDialog(iScreenNumber,_L("Auto tests complete"),timeBuf, testReport);
+ }
+
+// TTestRects //
+//
+// This class provides a list of rectangles to test graphics to the test windows
+// The list designed to test all cases total clipping, partial clipping, touching the edges,
+// unclipped etc etc...
+//
+// NOTE:- Quick test version, does not provide a proper list yet
+//
+// For the rectangle list the graphics area is divided into 9 logical areas:-
+// 0:The area above & left of the drawing area
+// 1:The area above but within the left & right limits of the drawing area
+// 2:The area above & right of the drawing area
+// 3:The area left of but within the top & bottom limits of the drawing area
+// 4:The area within the drawing area
+// 5:The area right of but within the top & bottom limits of the drawing area
+// 6:The area below & left of the drawing area
+// 7:The area below but within the left & right limits of the drawing area
+// 8:The area below & right of the drawing area
+//
+// | |
+// 0 | 1 | 2
+// | |
+// -------------------------
+// | |
+// 3 | 4 | 5
+// | |
+// -------------------------
+// | |
+// 6 | 7 | 8
+// | |
+//
+//
+// The full list of rectangles needed to test an official release is as follows:
+//
+// 0-8: A rectangle wholly within each area (0 to 8) without touching the edges (if possible)
+// 9-17: A rectangle wholly within each area and touching all bounding edges
+// 18-26: A rectangle traversing each horizontal pair & triple of areas without touching the boundarys
+// 27-35: A rectangle traversing each vertical pair & triple of areas without touching the boundarys
+// 36-39: A rectangle traversing each 2x2 block of areas without touching the boundarys
+// 40-43: A rectangle traversing each 2x2 block of areas touching each boundary
+// 44: A rectangle that includes all areas
+// 45-48: A rectangle fully enclosed in the central area that touches each edge
+// 49-54: A rectangle fully enclosed in the central area that touches each pair of edges
+// 55-58: A rectangle fully enclosed in the central area that touches each set of three edges
+// 59-67: A Zero size rectangle in each of the 9 areas
+// 68-77: Wide rectangles with heights from 0 to 9 in the central area
+// 78-87: Tall rectangles with widths from 0 to 9 in the central area
+//
+
+void TTestRects::Construct(const RWindow &aWindow)
+ {
+// 59-67
+// Special case, does not use rectangles from here
+// 68-77
+// Special case, does not use rectangles from here
+// 78-87
+// Special case, does not use rectangles from here
+//
+
+ iSize=aWindow.Size();
+/*
+ TInt wid=size.iWidth;
+ TInt hgt=size.iHeight;
+ TInt wid2=wid/2;
+ TInt hgt2=hgt/2;
+ TInt wid3=wid/3;
+ TInt hgt3=hgt/3;
+ TInt wid4=wid/4;
+ TInt hgt4=hgt/4;
+ TInt 2wid=wid*2;
+ TInt 2hgt=hgt*2;
+ TInt 3wid=wid*3;
+ TInt 3hgt=hgt*3;
+// 0-8
+ iList[0]=TRect(-wid,-hgt,-wid2,-hgt2);
+ iList[1]=TRect(wid3,-hgt,wid-wid3,-hgt2);
+ iList[2]=TRect(wid+wid2,-2hgt,2wid,-hgt);
+ iList[3]=TRect(-3wid,hgt3,-wid3,hgt-hgt3);
+ iList[4]=TRect(wid4,hgt3,wid-wid3,hgt-hgt4);
+ iList[5]=TRect(3wid,hgt4,wid+3wid,hgt-hgt4);
+ iList[6]=TRect(-wid3,hgt+hgt4,-wid2,hgt+hgt);
+ iList[7]=TRect(wid2,hgt+hgt4,wid-wid4,hgt+hgt3);
+ iList[8]=TRect(2wid,hgt+hgt4,3wid,hgt+hgt2);
+// 9-17
+ iList[9]=TRect(-wid,-hgt,0,0);
+ iList[10]=TRect(0,-2hgt,wid,0);
+ iList[11]=TRect(wid,-hgt2,wid+wid3,0);
+ iList[12]=TRect(-wid3,0,0,hgt);
+ iList[13]=TRect(0,0,wid,hgt);
+ iList[14]=TRect(wid,0,wid+wid4,hgt);
+ iList[15]=TRect(-wid,hgt,0,hgt+hgt4);
+ iList[16]=TRect(0,hgt,wid,hgt+hgt);
+ iList[17]=TRect(wid,hgt,wid+3wid,hgt+3hgt);
+// 18-26
+ iList[18]=TRect(-wid,-hgt,wid2,hgt3);
+ iList[19]=TRect(wid3,-2hgt,2wid,-hgt3);
+ iList[20]=TRect(-wid,-hgt2,wid3,-hgt3);
+ iList[21]=TRect(-wid3,hgt4,wid2,hgt2);
+ iList[22]=TRect(wid3,hgt3,wid+wid3,hgt-hgt3);
+ iList[23]=TRect(-wid,hgt2,wid+wid4,hgt-hgt3);
+ iList[24]=TRect(-wid,2hgt,wid3,3hgt);
+ iList[25]=TRect(wid-wid4,hgt+hgt3,wid+wid4,2hgt);
+ iList[26]=TRect(-wid4,hgt+hgt4,wid+wid4,3);
+*/
+/*
+ iList[0]=TRect(0,0,size.iWidth,size.iHeight);
+ iList[1]=TRect(-10,-10,size.iWidth/2,size.iHeight/2);
+ iList[2]=TRect(size.iWidth/2,size.iHeight/2,size.iWidth+10,size.iHeight+10);
+ iList[3]=TRect(size.iWidth/4,size.iHeight/4,size.iWidth/2,size.iHeight/2);
+ iList[4]=TRect(-10,size.iHeight/4,size.iWidth+10,size.iHeight/2);
+*/
+ }
+
+TInt TTestRects::Count1() const
+//
+// Count1() provides the simple base set of rectangles
+//
+ {
+ return(2);
+ }
+
+TInt TTestRects::Count2() const
+//
+// Count2() provides an increased set of rectangles for each graphics func to test itself more thoroughly
+//
+ {
+ return(5);
+ }
+
+TInt TTestRects::Count3() const
+//
+// Count3() provides the full set of rects for each graphics func to a quick test on
+//
+ {
+ return(88);
+ }
+
+/** Reset the seed value to 0. */
+void TTestRects::ResetSeed()
+ {
+ iSeed = 0;
+ }
+
+TInt TTestRects::Rnd(TInt aSize)
+//
+// Return a random based around aSize, maybe bigger maybe smaller, who knows?
+//
+ {
+ TInt rnd=Math::Rand(iSeed);
+ TInt result;
+ if (rnd&0x8) // Increase from aSize
+ result=aSize*((rnd&0x7)+1);
+ else // Decrease from aSize
+ result=aSize/((rnd&0x7)+1);
+ return(result);
+ }
+
+TInt TTestRects::RndMax(TInt aSize)
+//
+// Return a random from 0 to aSize inclusive
+//
+ {
+ TInt64 tmpl=Math::Rand(iSeed);
+ TInt tmp = I64INT(tmpl) & 0xFFFF;
+ tmp*=aSize;
+ tmp/=0xFFFF;
+ return(tmp);
+ }
+
+TInt TTestRects::RectCoord(TInt aSection,TInt aSize)
+ {
+ TInt result=0;
+ switch(aSection)
+ {
+ case 0:
+ result=-(1+Rnd(aSize));
+ break;
+ case 1:
+ result=0;
+ break;
+ case 2:
+ result=1+RndMax(aSize-2);
+ break;
+ case 3:
+ result=aSize;
+ break;
+ case 4:
+ result=aSize+1+Rnd(aSize);
+ break;
+ default:
+ AutoPanic(EAutoPanicTestRectsSection);
+ }
+ return(result);
+ }
+
+void TTestRects::RectCoordPair(TInt &aTl, TInt &aBr, TInt aSection, TInt aSize)
+ {
+ do
+ {
+ aTl=RectCoord(aSection,aSize);
+ aBr=RectCoord(aSection,aSize);
+ } while(aTl==aBr && aSize>1);
+ if (aTl>aBr)
+ {
+ TInt tmp=aBr;
+ aBr=aTl;
+ aTl=tmp;
+ }
+ }
+
+TRect TTestRects::operator[](TInt aIndex)
+ {
+ TRect rect;
+ if (aIndex<EMaxRectFromList)
+ {
+ const TRect *pRect=&iList[aIndex];
+ if (pRect->iTl.iX==pRect->iBr.iX)
+ RectCoordPair(rect.iTl.iX,rect.iBr.iX,pRect->iTl.iX,iSize.iWidth);
+ else
+ {
+ rect.iTl.iX=RectCoord(pRect->iTl.iX,iSize.iWidth);
+ rect.iBr.iX=RectCoord(pRect->iBr.iX,iSize.iWidth);
+ }
+ if (pRect->iTl.iY==pRect->iBr.iY)
+ RectCoordPair(rect.iTl.iY,rect.iBr.iY,pRect->iTl.iY,iSize.iHeight);
+ else
+ {
+ rect.iTl.iY=RectCoord(pRect->iTl.iX,iSize.iHeight);
+ rect.iBr.iY=RectCoord(pRect->iBr.iX,iSize.iHeight);
+ }
+ }
+ else if (aIndex<EMaxRectZeroSize)
+ {
+ rect.iTl.iX=RectCoord(((aIndex-EMaxRectFromList)%3)*2,iSize.iWidth);
+ rect.iTl.iY=RectCoord(((aIndex-EMaxRectFromList)/3)*2,iSize.iHeight);
+ rect.iBr=rect.iTl;
+ }
+ else if (aIndex<EMaxRectWide)
+ {
+ rect.iTl.iX=1;
+ rect.iBr.iX=iSize.iWidth-1;
+ rect.iTl.iY=1;
+ rect.iBr.iY=rect.iTl.iY+(aIndex-EMaxRectWide);
+ }
+ else if (aIndex<EMaxRectHigh)
+ {
+ rect.iTl.iX=1;
+ rect.iBr.iX=rect.iTl.iX+(aIndex-EMaxRectHigh);
+ rect.iTl.iY=1;
+ rect.iBr.iY=iSize.iHeight-1;
+ }
+ else
+ AutoPanic(EAutoPanicTestRectsIndex);
+ return(rect);
+ }
+
+
+/*CBitmap*/
+
+CBitmap* CBitmap::NewLC(const TSize& aSizeInPixels,TDisplayMode aDispMode)
+ {
+ return NewLC(0,aSizeInPixels,aDispMode);
+ }
+
+CBitmap* CBitmap::NewL(const TSize& aSizeInPixels,TDisplayMode aDispMode)
+ {
+ CBitmap* self=NewLC(0,aSizeInPixels,aDispMode);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CBitmap* CBitmap::NewL(TInt aHandle)
+ {
+ CBitmap* self=NewLC(aHandle,TSize(),ENone);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CBitmap* CBitmap::NewL(TDesC& /*aFileName*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+CBitmap* CBitmap::NewLC(TInt aHandle,const TSize& aSizeInPixels,TDisplayMode aDispMode)
+ {
+ CBitmap* self=new(ELeave) CBitmap();
+ CleanupStack::PushL(self);
+ self->ConstructL(aHandle, aSizeInPixels, aDispMode);
+ return self;
+ }
+
+void CBitmap::ConstructL(TInt aHandle,const TSize& aSizeInPixels,TDisplayMode aDispMode)
+ {
+ iBitmap=new(ELeave) CFbsBitmap();
+ if (aHandle==0)
+ {
+ User::LeaveIfError(iBitmap->Create(aSizeInPixels,aDispMode));
+ }
+ else
+ {
+ User::LeaveIfError(iBitmap->Duplicate(aHandle));
+ }
+ iDevice=CFbsBitmapDevice::NewL(iBitmap);
+ User::LeaveIfError(iDevice->CreateContext(iGc));
+ }
+
+CBitmap::~CBitmap()
+ {
+ delete iGc;
+ delete iDevice;
+ delete iBitmap;
+ }
+
+
+// CTestBase //
+
+CTestBase::CTestBase(const TDesC& aTitle,CTWsGraphicsBase* aTestBase)
+ {
+ iTestBase=aTestBase;
+ iTitle.Copy(aTitle);
+
+ iScreenNo = iTestBase->GetScreenFromIni();
+
+ TheClient=new(ELeave) TestClient();
+
+ if (CTestBase::iScreenNo == 1)
+ {
+ TheClient->SetScreenNumber(1);
+ iScreenNumber = 1;
+ }
+ else
+ {
+ TheClient->SetScreenNumber(0);
+ iScreenNumber = 0;
+ }
+
+ if (iScreenNumber == 1)
+ {
+ iMinWin = new(ELeave) CMinWin(iScreenNumber);
+ iMinWin->ConstructL();
+ }
+
+ iTestNum=CTestDriver::iTestNum;
+ TheClient->ConstructL();
+ TheClient->StdLogWindow().LogTest(iTitle,iTestNum);
+ iDriver=TheClient->Driver();
+
+ if (CTestBase::iScreenNo == 1)
+ {
+ TheClient->iWs.SetFocusScreen(1);
+ }
+ else
+ {
+ TheClient->iWs.SetFocusScreen(0);
+ }
+
+ iTestRects.Construct(*BaseWin->Win());
+ iStdTestWindowSize=BaseWin->Size();
+ iRedrawType=EPartialRedraw_Unknown; // Reset between tests
+ if (iMaxGrays+iMaxColors==0)
+ {
+ TheClient->iWs.GetDefModeMaxNumColors(iMaxColors,iMaxGrays);
+ iNormalPointerCursorArea=TheClient->iWs.PointerCursorArea();
+ }
+ }
+
+CTestBase::~CTestBase()
+ {
+ delete iMinWin;
+ delete TheClient;
+ }
+
+void CTestBase::CloseAllPanicWindows()
+ {
+ TInt idFocus = TheClient->iWs.GetFocusWindowGroup();
+ TWsEvent event;
+ event.SetType(EEventKey);
+ TKeyEvent *keyEvent = event.Key();
+ keyEvent->iCode = EKeyEscape;
+ keyEvent->iScanCode = EStdKeyEscape;
+ keyEvent->iModifiers = 0;
+ TInt theLimit = 50;
+ while(idFocus != NULL && (theLimit-- > 0))
+ {
+ TheClient->iWs.SendEventToAllWindowGroups(event);
+ idFocus = TheClient->iWs.GetFocusWindowGroup();
+ }
+ }
+
+/**
+Returns the size of the standard test windows.
+@see iStdTestWindowSize
+*/
+const TSize& CTestBase::StdTestWindowSize()
+ {
+ return iStdTestWindowSize;
+ }
+
+/** Returns the number of greys available in the richest grey mode */
+TInt CTestBase::MaxGrays() const
+ {
+ return iMaxGrays;
+ }
+
+/** Returns the number of colours available in the richest supported colour mode. */
+TInt CTestBase::MaxColors() const
+ {
+ return iMaxColors;
+ }
+
+void CTestBase::TriggerFail()
+ {
+ iFail=ETrue;
+ }
+
+void CTestBase::LogLeave(TInt aErr)
+ {
+ TLogMessageText buf;
+ _LIT(Leave,"AUTO Left with error code %d in ");
+ buf.AppendFormat(Leave,aErr);
+ buf.Append(iSubTitle);
+ TheClient->LogMessage(buf);
+ }
+
+void CTestBase::LogSubTest(const TDesC &aSubTitle)
+ {
+ Driver()->iSubTestNum++;
+ iSubTitle=aSubTitle;
+ iTestBase->Logger().Write(TheClient->StdLogWindow().LogSubTest(aSubTitle,iState));
+ }
+
+void CTestBase::LogMessage(TInt aValue)
+ {
+ _LIT(WinID,"Win Id:");
+ TheClient->StdLogWindow().LogMessage(EFalse,WinID,aValue);
+ }
+
+void CTestBase::LogSubState(TInt aSubState)
+ {
+ _LIT(SubTest,"SubState");
+ iTestBase->Logger().Write(TheClient->StdLogWindow().LogMessage(ETrue,SubTest,aSubState));
+ }
+
+TBool DoCheckRectRWin(RWindowBase &aWin1,RWindowBase &aWin2,const TRect &aRect)
+ {
+ TRect rect1(aRect);
+ TRect rect2(aRect);
+ rect1.Move(aWin1.InquireOffset(*TheClient->iGroup->WinTreeNode()));
+ rect2.Move(aWin2.InquireOffset(*TheClient->iGroup->WinTreeNode()));
+ TBool match=TheClient->iScreen->RectCompare(rect1,rect2);
+#if defined(__WINS__)
+ if (!match)
+ FindNonMatchingPixel(rect1.iTl,rect2.iTl,aRect.Size());
+#endif
+ return match;
+ }
+
+TBool DoCheckRectRWin(RWindowBase &aWin1,RWindowBase &aWin2,const TRect &aRect, TUint aFlags)
+ {
+ TRect rect1(aRect);
+ TRect rect2(aRect);
+ rect1.Move(aWin1.InquireOffset(*TheClient->iGroup->WinTreeNode()));
+ rect2.Move(aWin2.InquireOffset(*TheClient->iGroup->WinTreeNode()));
+ TBool match=TheClient->iScreen->RectCompare(rect1,rect2, aFlags);
+#if defined(__WINS__)
+ if (!match)
+ FindNonMatchingPixel(rect1.iTl,rect2.iTl,aRect.Size());
+#endif
+ return match;
+ }
+
+TBool DoCheckRect(CTBaseWin *aWin1,CTBaseWin *aWin2,const TRect &aRect)
+ {
+ return DoCheckRectRWin(*aWin1->BaseWin(), *aWin2->BaseWin(), aRect);
+ }
+
+TBool DoCheckRect(CTBaseWin *aWin1,CTBaseWin *aWin2)
+ {
+ TSize winSize=aWin1->Size();
+ TRect rect1(aWin1->BaseWin()->InquireOffset(*TheClient->iGroup->WinTreeNode()),winSize);
+ TRect rect2(aWin2->BaseWin()->InquireOffset(*TheClient->iGroup->WinTreeNode()),winSize);
+ return TheClient->iScreen->RectCompare(rect1,rect2);
+ }
+
+TBool DoCheckRect(CTBaseWin *aWin1, CTBaseWin *aWin2, const TRect &aRect, TUint aFlags)
+ {
+ return DoCheckRectRWin(*aWin1->BaseWin(), *aWin2->BaseWin(), aRect, aFlags);
+ }
+
+
+/**
+Compares the contents of 2 rectangular areas of the screen.
+
+@param aPos1 The top left corner of the first rectangle.
+@param aPos2 The top left corner of the second rectangle.
+@param aSize The size of the rectangles
+@return ETrue if the 2 areas have the same content, EFalse otherwise.
+*/
+TBool DoCheckRect(TPoint aPos1,TPoint aPos2,TSize aSize)
+ {
+ return TheClient->iScreen->RectCompare(TRect(aPos1,aSize),TRect(aPos2,aSize));
+ }
+
+void CTestBase::DrawTestBackground(TBool aInvertColors, const TSize &aSize, TInt aGrays/*=16*/)
+//
+// Draws a standard test background with a mix of colors (shades).
+// This is mainly used to test for graphic functions writing outside the intended area.
+//
+// This code assumes an TheGc is already active on the window to use.
+//
+ {
+ TheGc->SetBrushColor(TRgb::Gray256(255));
+ TInt step=5;
+ TInt col=0;
+ TInt colorInc=(aGrays>9 ? 17 : 85);
+ TheGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ TheGc->SetPenStyle(CGraphicsContext::ENullPen);
+ for(TInt row=0;row<aSize.iHeight;row+=step)
+ {
+ TheGc->SetBrushColor(TRgb::Gray256(aInvertColors ? 255-col:col));
+ TheGc->DrawRect(TRect(0,row,aSize.iWidth,row+step));
+ col=col+colorInc;
+ if (col>255)
+ col=0;
+ }
+ }
+
+void CTestBase::AbortL()
+ {
+ CTestDriver* driver=iDriver;
+ iDriver->DestroyTest();
+ driver->TestComplete2();
+ User::Leave(ETestFailed);
+ }
+
+/*CTWsGraphicsBase*/
+
+CTWsGraphicsBase::CTWsGraphicsBase(CTestStep* aStep) : CTGraphicsBase(aStep)
+ {
+ }
+
+CTWsGraphicsBase::~CTWsGraphicsBase()
+ {
+ delete iTest;
+ }
+
+void CTWsGraphicsBase::CreateTestBaseL(CTTMSGraphicsStep* aTmsStep)
+ {
+ __ASSERT_ALWAYS(iTest==NULL,AutoPanic(EAutoPanicRecalledCreateTestBaseL));
+ iTest=new(ELeave) CTestBase(iStep->TestStepName(),this);
+ iTmsStep = aTmsStep;
+ }
+/**
+Gets the Screen Number from an .ini file supplied to the RUN_TEST_STEP. Screen number should
+be put under the section [useScreen] as screen=0 or screen=1.
+
+@return Screen number Defined in .ini file, otherwise 0.
+*/
+TInt CTWsGraphicsBase::GetScreenFromIni() const
+ {
+ _LIT(KUseScreenSection, "useScreen");
+ _LIT(KScreen, "screen");
+
+ TInt screen = 0;
+ TBool configAvailable = iStep->GetIntFromConfig(KUseScreenSection, KScreen, screen);
+ if(configAvailable)
+ {
+ return screen;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+void CTWsGraphicsBase::TestComplete()
+ {
+ _LIT(KTestComplete,"Test complete");
+ INFO_PRINTF1(KTestComplete);
+ CTGraphicsBase::TestComplete();
+ }
+
+void CTWsGraphicsBase::LogMessage(const TText8* aFile,TInt aLine,TRefByValue<const TDesC> aFmt,...)
+ {
+ TLogMessageText buf;
+ VA_LIST list;
+ VA_START(list,aFmt);
+ buf.AppendFormatList(aFmt,list);
+ TheClient->LogMessage(buf);
+ Logger().LogExtra(aFile,aLine,ESevrInfo,buf);
+ VA_END(list);
+ }
+
+TBool CTWsGraphicsBase::CheckRetValue(TBool aPass, const TDesC *aErrorMsg, const TDesC &aErrorFunction)
+ {
+ if (!aPass && aErrorMsg)
+ {
+ LOG_MESSAGE3(_L("%S %S failed"),aErrorMsg,&aErrorFunction);
+ iTmsStep->MQCTest(EFalse,((TText8*)__FILE__),__LINE__);
+ }
+ iStep->TEST(aPass);
+ return aPass;
+ }
+
+void CTWsGraphicsBase::CompareWindowsSoftFailWinscw(const TText8* aFile, TInt aLine)
+ {
+ if (!DoCheckRect(BaseWin, TestWin, BaseWin->Size()))
+ {
+#ifdef __WINS__
+ _LIT(KMessage,"ERROR: Test Failed but is ignored on WINSCW");
+ Logger().LogExtra(aFile, aLine, ESevrErr, KMessage);
+#else // __WINS__
+ iStep->TEST(EFalse);
+ _LIT(KMessage,"ERROR: Test Failed");
+ Logger().LogExtra(aFile, aLine, ESevrErr, KMessage);
+#endif // __WINS__
+ }
+ }
+
+void CTWsGraphicsBase::CheckRect(TPoint aPos1,TPoint aPos2,TSize aSize, const TDesC *aErrorMsg)
+ {
+ CheckRetValue(DoCheckRect(aPos1,aPos2,aSize),aErrorMsg,_L("CheckRect()"));
+ }
+
+void CTWsGraphicsBase::CheckRect(TPoint aPos1,TPoint aPos2,TSize aSize, const TDesC &aErrorMsg)
+ {
+ CheckRect(aPos1,aPos2,aSize,&aErrorMsg);
+ }
+
+void CTWsGraphicsBase::CheckRectNoMatch(TPoint aPos1,TPoint aPos2,TSize aSize, const TDesC *aErrorMsg)
+ {
+ CheckRetValue(!DoCheckRect(aPos1,aPos2,aSize),aErrorMsg,_L("CheckRectNoMatch()"));
+ }
+
+void CTWsGraphicsBase::CheckRectNoMatch(TPoint aPos1,TPoint aPos2,TSize aSize, const TDesC &aErrorMsg)
+ {
+ CheckRectNoMatch(aPos1,aPos2,aSize,&aErrorMsg);
+ }
+
+void CTWsGraphicsBase::CheckRect(CTBaseWin *aWin1,CTBaseWin *aWin2, const TDesC *aErrorMsg)
+ {
+ CheckRetValue(DoCheckRect(aWin1,aWin2),aErrorMsg,_L("CheckRect()"));
+ }
+
+void CTWsGraphicsBase::CheckRect(CTBaseWin *aWin1,CTBaseWin *aWin2, const TDesC &aErrorMsg)
+ {
+ CheckRect(aWin1,aWin2,&aErrorMsg);
+ }
+
+void CTWsGraphicsBase::CheckRectNoMatch(CTBaseWin *aWin1,CTBaseWin *aWin2, const TDesC *aErrorMsg)
+ {
+ CheckRetValue(!DoCheckRect(aWin1,aWin2),aErrorMsg,_L("CheckRectNoMatch()"));
+ }
+
+void CTWsGraphicsBase::CheckRectNoMatch(CTBaseWin *aWin1,CTBaseWin *aWin2, const TDesC &aErrorMsg)
+ {
+ CheckRectNoMatch(aWin1,aWin2,&aErrorMsg);
+ }
+
+TBool CTWsGraphicsBase::CheckRect(CTBaseWin *aWin1,CTBaseWin *aWin2,const TRect &aRect, const TDesC *aErrorMsg)
+ {
+ return CheckRetValue(DoCheckRect(aWin1,aWin2,aRect),aErrorMsg,_L("CheckRect()"));
+ }
+
+TBool CTWsGraphicsBase::CheckRect(CTBaseWin *aWin1,CTBaseWin *aWin2,const TRect &aRect, const TDesC &aErrorMsg)
+ {
+ return CheckRect(aWin1,aWin2,aRect,&aErrorMsg);
+ }
+
+void CTWsGraphicsBase::CheckRectNoMatch(CTBaseWin *aWin1,CTBaseWin *aWin2,const TRect &aRect, const TDesC *aErrorMsg)
+ {
+ CheckRetValue(!DoCheckRect(aWin1,aWin2,aRect),aErrorMsg,_L("CheckRectNoMatch()"));
+ }
+
+void CTWsGraphicsBase::CheckRectNoMatch(CTBaseWin *aWin1,CTBaseWin *aWin2,const TRect &aRect, const TDesC &aErrorMsg)
+ {
+ CheckRectNoMatch(aWin1,aWin2,aRect,&aErrorMsg);
+ }
+
+void CTWsGraphicsBase::CompareWindows(const TRect &aRect, const TDesC *aErrorMsg)
+ {
+ CheckRetValue(DoCheckRect(BaseWin,TestWin,aRect),aErrorMsg,_L("CompareWindows()"));
+ }
+
+TBool CTWsGraphicsBase::CompareWindows(const TDesC *aErrorMsg)
+ {
+ return CheckRetValue(DoCheckRect(BaseWin,TestWin,TRect(BaseWin->Size())),aErrorMsg,_L("CompareWindows()"));
+ }
+
+void CTWsGraphicsBase::CompareWindows(const TRect &aRect, const TDesC &aErrorMsg)
+ {
+ CompareWindows(aRect,&aErrorMsg);
+ }
+
+TBool CTWsGraphicsBase::CompareWindows(const TDesC &aErrorMsg)
+ {
+ return CompareWindows(&aErrorMsg);
+ }
+
+/**
+Returns the size of the standard test windows.
+
+Several tests use 3 windows : one is a log window, one is a reference window
+and one is the actual output of the test. All these windows have the same width which is roughly
+1/3 of the screen. They also have the same height which is roughly equal to the screen height.
+*/
+const TSize& CTWsGraphicsBase::StdTestWindowSize()
+ {
+ return iTest->StdTestWindowSize();
+ }
+
+/** Returns the number of greys available in the richest grey mode */
+TInt CTWsGraphicsBase::MaxGrays() const
+ {
+ return iTest->MaxGrays();
+ }
+
+/** Returns the number of colours available in the richest supported colour mode. */
+TInt CTWsGraphicsBase::MaxColors() const
+ {
+ return iTest->MaxColors();
+ }
+
+//
+// Panic testing //
+//
+
+LOCAL_C TInt PanicThreadFunc(TAny *aPtr)
+ {
+ CTrapCleanup* CleanUpStack=CTrapCleanup::New();
+ SPanicParams *ptr=(SPanicParams *)aPtr;
+ TInt ret;
+ TRAP(ret,ret=(*ptr->func)(ptr->num,ptr->ptr));
+ delete CleanUpStack;
+ if (ret==EWsExitReasonBad)
+ AutoPanic(EAutoPanicPanicFailed);
+ return(ret);
+ }
+
+TInt CTestBase::LaunchPanicThread(RThread &aThread, SPanicParams *aPtr)
+ {
+ TBuf<32> threadName;
+ threadName.Format(TRefByValue<const TDesC>(_L("AutoPanicThread%d")),iThreadNumber++);
+ return(aThread.Create(threadName,PanicThreadFunc,KDefaultStackSize,KPanicThreadHeapSize,KPanicThreadHeapSize,aPtr,EOwnerThread));
+ }
+
+TInt CTestBase::TestPanicL(SPanicParams *aPtr, TInt aExitReason, const TDesC &aCategory, TBool* aTestFinished)
+ {
+ RThread thread;
+ TRequestStatus stat;
+ TInt err=LaunchPanicThread(thread, aPtr);
+ if (err==KErrAlreadyExists)
+ {
+ // wait for kernel to clear up old threads
+ // and have several attempts at starting the thread
+ // if unsuccessful the first time
+ for (TInt i=0;i<3;i++)
+ {
+ User::After(TTimeIntervalMicroSeconds32(100000)); //0.1 secs
+ err=LaunchPanicThread(thread, aPtr);
+ if (err!=KErrAlreadyExists)
+ break;
+ }
+ }
+ User::LeaveIfError(err);
+ thread.Logon(stat);
+ User::SetJustInTime(EFalse);
+ thread.Resume();
+ User::WaitForRequest(stat);
+ User::SetJustInTime(ETrue);
+
+ TBool testFinished=EFalse;
+ TBool testPassed=ETrue;
+ if (thread.ExitType()==EExitKill)
+ {
+ User::LeaveIfError(thread.ExitReason());
+ if(thread.ExitReason()!=EWsExitReasonFinished)
+ {
+ testPassed=EFalse;
+ }
+ testFinished=ETrue; // Finish tests
+ }
+ else
+ {
+ if ((thread.ExitCategory().Compare(aCategory)!=0)
+ || (aExitReason!=EWservNoPanic && thread.ExitReason()!=aExitReason)
+ || (thread.ExitType()!=EExitPanic))
+ {
+ testPassed=EFalse;
+ }
+ }
+
+ if(aTestFinished)
+ *aTestFinished=testFinished;
+ thread.Close();
+ return(testPassed);
+ }
+
+TInt CTestBase::TestWsPanicL(TPanicFunction aFunction, TClientPanic aExitReason, TInt aInt, TAny *aPtr, TBool* aTestFinished)
+ {
+ return TestPanicL(aFunction,aExitReason,aInt,aPtr,KWSERV, aTestFinished);
+ }
+
+TInt CTestBase::TestW32PanicL(TPanicFunction aFunction, TW32Panic aExitReason, TInt aInt, TAny *aPtr, TBool* aTestFinished)
+ {
+ return TestPanicL(aFunction,aExitReason,aInt,aPtr,KW32,aTestFinished);
+ }
+
+ TInt CTestBase::TestWservPanicL(TPanicFunction aFunction, TWservPanic aExitReason, TInt aInt, TAny *aPtr)
+ {
+ _LIT(KWSERV1,"Wserv Internal Panic");
+ return TestPanicL(aFunction,aExitReason,aInt,aPtr,KWSERV1);
+ }
+
+TInt CTestBase::TestPanicL(TPanicFunction aFunction, TInt aExitReason, TInt aInt, TAny *aPtr, const TDesC &aCategory, TBool* aTestFinished)
+ {
+ SPanicParams params;
+ params.num=aInt;
+ params.func=aFunction;
+ params.ptr=aPtr;
+ return TestPanicL(¶ms, aExitReason, aCategory, aTestFinished);
+ }
+
+TBool CTestBase::IsFullRomL()
+ {
+ TBool isFullRom = EFalse;
+ _LIT(KWinName,"EikonServer");
+ TInt numWinGroups=TheClient->iWs.NumWindowGroups();
+ CArrayFixFlat<TInt>* list=new(ELeave) CArrayFixFlat<TInt>(numWinGroups);
+ TheClient->iWs.WindowGroupList(list);
+ numWinGroups=list->Count(); // Just in case it changed between originally getting it and getting the actual list
+ TBuf<64> name;
+ TInt ii;
+ for(ii=0;ii<numWinGroups;++ii)
+ {
+ TheClient->iWs.GetWindowGroupNameFromIdentifier((*list)[ii],name);
+ #ifndef DISABLE_FAIL_DIALOG
+ TInt ordinalPos=0;
+ ordinalPos+=ordinalPos; //To stop a warning
+ ordinalPos=
+ #endif
+ TheClient->iWs.GetWindowGroupOrdinalPriority((*list)[ii]);
+ if (name==KWinName)
+ {
+ isFullRom = ETrue;
+ break;
+ }
+ }
+ delete list;
+ return isFullRom;
+ }
+
+void CTestBase::DelayIfFullRomL()
+ {
+ if (IsFullRomL())
+ User::After(400000);
+ }
+
+TPartialRedrawType CTestBase::RedrawStoreTypeL()
+ {
+/* if (iRedrawType==EPartialRedraw_Unknown)
+ {
+ const TRgb KRed=TRgb(255,0,0);
+ const TRgb KGreen=TRgb(0,255,0);
+ const TRgb KBlue=TRgb(0,0,255);
+ CWsScreenDevice* scrDev=TheClient->iScreen;
+ TSize winSize=scrDev->SizeInPixels();
+ CBlankWindow* win=new(ELeave) CBlankWindow(KRed); //Window will be red if WSERV just draws in background color
+ CleanupStack::PushL(win);
+ TDisplayMode mode=EColor256;
+ win->SetUpL(TPoint(),winSize,TheClient->iGroup,*TheClient->iGc,&mode); //Window is activated
+ win->RealDraw(ETrue);
+ win->SetColor(KGreen);
+ CBlankWindow* win2=new(ELeave) CBlankWindow(KRed);
+ CleanupStack::PushL(win2);
+ win2->SetUpL(TPoint(),winSize,TheClient->iGroup,*TheClient->iGc,&mode); //New Window completely obscures other window
+ win2->RealDraw(ETrue);
+ win->CTWin::DrawNow(); //Window will be green if drawn from stored commands
+ win2->CTWin::DrawNow();
+ win2->SetVisible(EFalse);
+ TRgb col;
+ scrDev->GetPixel(col,TPoint(5,5)); //Pixel will be red if storing off by default and green otherwise
+ if (col==KRed)
+ {
+ win->Win()->EnableRedrawStore(ETrue);
+ win->CTWin::DrawNow(); //Create stored commands
+ }
+ else
+ __ASSERT_ALWAYS(col==KGreen,AutoPanic(EAutoPanicRedrawStoring));
+ win->SetColor(KBlue);
+ TRect redrawRect(TSize(10,10));
+ win->Invalidate(redrawRect);
+ win->Win()->BeginRedraw(redrawRect);
+ win->DrawNow(redrawRect); //Top left of Window will be blue if it draws itself
+ win->Win()->EndRedraw();
+ win2->SetVisible(ETrue);
+ win2->SetVisible(EFalse);
+ scrDev->GetPixel(col,TPoint(5,5)); //Pixel will be red if stored commands were lost
+ iRedrawType=EPartialRedraw_None;
+ if (col!=KRed)
+ {
+ __ASSERT_ALWAYS(col==KBlue,AutoPanic(EAutoPanicRedrawStoring));
+ TheClient->WaitForRedrawsToFinish();
+ win2->SetVisible(ETrue);
+ win2->SetVisible(EFalse);
+ scrDev->GetPixel(col,TPoint(15,15)); //Pixel will be blue if partial redraw triggers full redraw
+ iRedrawType=EPartialRedraw_PreserveStoredCmds;
+ if (col!=KBlue)
+ {
+ __ASSERT_ALWAYS(col==KGreen,AutoPanic(EAutoPanicRedrawStoring));
+ iRedrawType=EPartialRedraw_FullRedrawSupport;
+ }
+ }
+ CleanupStack::PopAndDestroy(2,win);
+ }
+ return iRedrawType;*/
+ return EPartialRedraw_FullRedrawSupport;
+ }
+
+void CTestBase::SetUpMember(TSpriteMember &aMember)
+ {
+ aMember.iMaskBitmap=NULL;
+ aMember.iInvertMask=EFalse;
+ aMember.iDrawMode=CGraphicsContext::EDrawModePEN;
+ aMember.iOffset=TPoint();
+ aMember.iInterval=TTimeIntervalMicroSeconds32(0);
+ }
+
+void CTestBase::SimulateKeyDownUpWithModifiers(TInt aScanCode,TUint aModifiers)
+ {
+ if (aModifiers&EModifierAlt)
+ SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftFunc);
+ if (aModifiers&EModifierCtrl)
+ SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftCtrl);
+ if (aModifiers&EModifierShift)
+ SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftShift);
+ SimulateKeyDownUp(aScanCode);
+ if (aModifiers&EModifierShift)
+ SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftShift);
+ if (aModifiers&EModifierCtrl)
+ SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftCtrl);
+ if (aModifiers&EModifierAlt)
+ SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftFunc);
+ }
+
+void CTestBase::SimulateKeyDownUp(TInt aScanCode)
+ {
+ __ASSERT_DEBUG(aScanCode<'a' || aScanCode>'z',AutoPanic(EAutoPanicScanCapital));
+ SimulateKey(TRawEvent::EKeyDown,aScanCode);
+ SimulateKey(TRawEvent::EKeyUp,aScanCode);
+ }
+
+void CTestBase::SimulatePointerDownUp(TInt aX, TInt aY)
+ {
+ SimulatePointer(TRawEvent::EButton1Down,aX,aY);
+ SimulatePointer(TRawEvent::EButton1Up,aX,aY);
+ }
+
+void CTestBase::SimulateKey(TRawEvent::TType aType, TInt aScanCode)
+ {
+ TRawEvent rawEvent;
+ rawEvent.Set(aType,aScanCode);
+ TheClient->iWs.SimulateRawEvent(rawEvent);
+ }
+
+/**
+ * Determine if the configuration supports pointer event testing.
+ *
+ * There are certain circumstances where we want to skip pointer event
+ * testing because we are simulating pointer events, and don't want to
+ * simulate a pointer event from an impossible co-ordinate. We'd rather
+ * just identify that there is no point in doing the test and skip over
+ * to the next test case.
+ *
+ * In particular, when a ROM configured with a digitiser is deployed on a
+ * Naviengine, with hardware configuration DIP switches which say that there
+ * is an external screen connected, then no touch pad is active.
+ * The base port under these conditions returns a digitiser area (0,0,0,0)
+ *
+ * @return ETrue if the configuration supports pointer event testing, otherwise
+ * return EFalse.
+ */
+TBool CTestBase::ConfigurationSupportsPointerEventTesting() const
+ {
+ if (iNormalPointerCursorArea.IsEmpty())
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+
+void CTestBase::SimulatePointer(TRawEvent::TType aType, TInt aX, TInt aY)
+ {
+ __ASSERT_DEBUG(ConfigurationSupportsPointerEventTesting(), AutoPanic(EAutoPanicNoDigitiser));
+
+
+#ifdef WSERV_TAUTO_LOG_POINTER_EVENTS
+ TLogMessageText buf;
+ _LIT(KLog,"SimulatePointer Type=%d Pos=(%d,%d)");
+ buf.Format(KLog,aType,aX,aY);
+ TheClient->LogMessage(buf);
+#endif
+
+ TRawEvent rawEvent;
+ rawEvent.Set(aType,aX,aY);
+ TheClient->iWs.SimulateRawEvent(rawEvent);
+ }
+
+void CTestBase::SimulateEvent(TRawEvent::TType aType)
+ {
+ TRawEvent rawEvent;
+ rawEvent.Set(aType);
+ TheClient->iWs.SimulateRawEvent(rawEvent);
+ }
+
+void CTestBase::LogColors(const CBitmapDevice& aDevice,TPoint aBasePoint, TPoint aStartPoint, TPoint aEndPoint)
+ {
+ _LIT(KPixel,"Pixel(%d,%d) R=%d G=%d B=%d");
+ TLogMessageText buf;
+ TBuf8<2560> screen;
+ const TRgb* pixel;
+ if (aStartPoint.iX==aEndPoint.iX)
+ ++aEndPoint.iX;
+ if (aStartPoint.iY==aEndPoint.iY)
+ ++aEndPoint.iY;
+ TInt width=aEndPoint.iX-aStartPoint.iX;
+ TInt xx,yy;
+ for (yy=aStartPoint.iY;yy<aEndPoint.iY;++yy)
+ {
+ xx=aStartPoint.iX;
+ aDevice.GetScanLine(screen,aBasePoint+TPoint(xx,yy),width,ERgb);
+ pixel=REINTERPRET_CAST(const TRgb*,screen.Ptr());
+ for (;xx<aEndPoint.iX;++xx,++pixel)
+ {
+ buf.Format(KPixel,xx,yy,pixel->Red(),pixel->Green(),pixel->Blue());
+ //RDebug::Print(buf);
+ TheClient->iWs.LogMessage(buf);
+ }
+ }
+ TheClient->iWs.Flush();
+ }
+
+void CTestBase::LogColors4(const CBitmapDevice& aDevice,TPoint aStartPoint,TInt aLen)
+ {
+ _LIT(KValue,"Pixel(%d,%d) Byte %d, Value %d");
+ TLogMessageText buf;
+ TBuf8<2560> screen;
+ aDevice.GetScanLine(screen,aStartPoint,aLen,EGray4);
+ TInt len=(aLen+3)/4;
+ TInt ii;
+ for (ii=0;ii<len;++ii,aStartPoint.iX+=4)
+ {
+ buf.Format(KValue,aStartPoint.iX,aStartPoint.iY,ii,screen[ii]);
+ TheClient->iWs.LogMessage(buf);
+ }
+ }
+
+void CTestBase::UpdateTestResults(TInt aNoOfTest, TInt aNoOfTestPass)
+ {
+ iNumberTests+=aNoOfTest;
+ iNumberTestsPass+=aNoOfTestPass;
+ }
+
+TInt CTestBase::SaveScreen(const TDesC& aFileName)
+ {
+ return SaveScreen(aFileName,TheClient->iScreen->SizeInPixels(),TheClient->iScreen->DisplayMode());
+ }
+
+TInt CTestBase::SaveScreen(const TDesC& aFileName,const TSize& aScreenSize,TDisplayMode aColorDepth)
+ {
+ TRAPD(err,SaveScreenL(aFileName,aScreenSize,aColorDepth));
+ return err;
+ }
+
+void CTestBase::SaveScreenL(const TDesC& aFileName,const TSize& aScreenSize,TDisplayMode aColorDepth)
+ {
+ CBitmap* copyOfScreen=CBitmap::NewLC(aScreenSize,aColorDepth);
+ CFbsScreenDevice* scrDevice=CFbsScreenDevice::NewL(iScreenNumber,aColorDepth);
+ CleanupStack::PushL(scrDevice);
+ CFbsBitGc* gc;
+ User::LeaveIfError(scrDevice->CreateContext(gc));
+ CleanupStack::PushL(gc);
+ copyOfScreen->Gc().BitBlt(TPoint(),*gc);
+ User::LeaveIfError(copyOfScreen->Bitmap().Save(aFileName));
+ CleanupStack::PopAndDestroy(3,copyOfScreen);
+ }
+
+
+/*CProcess*/
+_LIT(KScreenTag,"Screen");
+
+void CProcess::GetProcArg(const TWinCommand& aParam,TBufArg& aProcArg)
+ {
+ TInt pos = aParam.Find(KScreenTag);
+ if (pos!=KErrNotFound)
+ aProcArg = aParam.Left(pos-1);
+ else
+ aProcArg = aParam;
+ }
+
+void CProcess::GetScreenArg(const TWinCommand& aParam, TInt& aScreenArg)
+ {
+ TInt pos = aParam.Find(KScreenTag);
+ if (pos!=KErrNotFound)
+ {
+ TBufArg secondArg(aParam.Right(aParam.Length()-pos));
+ if (secondArg.Length()>6)
+ {
+ TBuf<1> digit(secondArg.Mid(6,1));
+ TLex lex(digit);
+ lex.Val(aScreenArg);
+ }
+ }
+ }
+
+TInt CProcess::Start(const TWinCommand& aParam)
+ {
+ // parse command line aParam to retrieve value of
+ // screen number if it is specified
+ //
+ // command line format: <process-id> [screen<id>]
+ //
+ TBufArg procArg(_L(""));
+ TInt screenArg = KDefaultScreen;
+
+ GetProcArg(aParam, procArg);
+ GetScreenArg(aParam, screenArg);
+
+ TInt ii;
+ for(ii=0;ii<eNumProcessCalls;ii++)
+ {
+ if (procArg==iFunctions[ii].iParam)
+ {
+ TRAPD(ret,iFunctions[ii].iFunction((TAny*)screenArg));
+
+ // need to pass test result to owning process
+ // for multiple display test
+ if (ii==eProcessMultiDisplayTest)
+ ret = TheTestResult;
+
+ return ret;
+ }
+ }
+
+ return KErrNone; //Shouldn't get here
+ }
+
+CProcess* CProcess::NewL(TInt aFunctionNo,TInt aScreenNumber)
+ {
+ CProcess* self=new(ELeave) CProcess();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFunctionNo,aScreenNumber);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CProcess* CProcess::NewTL(TInt aFunctionNo,TInt aScreenNumber,TRequestStatus* aStatus /*=NULL*/)
+ {
+ CProcess* self=new(ELeave) CProcess();
+ CleanupStack::PushL(self);
+ self->ConstructTL(aFunctionNo,aScreenNumber,aStatus);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CProcess* CProcess::NewThreadL(const TDesC& aName,TThreadFunction aFunction,TThreadStartUp* aPtr
+ ,TRequestStatus* aStatus)
+ {
+ CProcess* self=new(ELeave) CProcess();
+ CleanupStack::PushL(self);
+ self->ConstructL(aName,aFunction,aPtr,aStatus);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CProcess* CProcess::NewThreadRendezvousL(const TDesC& aName,TThreadFunction aFunction,TThreadStartUp* aPtr ,TRequestStatus* aLogonStatus,TRequestStatus& aRendesvouzStatus)
+ {
+ CProcess* self=new(ELeave) CProcess();
+ CleanupStack::PushL(self);
+ self->ConstructRendezvousL(aName,aFunction,aPtr,aLogonStatus,aRendesvouzStatus);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CProcess* CProcess::NewThreadRendezvousL(const TDesC& aName,TThreadStartUp* aPtr,TRequestStatus& aRendesvouzStatus)
+ {
+ return NewThreadRendezvousL(aName,ThreadInit,aPtr,NULL,aRendesvouzStatus);
+ }
+
+CProcess* CProcess::NewThreadL(const TDesC& aName,TThreadStartUp* aPtr)
+ {
+ return NewThreadL(aName,ThreadInit,aPtr,NULL);
+ }
+
+CProcess* CProcess::NewSimpleThreadL(const TDesC& aName,TThreadStartUp* aPtr,TRequestStatus* aStatus/*=NULL*/)
+ {
+ return NewThreadL(aName,SimpleThreadInit,aPtr,aStatus);
+ }
+
+_LIT(KSpace," ");
+_LIT(KScreenFormat,"%d");
+
+void CProcess::ConstructL(TInt aFunctionNo,TInt aScreenNumber/*=KDefaultScreen*/)
+ {
+ Close();
+ // add screen number into command line param
+ // format: <proc-id> [screen<id>]
+ //
+ TBuf<100> commandLine;
+
+ commandLine = iFunctions[aFunctionNo].iParam;
+ commandLine.Append(KSpace);
+ commandLine.Append(KScreenTag);
+ commandLine.AppendFormat(KScreenFormat,aScreenNumber);
+ User::LeaveIfError(iOther.Create(RProcess().FileName(),commandLine));
+ iCreated|=eOtherCreated;
+ iOther.Resume();
+ }
+
+void CProcess::ConstructTL(TInt aFunctionNo,TInt aScreenNumber/*=KDefaultScreen*/,TRequestStatus* aStatus)
+ {
+ Close();
+ TUint flag=eThreadCreated;
+ TInt err=iThread.Create(iFunctions[aFunctionNo].iParam,iFunctions[aFunctionNo].iFunction
+ ,KDefaultStackSize,KOtherProcHeapSize,KOtherProcHeapSize,(TAny*)aScreenNumber,EOwnerThread);
+ User::LeaveIfError(err);
+ iCreated|=flag;
+ if (aStatus)
+ Logon(*aStatus);
+ iThread.Resume();
+ }
+
+
+void CProcess::ConstructL(const TDesC& aName,TThreadFunction aFunction,TThreadStartUp* aPtr,TRequestStatus* aStatus)
+ {
+ Close();
+ User::LeaveIfError(iThread.Create(aName,aFunction,KDefaultStackSize,KOtherProcHeapSize,KOtherProcHeapSize,aPtr,EOwnerThread));
+ iCreated|=eThreadCreated;
+ if (aStatus)
+ Logon(*aStatus);
+ iThread.Resume();
+ }
+
+void CProcess::ConstructRendezvousL(const TDesC& aName,TThreadFunction aFunction,TThreadStartUp* aPtr,TRequestStatus* aLogonStatus,TRequestStatus& aRendezvousStatus)
+ {
+ Close();
+ User::LeaveIfError(iThread.Create(aName,aFunction,KDefaultStackSize,KOtherProcHeapSize,KOtherProcHeapSize,aPtr,EOwnerThread));
+ iCreated|=eThreadCreated;
+ if (aLogonStatus)
+ Logon(*aLogonStatus);
+
+ iThread.Rendezvous(aRendezvousStatus);
+ iThread.Resume();
+ }
+
+void CProcess::Logon(TRequestStatus& aStatus) const
+ {
+ if (iCreated&eThreadCreated)
+ iThread.Logon(aStatus);
+ else
+ {
+ iOther.Logon(aStatus);
+ }
+ }
+
+void CProcess::Terminate(TInt aReason)
+ {
+ if (iCreated&eThreadCreated)
+ iThread.Terminate(aReason);
+ else
+ {
+ iOther.Terminate(aReason);
+ }
+ Close();
+ }
+
+void CProcess::Close()
+ {
+ if (iCreated&eOtherCreated)
+ iOther.Close();
+ if (iCreated&eThreadCreated)
+ iThread.Close();
+ iCreated=0;
+ }
+
+CProcess::~CProcess()
+ {
+ Close();
+ }
+
+TBool CProcess::StillAlive()
+ {
+ if (iCreated&eOtherCreated)
+ return iOther.ExitType()==EExitPending;
+ return iThread.ExitType()==EExitPending;
+ }
+
+void CProcess::LeaveIfDied() //Can Leave
+ {
+ User::After(200000); //0.2 secs
+ if (StillAlive())
+ return;
+ if (iCreated&eOtherCreated)
+ User::Leave(iOther.ExitReason());
+ User::Leave(iThread.ExitReason());
+ }
+
+const TInt KFirstInstanceId = 1;
+const TInt KOtherInstanceId = 2;
+
+TBool CProcess::ProcessDied(TInt aScreenNo/*=KDefaultScreen*/)
+ {
+ _LIT(pName,"TAutoServer*");
+ TFindProcess find(pName);
+ TFullName name;
+
+ TBool found = EFalse;
+ TInt instanceId = aScreenNo==KDefaultScreen? KFirstInstanceId : KOtherInstanceId;
+ // find the correct instance of the process
+ // required in multi display test
+ while (!found && find.Next(name)==KErrNone)
+ {
+ TPtrC scrId = name.Right(1);
+ TInt id;
+ TLex lex(scrId);
+ lex.Val(id);
+ if (id==instanceId)
+ found = ETrue;
+ }
+ if (!found)
+ return EFalse;
+
+ RProcess p;
+ p.Open(name);
+ if (p.Id()!=RProcess().Id())
+ return EFalse;
+ p.Close();
+ return (find.Next(name)!=KErrNone);
+ }
+
+TInt CProcess::ThreadInit(TAny *aPtr)
+ {
+ __UHEAP_MARK;
+ TInt err=KErrNone;
+ CTrapCleanup* CleanUpStack=CTrapCleanup::New();
+ if (CleanUpStack==NULL)
+ err=KErrNoMemory;
+ else
+ {
+ TRAP(err,InitialiseL(STATIC_CAST(TThreadStartUp*,aPtr)))
+ delete CleanUpStack;
+ }
+ __UHEAP_MARKEND;
+ return(err);
+ }
+
+void CProcess::InitialiseL(TThreadStartUp* aPtr)
+ {
+ CActiveScheduler* activeScheduler=new(ELeave) CActiveScheduler;
+ CActiveScheduler::Install(activeScheduler);
+ CleanupStack::PushL(activeScheduler);
+ aPtr->iInitFunction(aPtr->iParam);
+ CActiveScheduler::Start();
+ CleanupStack::PopAndDestroy(activeScheduler);
+ }
+
+TInt CProcess::SimpleThreadInit(TAny *aPtr)
+ {
+ __UHEAP_MARK;
+ TInt err=KErrNone;
+ CTrapCleanup* CleanUpStack=CTrapCleanup::New();
+ if (CleanUpStack==NULL)
+ err=KErrNoMemory;
+ else
+ {
+ TThreadStartUp* ptr=STATIC_CAST(TThreadStartUp*,aPtr);
+ ptr->iInitFunction(ptr->iParam);
+ delete CleanUpStack;
+ }
+ __UHEAP_MARKEND;
+ return(err);
+ }
+
+/*CMinWin*/
+
+CMinWin::CMinWin(TInt aScreenNo): iScreenNo(aScreenNo)
+ {}
+
+void CMinWin::ConstructL()
+ {
+ User::LeaveIfError(iWs.Connect());
+ iScr=new(ELeave) CWsScreenDevice(iWs);
+ User::LeaveIfError(iScr->Construct(iScreenNo));
+ iGroup=RWindowGroup(iWs);
+ User::LeaveIfError(iGroup.Construct(8970+iScreenNo,ETrue));
+ iWin=RWindow(iWs);
+ User::LeaveIfError(iWin.Construct((RWindowTreeNode)iGroup,(TUint32)this));
+ iRect=TSize(10,10);
+ iWin.SetExtent(TPoint(0,0),iRect.Size());
+ iWin.SetRequiredDisplayMode(EColor256);
+ iWin.SetBackgroundColor(KRgbGreen);
+ iWin.Activate();
+ iGc=new(ELeave) CWindowGc(iScr);
+ User::LeaveIfError(iGc->Construct());
+
+ Draw(iRect);
+ iWs.Flush();
+ }
+
+CMinWin::~CMinWin()
+ {
+ delete iGc;
+ iWin.Close();
+ iGroup.Close();
+ delete iScr;
+ iWs.Close();
+ }
+
+void CMinWin::Draw(const TRect& aRect)
+ {
+ iWin.BeginRedraw();
+ iGc->Activate(iWin);
+ iGc->SetPenStyle(CGraphicsContext::ENullPen);
+ iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ iGc->SetBrushColor(KRgbGreen);
+ iGc->DrawRect(aRect);
+ iGc->Deactivate();
+ iWin.EndRedraw();
+ }
+
+
+/*CTimeOut*/
+
+void CTimeOut::ConstructL()
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add(this);
+ }
+
+void CTimeOut::Start(TTimeIntervalMicroSeconds32 aInterval,TCallBack aCallBack)
+ {
+ iCallBack=aCallBack;
+ After(aInterval);
+ }
+
+void CTimeOut::RunL()
+ {
+ iCallBack.CallBack();
+ }
+
+/*
+ * Simply returns the DisplayMode as a string. Used to display mode details on test results.
+ */
+GLDEF_C TPtrC DisplayModeAsString(TDisplayMode aMode)
+ {
+
+ TPtrC modeAsString;
+
+ switch(aMode)
+ {
+ case ENone:
+ _LIT(KENoneMode,"ENone");
+ modeAsString.Set(KENoneMode);
+ break;
+ case EGray2:
+ _LIT(KEGray2Mode,"EGray2");
+ modeAsString.Set(KEGray2Mode);
+ break;
+ case EGray4:
+ _LIT(KEGray4Mode,"EGray4");
+ modeAsString.Set(KEGray4Mode);
+ break;
+ case EGray16:
+ _LIT(KEGray16Mode,"EGray16");
+ modeAsString.Set(KEGray16Mode);
+ break;
+ case EGray256:
+ _LIT(KEGray256Mode,"EGray256");
+ modeAsString.Set(KEGray256Mode);
+ break;
+ case EColor16:
+ _LIT(KEColor16Mode,"EColor16");
+ modeAsString.Set(KEColor16Mode);
+ break;
+ case EColor256:
+ _LIT(KEColor256Mode,"EColor256");
+ modeAsString.Set(KEColor256Mode);
+ break;
+ case EColor64K:
+ _LIT(KEColor64KMode,"EColor64K");
+ modeAsString.Set(KEColor64KMode);
+ break;
+ case EColor16M:
+ _LIT(KEColor16MMode,"EColor16M");
+ modeAsString.Set(KEColor16MMode);
+ break;
+ case EColor4K:
+ _LIT(KEColor4KMode,"EColor4K");
+ modeAsString.Set(KEColor4KMode);
+ break;
+ case EColor16MU:
+ _LIT(KEColor16MUMode,"EColor16MU");
+ modeAsString.Set(KEColor16MUMode);
+ break;
+ case EColor16MA:
+ _LIT(KEColor16MAMode,"EColor16MA");
+ modeAsString.Set(KEColor16MAMode);
+ break;
+ case EColor16MAP:
+ _LIT(KEColor16MAPMode,"EColor16MAP");
+ modeAsString.Set(KEColor16MAPMode);
+ break;
+ default:
+ _LIT(KUnknownMode,"Unknown");
+ modeAsString.Set(KUnknownMode);
+ break;
+ }
+
+ return modeAsString;
+ }
+
+// Check if an area of a bitmap is of a certain color
+GLDEF_C TBool LossyCheckBlankBitmap(const CFbsBitmap& aBitmap, const TRect aArea, const TRgb aCheckColor, TBool aLossyCompare)
+ {
+ const TReal errorLimit = (aLossyCompare ? 0.05 : 0.00); //Lossy(default) or exact compare?
+
+ TBool result = ETrue;
+ /* TInt mismatchedPixels = 0; */ // -- Useful for debugging
+ TRgb bitmapPix = TRgb(0,0,0,0); //testWin Pixel
+ for (TInt x = 0; x < aArea.Size().iWidth; x++)
+ {
+ for (TInt y = 0; y < aArea.Size().iHeight; y++)
+ {
+ aBitmap.GetPixel(bitmapPix, TPoint(x,y));
+
+ //Check if there are differeces in color between the bitmap and the test color
+ if(((TReal)abs(bitmapPix.Red() - aCheckColor.Red())/255) > errorLimit ||
+ ((TReal)abs(bitmapPix.Blue() - aCheckColor.Blue())/255) > errorLimit ||
+ ((TReal)abs(bitmapPix.Green() - aCheckColor.Green())/255) > errorLimit ||
+ ((TReal)abs(bitmapPix.Alpha() - aCheckColor.Alpha())/255) > errorLimit)
+ {
+ /* mismatchedPixels++; */ // -- Useful for debugging
+ result = EFalse;
+ break;
+ }
+ }
+ }
+
+ /* INFO_PRINTF2(_L("Number of different pixels: %i"), mismatchedPixels); */ // -- Useful for debugging
+ return result;
+ }
+
+// Compare a section of two bitmaps
+GLDEF_C TBool LossyCompareBitmap(const CFbsBitmap& aBitmap1, const CFbsBitmap& aBitmap2, const TRect aCompareRect, TBool aLossyCompare)
+ {
+ const TReal errorLimit = (aLossyCompare ? 0.05 : 0.00); //Lossy or Exact compare?
+
+ TBool result = ETrue;
+
+ if (aBitmap1.DisplayMode() != aBitmap2.DisplayMode())
+ {
+ RDebug::Printf(" DisplayMode difference %d, %d", aBitmap1.DisplayMode(), aBitmap2.DisplayMode());
+ }
+
+ TRgb bitmap1Pix = TRgb(0,0,0,0);
+ TRgb bitmap2Pix = TRgb(0,0,0,0);
+ for (TInt x = 0; x < aCompareRect.Size().iWidth; x++)
+ {
+ for (TInt y = 0; y < aCompareRect.Size().iHeight; y++)
+ {
+ aBitmap1.GetPixel(bitmap1Pix, TPoint(x,y));
+ aBitmap2.GetPixel(bitmap2Pix, TPoint(x,y));
+
+ //Check if there are differences between the colors of the two bitmaps
+ if(((TReal)abs(bitmap1Pix.Red() - bitmap2Pix.Red())/255) > errorLimit ||
+ ((TReal)abs(bitmap1Pix.Blue() - bitmap2Pix.Blue())/255) > errorLimit ||
+ ((TReal)abs(bitmap1Pix.Green() - bitmap2Pix.Green())/255) > errorLimit ||
+ ((TReal)abs(bitmap1Pix.Alpha() - bitmap2Pix.Alpha())/255) > errorLimit)
+ {
+ /*
+ * There was a difference so return without checking the rest of the
+ * bitmap. If you are seeing Lossy compare errors, and want to diagnose
+ * further, consider switching over to using a recording version of this
+ * function, LossyCompareBitmapRecord()
+ */
+ result = EFalse;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+/**
+ * Compare two bitmaps, optionally a lossy comparison, recording any differences and saving bitmaps
+ *
+ * @param aBitmap1 Bitmap being checked
+ * @param aBitmap2 Reference Bitmap
+ * @param aCompareRect Area of bitmap to compare
+ * @param aLossyCompare ETrue means use a lossy compare strategy, else do an exact compare
+ * @param aPixelsDifferent Returned value representing the number of pixels which are different
+ * @param aLogger Facility for logging to be reported by this function
+ * @return ETrue if the bitmaps are the same (or similar).
+ * Otherwise EFalse, with logging reporting the differences, and bitmaps saved in c:\logs\
+ * @pre c:\logs directory must exist
+ */
+GLDEF_C TBool LossyCompareBitmapRecord(CFbsBitmap& aBitmap1, CFbsBitmap& aBitmap2, const TRect aCompareRect, TBool aLossyCompare, TInt& aPixelsDifferent, CTestExecuteLogger& aLogger)
+ {
+ const TReal errorLimit = (aLossyCompare ? 0.05 : 0.00); //Lossy or Exact compare?
+
+ TBool result = ETrue;
+ TInt mismatchedPixels = 0;
+ TRgb bitmap1Pix = TRgb(0,0,0,0);
+ TRgb bitmap2Pix = TRgb(0,0,0,0);
+ if (aBitmap1.DisplayMode() != aBitmap2.DisplayMode())
+ {
+ aLogger.LogExtra(((TText8*)__FILE__), __LINE__, ESevrInfo,
+ _L(" DisplayMode difference %d, %d"), aBitmap1.DisplayMode(), aBitmap2.DisplayMode());
+ }
+ for (TInt x = 0; x < aCompareRect.Size().iWidth; x++)
+ {
+ for (TInt y = 0; y < aCompareRect.Size().iHeight; y++)
+ {
+ aBitmap1.GetPixel(bitmap1Pix, TPoint(x,y));
+ aBitmap2.GetPixel(bitmap2Pix, TPoint(x,y));
+
+ //Check if there are differences between the colors of the two bitmaps
+ if(((TReal)abs(bitmap1Pix.Red() - bitmap2Pix.Red())/255) > errorLimit ||
+ ((TReal)abs(bitmap1Pix.Blue() - bitmap2Pix.Blue())/255) > errorLimit ||
+ ((TReal)abs(bitmap1Pix.Green() - bitmap2Pix.Green())/255) > errorLimit ||
+ ((TReal)abs(bitmap1Pix.Alpha() - bitmap2Pix.Alpha())/255) > errorLimit)
+ {
+ mismatchedPixels++;
+
+ aLogger.LogExtra(((TText8*)__FILE__), __LINE__, ESevrInfo,
+ _L(" Pixel difference %d,%d: %d"),x,y, bitmap1Pix.Difference(bitmap2Pix));
+ result = EFalse;
+ // we loop around again to pick up all the differences
+ }
+ }
+ }
+ aPixelsDifferent = mismatchedPixels;
+
+ /*
+ * When the bitmaps are different, we store them locally in c:\\logs in
+ * timestamped files. Save() is a non-const method; this is why aBitmap1
+ * and aBitmap2 are non-const. Saving can fail, perhaps because we have
+ * exceeded storage limits.
+ */
+ if (!result)
+ {
+ TTime now;
+ now.UniversalTime();
+ TInt timestamp = I64INT(now.Int64() & 0x7fffffffu);
+ timestamp/=1000; // a millisecond resolution is easier to track
+ TFileName mbmFileSrc;
+ mbmFileSrc.Format (_L("c:\\logs\\%d_LossyCompareBitmap1.mbm"), timestamp);
+ TFileName mbmFileDst;
+ mbmFileDst.Format (_L("c:\\logs\\%d_LossyCompareBitmap2.mbm"), timestamp);
+ TInt saveResult1;
+ TInt saveResult2;
+ saveResult1 = aBitmap1.Save(mbmFileSrc);
+ saveResult2 = aBitmap2.Save(mbmFileDst);
+ if (saveResult1 == KErrNone && saveResult2 == KErrNone)
+ {
+ aLogger.LogExtra(((TText8*)__FILE__), __LINE__, ESevrInfo,
+ _L(" Bitmaps are different: see %S, %S"), &mbmFileSrc, &mbmFileDst);
+ }
+ else
+ {
+ aLogger.LogExtra(((TText8*)__FILE__), __LINE__, ESevrInfo,
+ _L(" Bitmaps are different, but could not save files into c:\\logs : %d %d"), saveResult1, saveResult2);
+ }
+ }
+
+ return result;
+ }
+
+// Check if an area of a screen is of a certain color
+GLDEF_C TBool LossyCheckBlankWindow(const CWsScreenDevice& aScreen, CFbsBitmap& aBitmap, const TRect aArea, const TRgb aCheckColor)
+ {
+ aScreen.CopyScreenToBitmap(&aBitmap, aArea);
+ return LossyCheckBlankBitmap(aBitmap, aArea, aCheckColor);
+ }
+
+// Compare a section of two windows on the screen
+GLDEF_C TBool LossyCompareWindow(const CWsScreenDevice& aScreen, CFbsBitmap& aBitmap1, CFbsBitmap& aBitmap2, const TRect aCompareRect)
+ {
+ aScreen.CopyScreenToBitmap(&aBitmap1, aCompareRect);
+ aScreen.CopyScreenToBitmap(&aBitmap2, aCompareRect);
+ return LossyCompareBitmap(aBitmap1, aBitmap2, aCompareRect);
+ }
+