os/graphics/windowing/windowserver/test/tauto/TTEXTCURS.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/windowing/windowserver/test/tauto/TTEXTCURS.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2040 @@
     1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Test the text cursor.
    1.18 +//
    1.19 +// This suite of tests checks to see if the TextCursors are operating
    1.20 +// correctly for a number of use case scenarios; see doxygen comments
    1.21 +// for each sub-test.  This test suite is applicable on both winscw
    1.22 +// emulator and armv5 target hardware.  However, it must be noted that
    1.23 +// text cursors are special due to their timeliness.  The text cursor
    1.24 +// must flash every second: half a second ON, half a second OFF.  One
    1.25 +// consequence of this is that when the test suite is run on emulator,
    1.26 +// the PC must be otherwise quiescent.  No other IO or CPU intensive
    1.27 +// activities may occur on the system, because these will cause delays
    1.28 +// to the flashing of the text cursor giving unreliable results.
    1.29 +// Where timeliness is a consideration, we use TEST_SOFTFAIL_WINSCW so
    1.30 +// that if the test fails and we are running on the PC emulator, we only
    1.31 +// record the fact, but don't mark the test as failing.
    1.32 +
    1.33 +/**
    1.34 + @file
    1.35 + @test
    1.36 + @internalComponent - Internal Symbian test code
    1.37 +*/
    1.38 +
    1.39 +#include "TTEXTCURS.H"
    1.40 +#include "graphics/windowserverconstants.h"
    1.41 +
    1.42 +const TInt KNumberOfCustoTextCursors	= 3;
    1.43 +const TInt KTextCursorInitialIdValue	= 1001;
    1.44 +const TInt KTextCursorPanicUid1			= 200;
    1.45 +const TInt KTextCursorPanicUid2			= 2000;
    1.46 +const TInt KTextCursorPanicUid3			= 3000;
    1.47 +const TInt KTextCursorPanicUid4			= 4000;
    1.48 +const TInt KTextCursorPanicUid5			= 5000;
    1.49 +
    1.50 +CTestBase* CTCursorTest::iStaticTest = NULL;
    1.51 +const TInt kWinWidth=400;
    1.52 +const TInt kWinHeight=100;
    1.53 +const TSize kWinSize(kWinWidth,kWinHeight);
    1.54 +const TInt kWinXPos=150;
    1.55 +const TInt kCursorWidth = 10;
    1.56 +const TInt kCursorHeight = 20;
    1.57 +const TSize kCursorSize(kCursorWidth,kCursorHeight);
    1.58 +const TPoint kWin1TopLeft(kWinXPos,0);
    1.59 +const TPoint kWin2TopLeft(kWinXPos,kWinHeight+10);
    1.60 +
    1.61 +LOCAL_D void DeleteSpriteMember(TAny* aSpriteMember)
    1.62 +	{
    1.63 +	TSpriteMember* member=reinterpret_cast<TSpriteMember*>(aSpriteMember);
    1.64 +	delete member->iBitmap;
    1.65 +	member->iBitmap=NULL;
    1.66 +	delete member->iMaskBitmap;
    1.67 +	member->iMaskBitmap=NULL;
    1.68 +	}
    1.69 +
    1.70 +CCustomTextCursor::~CCustomTextCursor()
    1.71 +	{
    1.72 +	const TInt count = iSpriteMemberArray.Count();
    1.73 +	for (TInt index=0; index<count; ++index)
    1.74 +		{
    1.75 +		DeleteSpriteMember(&iSpriteMemberArray[index]);
    1.76 +		}
    1.77 +	iSpriteMemberArray.Close();
    1.78 +	}
    1.79 +	
    1.80 +CCustomTextCursor::CCustomTextCursor(CTestBase* aTest)
    1.81 +	: iTest(aTest)
    1.82 +	{	
    1.83 +	}
    1.84 +
    1.85 +void CCustomTextCursor::ConstructL(TInt aScreenNumber,TInt aBmpIndex)
    1.86 +	{
    1.87 +	ASSERT(aBmpIndex < KNumberOfCustoTextCursors);
    1.88 +	
    1.89 +
    1.90 +	TSpriteMember spriteMember;
    1.91 +	spriteMember.iBitmap = NULL;
    1.92 +	spriteMember.iMaskBitmap = NULL;
    1.93 +	spriteMember.iInvertMask =EFalse;
    1.94 +	spriteMember.iDrawMode = CGraphicsContext::EDrawModePEN;
    1.95 +	spriteMember.iOffset = TPoint();
    1.96 +	spriteMember.iInterval = TTimeIntervalMicroSeconds32(0);
    1.97 +	CleanupStack::PushL(TCleanupItem(DeleteSpriteMember, &spriteMember));
    1.98 +	spriteMember.iBitmap = new (ELeave) CFbsBitmap;
    1.99 +	User::LeaveIfError(spriteMember.iBitmap->Load(TEST_BITMAP_NAME, EMbmWsautotestBmp1));
   1.100 +	spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap;
   1.101 +	User::LeaveIfError(spriteMember.iMaskBitmap->Load(TEST_BITMAP_NAME, EMbmWsautotestBmp1mask));
   1.102 +
   1.103 +	User::LeaveIfError(iSpriteMemberArray.Append(spriteMember));
   1.104 +	CleanupStack::Pop(&spriteMember);
   1.105 +
   1.106 +	// create unique-id accross screens
   1.107 +	//
   1.108 +	iIdentifier = KTextCursorInitialIdValue + aScreenNumber*KNumberOfCustoTextCursors + aBmpIndex;
   1.109 +	iAlignment = (RWsSession::TCustomTextCursorAlignment)(aBmpIndex);
   1.110 +	}
   1.111 +
   1.112 +CCustomTextCursor* CCustomTextCursor::CreateCustomTextCursorL(TInt aScreenNumber,TInt aBmpIndex,CTestBase* aTest)
   1.113 +	{
   1.114 +	CCustomTextCursor* customTextCursor = new (ELeave) CCustomTextCursor(aTest);
   1.115 +	CleanupStack::PushL(customTextCursor);
   1.116 +	customTextCursor->ConstructL(aScreenNumber,aBmpIndex);
   1.117 +	CleanupStack::Pop(customTextCursor);
   1.118 +	return customTextCursor;
   1.119 +	}
   1.120 +
   1.121 +/*
   1.122 + * Wrapper class for a list of custom text cursor.
   1.123 + */
   1.124 +class CCustomTextCursorsWrapper : public CBase
   1.125 +	{
   1.126 +public:
   1.127 +	static CCustomTextCursorsWrapper* NewLC(TInt aScreenNumber,CTestBase* aTest);
   1.128 +	~CCustomTextCursorsWrapper();
   1.129 +	inline RPointerArray<CCustomTextCursor>& CustomTextCursorsArray();
   1.130 +	inline CCustomTextCursor& CustomTextCursor(TInt aIndex);
   1.131 +private:
   1.132 +	void ConstructL(TInt aScreenNumber,CTestBase* aTest);
   1.133 +private:
   1.134 +	RPointerArray<CCustomTextCursor> iCustomTextCursors;
   1.135 +	};
   1.136 +
   1.137 +inline RPointerArray<CCustomTextCursor>& CCustomTextCursorsWrapper::CustomTextCursorsArray()
   1.138 +		{
   1.139 +		return iCustomTextCursors;
   1.140 +		}
   1.141 +
   1.142 +inline CCustomTextCursor& CCustomTextCursorsWrapper::CustomTextCursor(TInt aIndex)
   1.143 +		{
   1.144 +		return *(iCustomTextCursors[aIndex]);
   1.145 +		}
   1.146 +
   1.147 +CCustomTextCursorsWrapper* CCustomTextCursorsWrapper::NewLC(TInt aScreenNumber,CTestBase* aTest)
   1.148 +	{
   1.149 +	CCustomTextCursorsWrapper* self = new(ELeave) CCustomTextCursorsWrapper();
   1.150 +	CleanupStack::PushL(self);
   1.151 +	self->ConstructL(aScreenNumber,aTest);
   1.152 +	return self;
   1.153 +	}
   1.154 +
   1.155 +CCustomTextCursorsWrapper::~CCustomTextCursorsWrapper()
   1.156 +	{
   1.157 +	iCustomTextCursors.ResetAndDestroy();
   1.158 +	iCustomTextCursors.Close();
   1.159 +	}
   1.160 +
   1.161 +void CCustomTextCursorsWrapper::ConstructL(TInt aScreenNumber, CTestBase* aTest)
   1.162 +	{
   1.163 +	for (TInt index=0; index<KNumberOfCustoTextCursors; ++index)
   1.164 +		{
   1.165 +		CCustomTextCursor* customTextCursor=CCustomTextCursor::CreateCustomTextCursorL(aScreenNumber,index, aTest);
   1.166 +		CleanupStack::PushL(customTextCursor);
   1.167 +		User::LeaveIfError(iCustomTextCursors.Append(customTextCursor));
   1.168 +		CleanupStack::Pop(customTextCursor);
   1.169 +		}
   1.170 +	}
   1.171 +
   1.172 +CTCursorTest::CTCursorTest(CTestStep* aStep) :
   1.173 +	CTWsGraphicsBase(aStep)
   1.174 +	{
   1.175 +	iCursorType = TTextCursor::ETypeFirst;
   1.176 +	iStaticTest=iTest;
   1.177 +	}
   1.178 +	
   1.179 +CTCursorTest::~CTCursorTest()
   1.180 +	{
   1.181 +	delete iWorkInProgress;
   1.182 +	delete iComparisonWindow;
   1.183 +	}
   1.184 +
   1.185 +TInt CTCursorTest::DoPanicTest(TInt aInt, TAny *aScreenNumber)
   1.186 +	{
   1.187 +	RWsSession ws;
   1.188 +	if (ws.Connect()==KErrNone)
   1.189 +		{
   1.190 +		// use correct screen
   1.191 +		CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
   1.192 +		User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
   1.193 +		RWindowGroup group(ws);
   1.194 +		if (group.Construct(444)==KErrNone)
   1.195 +			{
   1.196 +			group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
   1.197 +			RWindow wnd(ws);
   1.198 +			if (wnd.Construct(group, TInt32(&ws))==KErrNone)
   1.199 +				{
   1.200 +				TTextCursor tc;
   1.201 +				tc.iHeight=10;
   1.202 +				tc.iAscent=5;
   1.203 +				tc.iWidth=10;
   1.204 +				tc.iFlags=0;
   1.205 +				tc.iColor=TRgb(0,0,0);
   1.206 +				switch(aInt)
   1.207 +					{
   1.208 +					case 0:
   1.209 +						{
   1.210 +						/* TESTCASE:	6.1
   1.211 +						* TITLE:		Invalid use of a custom text cursor ID (basic text cursor).
   1.212 +						* IMPORTANCE:	1
   1.213 +						* REQUIREMENT:	Unknown.
   1.214 +						* 
   1.215 +						* ACTION:		This test tries to set a text cursor using an ID which is invalid.
   1.216 +						* 
   1.217 +						* CHECK:		The thread should panic with the exit reason EWservPanicInvalidTextCursor
   1.218 +						*/ 
   1.219 +						tc.iType=(TTextCursor::EType)KTextCursorPanicUid1;
   1.220 +						group.SetTextCursor(wnd,TPoint(10,10),tc);
   1.221 +						}
   1.222 +						break;
   1.223 +					case 1:
   1.224 +						{
   1.225 +						/* TESTCASE:	6.2
   1.226 +						* TITLE:		Invalid use of a window for a text cursor.
   1.227 +						* IMPORTANCE:	1
   1.228 +						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
   1.229 +						* 
   1.230 +						* ACTION:		This test tries to set a text cursor using a window which is not part
   1.231 +						*				of the window group calling the setting API.
   1.232 +						* 
   1.233 +						* CHECK:		The thread should panic with the exit reason EWservPanicWindow
   1.234 +						*/ 
   1.235 +						tc.iType=(TTextCursor::EType)KTextCursorPanicUid2;
   1.236 +						group.SetTextCursor(*TestWin->Win(),TPoint(10,10),tc);
   1.237 +						}
   1.238 +						break;
   1.239 +					case 2:
   1.240 +						{
   1.241 +						/* TESTCASE:	6.3
   1.242 +						* TITLE:		Invalid use of a custom text cursor ID.
   1.243 +						* IMPORTANCE:	1
   1.244 +						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
   1.245 +						* 
   1.246 +						* ACTION:		This test tries to set a text cursor using an ID which is associated to
   1.247 +						*				an non-existing custom text cursor.
   1.248 +						* 
   1.249 +						* CHECK:		The thread should panic with the exit reason EWservPanicNoCustomTextCursor
   1.250 +						*/ 
   1.251 +						tc.iType=(TTextCursor::EType)KTextCursorPanicUid3;
   1.252 +						group.SetTextCursor(wnd,TPoint(10,10),tc);
   1.253 +						}
   1.254 +						break;
   1.255 +					case 3:
   1.256 +						{
   1.257 +						/* TESTCASE:	6.4
   1.258 +						* TITLE:		Invalid use of a custom text cursor ID.
   1.259 +						* IMPORTANCE:	1
   1.260 +						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
   1.261 +						* 
   1.262 +						* ACTION:		This test tries to set a custom text cursor which has been set to use
   1.263 +						*				an invalid alignment.
   1.264 +						* 
   1.265 +						* CHECK:		The thread should panic with the exit reason EWservPanicCustomTextCursorAlign
   1.266 +						*/ 
   1.267 +						CCustomTextCursor* customTextCursor=NULL;
   1.268 +						TRAPD(error, customTextCursor=CCustomTextCursor::CreateCustomTextCursorL((TInt)aScreenNumber,0,iStaticTest));
   1.269 +						if (error==KErrNone)
   1.270 +							{
   1.271 +							error = ws.SetCustomTextCursor(KTextCursorPanicUid4, customTextCursor->iSpriteMemberArray.Array(), 0, (RWsSession::TCustomTextCursorAlignment)(RWsSession::ECustomTextCursorAlignBottom+1));
   1.272 +							if (error==KErrNone || error==KErrAlreadyExists)
   1.273 +								{
   1.274 +								tc.iType=(TTextCursor::EType)KTextCursorPanicUid4;
   1.275 +								group.SetTextCursor(wnd,TPoint(10,10),tc);
   1.276 +								}
   1.277 +							}
   1.278 +						delete customTextCursor;
   1.279 +						}
   1.280 +						break;
   1.281 +					case 4:
   1.282 +						{
   1.283 +						/* TESTCASE:	6.5
   1.284 +						* TITLE:		Use of an invalid custom text cursor
   1.285 +						* IMPORTANCE:	1
   1.286 +						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
   1.287 +						* 
   1.288 +						* ACTION:		This test tries to set a custom text cursor which does not have
   1.289 +						*				any sprite member set.
   1.290 +						* 
   1.291 +						* CHECK:		The thread should panic with the exit reason EWservPanicNoSpriteMember
   1.292 +						*/ 
   1.293 +						RArray<TSpriteMember> spriteMemberArray;
   1.294 +						const TInt error = ws.SetCustomTextCursor(KTextCursorPanicUid5, spriteMemberArray.Array(), 0, (RWsSession::TCustomTextCursorAlignment)(RWsSession::ECustomTextCursorAlignBottom));
   1.295 +						if (error==KErrNone || error==KErrAlreadyExists)
   1.296 +							{
   1.297 +							tc.iType=(TTextCursor::EType)KTextCursorPanicUid5;
   1.298 +							group.SetTextCursor(wnd,TPoint(10,10),tc);
   1.299 +							}
   1.300 +						}
   1.301 +						break;
   1.302 +					case 5:
   1.303 +						{
   1.304 +						// Uncover set.cursor.iType < TTextCursor::ETypeFirst code path
   1.305 +						tc.iType=(TTextCursor::EType)TTextCursor::ETypeFirst - 1;
   1.306 +						group.SetTextCursor(wnd,TPoint(10,10),tc);
   1.307 +						}
   1.308 +						break;
   1.309 +					case 6:
   1.310 +						{
   1.311 +						// Uncover (set.cursor.iFlags&static_cast<TUint>(TTextCursor::EPrivateFlags) code path
   1.312 +						tc.iFlags=ETextCursorPrivateFlags;
   1.313 +						group.SetTextCursor(wnd,TPoint(10,10),tc);
   1.314 +						}
   1.315 +						break;
   1.316 +					case 7:
   1.317 +						{
   1.318 +						// Uncover (iGroupWin != searchWin) i.e. bogus group window
   1.319 +						tc.iType=(TTextCursor::EType)TTextCursor::ETypeRectangle;
   1.320 +						RWindow windowNotAssociatedWithAGroup(ws);
   1.321 +						group.SetTextCursor(windowNotAssociatedWithAGroup, TPoint(10,10),tc);
   1.322 +						}
   1.323 +						break;
   1.324 +					}
   1.325 +				}
   1.326 +			ws.Flush();
   1.327 +			}
   1.328 +		}
   1.329 +	return(EWsExitReasonBad);
   1.330 +	}
   1.331 +
   1.332 +void CTCursorTest::TestPanicsL()
   1.333 +	{	
   1.334 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicInvalidTextCursor, 0, (TAny*)iTest->iScreenNumber));
   1.335 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicWindow, 1, (TAny*)iTest->iScreenNumber));
   1.336 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicNoCustomTextCursor, 2, (TAny*)iTest->iScreenNumber));
   1.337 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicCustomTextCursorAlign, 3, (TAny*)iTest->iScreenNumber));
   1.338 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicNoSpriteMember, 4, (TAny*)iTest->iScreenNumber));
   1.339 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicInvalidTextCursor, 5, (TAny*)iTest->iScreenNumber));
   1.340 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicInvalidTextCursor, 6, (TAny*)iTest->iScreenNumber));
   1.341 +		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicWindow, 7, (TAny*)iTest->iScreenNumber));
   1.342 +		iTest->CloseAllPanicWindows();
   1.343 +	}
   1.344 +
   1.345 +void CTCursorTest::TextCursorSetLCoverageTests()
   1.346 +	{
   1.347 +	ValidateWin(BaseWin,TRgb::Gray256(255));
   1.348 +	ValidateWin(TestWin,TRgb::Gray256(255));	
   1.349 +	TTextCursor textCursor;
   1.350 +	textCursor.iHeight = 10;
   1.351 +	textCursor.iAscent = 0;
   1.352 +	textCursor.iWidth = 10;
   1.353 +	textCursor.iFlags = 0;
   1.354 +	textCursor.iColor = KRgbBlack;
   1.355 +	textCursor.iType = (TTextCursor::EType)TTextCursor::ETypeRectangle;
   1.356 +	TPoint position(10, 10);
   1.357 +	TRect clipRect0(10, 10, 10, 10);
   1.358 +	TRect clipRect1(10, 10, 5, 5);
   1.359 +	RWindowGroup *group = TheClient->iGroup->GroupWin(); 
   1.360 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.361 +	/*
   1.362 +	 * Duplicate the previous SetTextCursor command to uncover the code which checks for any delta in SetL
   1.363 +	 * compared to the current settings.
   1.364 +	 */
   1.365 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.366 +	/*
   1.367 +	 * Change the type only to pick up that difference in SetL.
   1.368 +	 */
   1.369 +	textCursor.iType++;
   1.370 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.371 +	textCursor.iType--;
   1.372 +	/*
   1.373 +	 * Vary the clipping rectangle.
   1.374 +	 */
   1.375 +	group->SetTextCursor(*TestWin->Win(), position, textCursor, clipRect0);
   1.376 +	group->SetTextCursor(*TestWin->Win(), position, textCursor, clipRect1);
   1.377 +	/*
   1.378 +	 * Vary the color.
   1.379 +	 */
   1.380 +	textCursor.iColor = KRgbGreen;
   1.381 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.382 +	textCursor.iColor = KRgbBlack;
   1.383 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.384 +	/*
   1.385 +	 * Vary the target Window.
   1.386 +	 */
   1.387 +	group->SetTextCursor(*BaseWin->Win(), position, textCursor);
   1.388 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.389 +	/*
   1.390 +	 * Vary the size of the cursor.
   1.391 +	 */
   1.392 +	textCursor.iWidth++;
   1.393 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.394 +	textCursor.iWidth--;
   1.395 +	/*
   1.396 +	 * Set different custom cursors.
   1.397 +	 */
   1.398 +	CCustomTextCursorsWrapper* customTextCursorsWrapper = CCustomTextCursorsWrapper::NewLC(iTest->iScreenNumber, iTest);
   1.399 +	const TInt count = customTextCursorsWrapper->CustomTextCursorsArray().Count();
   1.400 +	for (TInt index=0; index<count; ++index)
   1.401 +		{
   1.402 +		CCustomTextCursor& customTextCursor = customTextCursorsWrapper->CustomTextCursor(index);
   1.403 +		textCursor.iType = customTextCursor.iIdentifier;
   1.404 +		group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.405 +		}			
   1.406 +	CleanupStack::PopAndDestroy(customTextCursorsWrapper);
   1.407 +	/*
   1.408 +	 * Set the last custom cursor from the above loop again so the
   1.409 +	 * product code sees the same Custom Text Cursor settings come
   1.410 +	 * in a second time.
   1.411 +	 */
   1.412 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.413 +	textCursor.iType = (TTextCursor::EType)TTextCursor::ETypeRectangle;
   1.414 +	/*
   1.415 +	 * Vary the horizontal clipping.
   1.416 +	 */
   1.417 +	textCursor.iFlags = TTextCursor::EFlagClipHorizontal;
   1.418 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.419 +	/*
   1.420 +	 * Vary the horizontal clipping.
   1.421 +	 */
   1.422 +	textCursor.iFlags = TTextCursor::EFlagClipVertical;
   1.423 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.424 +	/*
   1.425 +	 * Try both horizontal and vertical clipping.
   1.426 +	 */
   1.427 +	textCursor.iFlags = TTextCursor::EFlagClipVertical|TTextCursor::EFlagClipHorizontal;
   1.428 +	group->SetTextCursor(*TestWin->Win(), position, textCursor);
   1.429 +	textCursor.iFlags = 0;
   1.430 +	
   1.431 +	TheClient->iWs.Flush();
   1.432 +	CancelTextCursor();
   1.433 +	}
   1.434 +
   1.435 +void CTCursorTest::SetCursor(const TPoint &aPos,const TSize &aSize,TRgb aColor, const TRect &aRect, TUint aFlags)
   1.436 +	{
   1.437 +	TTextCursor tc;
   1.438 +	tc.iType=iCursorType;
   1.439 +    tc.iHeight=aSize.iHeight;
   1.440 +    tc.iAscent=aSize.iHeight*4/5;
   1.441 +    tc.iWidth=aSize.iWidth;
   1.442 +    tc.iFlags=aFlags;
   1.443 +	tc.iColor=aColor;
   1.444 +	TheClient->iGroup->GroupWin()->SetTextCursor(*TestWin->Win(),TPoint(aPos.iX,aPos.iY+tc.iAscent),tc,aRect);
   1.445 +	}
   1.446 +
   1.447 +void CTCursorTest::SetCursor(const TPoint &aPos,const TSize &aSize,TRgb aColor, TUint aFlags)
   1.448 +	{
   1.449 +	TTextCursor tc;
   1.450 +	tc.iType=iCursorType;
   1.451 +    tc.iHeight=aSize.iHeight;
   1.452 +    tc.iAscent=aSize.iHeight*4/5;
   1.453 +    tc.iWidth=aSize.iWidth;
   1.454 +    tc.iFlags=aFlags;
   1.455 +	tc.iColor=aColor;
   1.456 +	TheClient->iGroup->GroupWin()->SetTextCursor(*TestWin->Win(),TPoint(aPos.iX,aPos.iY+tc.iAscent),tc);
   1.457 +	}
   1.458 +
   1.459 +void CTCursorTest::SetCursorPlusBox(const TPoint &aPos,const TSize &aSize,TRgb aColor, const TRect *aClipRect, TUint aFlags)
   1.460 +	{
   1.461 +	if (aClipRect)
   1.462 +		SetCursor(aPos,aSize,aColor,*aClipRect,aFlags);
   1.463 +	else
   1.464 +		SetCursor(aPos,aSize,aColor,aFlags);
   1.465 +	TRect rect(aPos,aSize);
   1.466 +	if (aClipRect)
   1.467 +		rect.Intersection(*aClipRect);
   1.468 +	rect.Grow(2,2);
   1.469 +	
   1.470 +	TheClient->iGc->Activate(*(TestWin->Win()));
   1.471 +	TestWin->Invalidate(rect);
   1.472 +	TestWin->Win()->BeginRedraw(rect);
   1.473 +	TheClient->iGc->SetPenColor(aColor);
   1.474 +	TheClient->iGc->SetDrawMode(CGraphicsContext::EDrawModeXOR);
   1.475 +
   1.476 +	TheClient->iGc->DrawRect(rect);
   1.477 +	TheClient->iGc->Deactivate();
   1.478 +	TestWin->Win()->EndRedraw();
   1.479 +	
   1.480 +	}
   1.481 +
   1.482 +void CTCursorTest::CancelTextCursor()
   1.483 +	{
   1.484 +	TheClient->iGroup->GroupWin()->CancelTextCursor();
   1.485 +	}
   1.486 +
   1.487 +void CTCursorTest::ConstructL()
   1.488 +	{
   1.489 +	// for allocating some cached memory
   1.490 +	CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
   1.491 +	CleanupStack::PushL(bitmap);
   1.492 +	User::LeaveIfError(bitmap->Load(TEST_BITMAP_NAME, 0));
   1.493 +	CleanupStack::PopAndDestroy(bitmap);
   1.494 +
   1.495 +	CCustomTextCursorsWrapper* customTextCursorsWrapper = CCustomTextCursorsWrapper::NewLC(iTest->iScreenNumber, iTest);
   1.496 +	const TInt count = customTextCursorsWrapper->CustomTextCursorsArray().Count();
   1.497 +	for (TInt index=0; index<count; ++index)
   1.498 +		{
   1.499 +		CCustomTextCursor& customTextCursor = customTextCursorsWrapper->CustomTextCursor(index);
   1.500 +		TInt err = TheClient->iWs.SetCustomTextCursor(customTextCursor.iIdentifier, customTextCursor.iSpriteMemberArray.Array(), customTextCursor.iSpriteFlags, customTextCursor.iAlignment);
   1.501 +		TEST(err == KErrNone || err == KErrAlreadyExists);
   1.502 +		if (err!=KErrNone && err != KErrAlreadyExists)
   1.503 +			INFO_PRINTF4(_L("TheClient->iWs.SetCustomTextCursor return value  - Expected: %d or %d, Actual: %d"), KErrNone, KErrAlreadyExists, err);
   1.504 +
   1.505 +		__UHEAP_MARK;
   1.506 +		err = TheClient->iWs.SetCustomTextCursor(customTextCursor.iIdentifier, customTextCursor.iSpriteMemberArray.Array(), customTextCursor.iSpriteFlags, customTextCursor.iAlignment);
   1.507 +		__UHEAP_MARKEND;
   1.508 +		TEST(err == KErrAlreadyExists);
   1.509 +		if (err != KErrAlreadyExists)
   1.510 +			INFO_PRINTF3(_L("TheClient->iWs.SetCustomTextCursor return value  - Expected: %d, Actual: %d"), KErrAlreadyExists, err);
   1.511 +
   1.512 +		}
   1.513 +	_LIT(KLog,"Text Cursor: Loaded %d Custom Cursors");
   1.514 +	TLogMessageText buf;
   1.515 +	buf.Format(KLog,count);
   1.516 +	TheClient->LogMessage(buf);
   1.517 +	CleanupStack::PopAndDestroy(customTextCursorsWrapper);
   1.518 +//
   1.519 +	ValidateWin(BaseWin,TRgb::Gray256(204));
   1.520 +	ValidateWin(TestWin,TRgb::Gray256(204));
   1.521 +//
   1.522 +	SetCursor(TPoint(10,90),TSize(80,100),TRgb(255,255,255));
   1.523 +//
   1.524 +	iWinState=0;
   1.525 +	iWinPos=TPoint(2*TheClient->iGroup->Size().iWidth/3,0);
   1.526 +//
   1.527 +	iMoveWin=new(ELeave) CBlankWindow(TRgb::Gray256(220));
   1.528 +	TDisplayMode mode=EGray16;
   1.529 +	TInt testWinWidth = TestWin->Size().iWidth;
   1.530 +	TInt halfTestWinWidth = testWinWidth/2;
   1.531 +	TInt halfTestWinHeight = TestWin->Size().iHeight/2;
   1.532 +	
   1.533 +	iMoveWin->SetUpL(iWinPos,TSize(halfTestWinHeight,halfTestWinHeight),
   1.534 +			TheClient->iGroup,*TheClient->iGc,&mode);
   1.535 +
   1.536 +	iCheckWin=new(ELeave) CBlankWindow(TRgb::Gray256(220));
   1.537 +	iCheckWin->SetUpL(TPoint(testWinWidth+halfTestWinWidth,halfTestWinHeight),
   1.538 +			TSize(halfTestWinWidth,halfTestWinHeight),
   1.539 +			TheClient->iGroup,*TheClient->iGc,&mode);
   1.540 +	}
   1.541 +
   1.542 +void CTCursorTest::DeleteMoveWindows()
   1.543 +	{
   1.544 +	delete iMoveWin;
   1.545 +	delete iCheckWin;
   1.546 +	CancelTextCursor();
   1.547 +	}
   1.548 +
   1.549 +void CTCursorTest::ResetMoveWindowsL()
   1.550 +	{
   1.551 +	SetCursor(TPoint(10,90),TSize(80,100),TRgb(255,255,255));
   1.552 +	iWinState=0;
   1.553 +	iWinPos=TPoint(2*TheClient->iGroup->Size().iWidth/3,0);
   1.554 +	iMoveWin->SetExtL(iWinPos,TSize(TestWin->Size().iWidth/2,TestWin->Size().iHeight/2));
   1.555 +	iCheckWin->SetExtL(TPoint(TestWin->Size().iWidth+(TestWin->Size().iWidth>>1),TestWin->Size().iHeight>>1),
   1.556 +														TSize(TestWin->Size().iWidth/2,TestWin->Size().iHeight/2));
   1.557 +	}
   1.558 +
   1.559 +TBool CTCursorTest::MoveWindow()
   1.560 +	{
   1.561 +	TSize scrSize(TheClient->iScreen->SizeInPixels());
   1.562 +	iWinState++;
   1.563 +	if (iWinState<20)
   1.564 +		iWinPos+=TPoint((4*scrSize.iWidth)/640,(4*scrSize.iHeight)/240);
   1.565 +	else if (iWinState<40)
   1.566 +		iWinPos+=TPoint((1*scrSize.iWidth)/640,(-3*scrSize.iHeight)/240);
   1.567 +	else if (iWinState<60)
   1.568 +		iWinPos+=TPoint((-6*scrSize.iWidth)/640,(3*scrSize.iHeight)/240);
   1.569 +	else
   1.570 +		iWinPos+=TPoint((1*scrSize.iWidth)/640,(-2*scrSize.iHeight)/240);
   1.571 +	iMoveWin->SetPos(iWinPos);
   1.572 +	return (iWinState==80);
   1.573 +	}
   1.574 +
   1.575 +void CTCursorTest::ValidateWin(TestWindow *aWin, TRgb aColor)
   1.576 +	{
   1.577 +	aWin->Win()->Invalidate();
   1.578 +	RedrawWin(*aWin->Win(),aColor);
   1.579 +	}
   1.580 +
   1.581 +void CTCursorTest::RedrawWin(RWindow &aWin, TRgb aColor)
   1.582 +	{
   1.583 +	aWin.BeginRedraw();
   1.584 +	TheClient->iGc->Activate(aWin);
   1.585 +	TheClient->iGc->SetBrushColor(aColor);
   1.586 +	TheClient->iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
   1.587 +	TheClient->iGc->SetPenStyle(CGraphicsContext::ENullPen);
   1.588 +	TheClient->iGc->Clear();
   1.589 +	TheClient->iGc->Deactivate();
   1.590 +	aWin.EndRedraw();
   1.591 +	}
   1.592 +
   1.593 +void CTCursorTest::ScrollTest()
   1.594 +	{
   1.595 +	const TSize size(20,40);
   1.596 +	ValidateWin(TestWin,TRgb::Gray256(255));
   1.597 +
   1.598 +	SetCursor(TPoint(10,20),size,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
   1.599 +	TheClient->iWs.Flush();
   1.600 +	TheClient->WaitForRedrawsToFinish();
   1.601 +	TheClient->iWs.Finish();
   1.602 +
   1.603 +	for(TInt ii=0;ii<20;ii++)
   1.604 +		{
   1.605 +		TInt dist=(ii&3)*2;
   1.606 +		TInt nx=ii&0x1?1:-1;
   1.607 +		TInt ny=ii&0x2?1:-1;
   1.608 +		TestWin->Win()->Scroll(TPoint(dist*nx,dist*ny),TRect(10,20,30,40));
   1.609 +		TheClient->iWs.Flush();
   1.610 +		}
   1.611 +	TheClient->WaitForRedrawsToFinish();
   1.612 +	TheClient->iWs.Finish();
   1.613 +
   1.614 +	BaseWin->Win()->Invalidate();
   1.615 +	BaseWin->Win()->BeginRedraw();
   1.616 +	TheClient->iGc->Activate(*(BaseWin->Win()));
   1.617 +	TheClient->iGc->Clear();
   1.618 +	TheClient->iGc->SetBrushColor(TRgb::Gray256(255));
   1.619 +	TheClient->iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
   1.620 +	TheClient->iGc->SetPenStyle(CGraphicsContext::ENullPen);
   1.621 +	TheClient->iGc->Clear(TRect(TPoint(10,20),size));
   1.622 +	TheClient->iGc->Deactivate();
   1.623 +	BaseWin->Win()->EndRedraw();
   1.624 +
   1.625 +	TheClient->iWs.Flush();
   1.626 +	TheClient->WaitForRedrawsToFinish();
   1.627 +	TheClient->iWs.Finish();
   1.628 +
   1.629 +	/*
   1.630 +	 * NOTE: Reason for removal of COMPARE_WINDOWS_SOFTFAIL_WINSCW
   1.631 +	 * Due to the new implementation of sprites in wserv2, the sprites no longer keep a 
   1.632 +	 * backup bitmap of what the screen looks like beneath them. As it is not possible to 
   1.633 +	 * move the sprites associated with the custom text cursors that were created in second 
   1.634 +	 * phase construction of the CTCursorTest object, the COMPARE_WINDOWS_SOFTFAIL_WINSCW; 
   1.635 +	 * macro function has been removed. Otherwise the test case is going to subject to the
   1.636 +	 * timing of the flashing sprite. An alternative solution would be to assign NULL values
   1.637 +	 * to the sprite bitmaps in second phase construction, but this is avoided as it would
   1.638 +	 * trigger failures in some test cases later on (that are depended on these "embedded"
   1.639 +	 * sprite images).
   1.640 +	 */	
   1.641 +	CancelTextCursor();
   1.642 +	}
   1.643 +
   1.644 +void DrawTestSprite(CBitmapContext *aGc,TInt , const TSize &aSize, TBool aDoMask, TAny *)
   1.645 +	{
   1.646 +	aGc->SetBrushColor(TRgb::Gray4(aDoMask ? 0 : 2));
   1.647 +	aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
   1.648 +	aGc->SetPenStyle(CGraphicsContext::ENullPen);
   1.649 +	aGc->DrawRect(TRect(aSize));
   1.650 +	aGc->SetPenStyle(CGraphicsContext::ESolidPen);
   1.651 +	aGc->SetPenColor(TRgb::Gray4(aDoMask ? 3 : 0));
   1.652 +	aGc->SetBrushColor(TRgb::Gray4(aDoMask ? 3 : 1));
   1.653 +	aGc->DrawEllipse(TRect(aSize));
   1.654 +	}
   1.655 +
   1.656 +CTSprite *CTCursorTest::CreateTestSpriteLC(RWindowTreeNode &aWindow, const TPoint &aPos, TInt aCount)
   1.657 +//
   1.658 +// At the moment aCount must be 1 or 2
   1.659 +//
   1.660 +	{
   1.661 +	TSpriteCreateParams params(TSize(30,70),TPoint(0,0),DrawTestSprite);
   1.662 +	TSpriteCreateParams paramarray[2];
   1.663 +	params.iInterval=TTimeIntervalMicroSeconds32(200000);
   1.664 +
   1.665 +	paramarray[0]=params;
   1.666 +	paramarray[1]=params;
   1.667 +	paramarray[1].iSize=TSize(100,10);
   1.668 +	CTSprite *sprite=new(ELeave) CTSprite(TheClient->iWs);
   1.669 +	CleanupStack::PushL(sprite);
   1.670 +	sprite->ConstructL(aWindow,aPos,aCount,&paramarray[0],0);
   1.671 +	return(sprite);
   1.672 +	}
   1.673 +
   1.674 +void CTCursorTest::doMoveWindowTestL()
   1.675 +	{
   1.676 +	RBlankWindow blankwin(TheClient->iWs);
   1.677 +	User::LeaveIfError(blankwin.Construct(*TestWin->Win(),1));
   1.678 +	CleanupStack::PushL(TCleanupItem(CleanUpWindow,&blankwin));
   1.679 +//
   1.680 +	blankwin.SetExtent(TPoint(35,165),TSize(40,40));
   1.681 +	blankwin.SetColor(TRgb::Gray256(220));
   1.682 +	blankwin.Activate();
   1.683 +	TheClient->iWs.SetAutoFlush(ETrue);
   1.684 +	User::After(500000);
   1.685 +	blankwin.SetPosition(TPoint(25,55));
   1.686 +	User::After(500000);
   1.687 +	blankwin.SetPosition(TPoint(30,160));
   1.688 +	User::After(500000);
   1.689 +	blankwin.SetPosition(TPoint(12,22));	// Almost totally covering sprite
   1.690 +	User::After(500000);
   1.691 +	blankwin.SetPosition(TPoint(-100,-100));	// Totally off the sprite
   1.692 +	User::After(500000);
   1.693 +	blankwin.SetPosition(TPoint(10,20));	// Write on top of sprite
   1.694 +	User::After(500000);
   1.695 +	blankwin.SetPosition(TPoint(24,24));	// moving off...
   1.696 +	User::After(500000);
   1.697 +	blankwin.SetPosition(TPoint(38,28));	// ...
   1.698 +	User::After(500000);
   1.699 +	blankwin.SetPosition(TPoint(58,48));	// ...
   1.700 +	User::After(500000);
   1.701 +	blankwin.SetPosition(TPoint(92,62));	// ... off
   1.702 +	User::After(500000);
   1.703 +	CleanupStack::PopAndDestroy();	// blank window
   1.704 +	TheClient->iWs.Flush();
   1.705 +	TheClient->WaitForRedrawsToFinish();
   1.706 +	TheClient->iWs.Finish();
   1.707 +
   1.708 +	TheClient->iWs.SetAutoFlush(EFalse);
   1.709 +	}
   1.710 +
   1.711 +void CTCursorTest::MoveWindowTest1L()
   1.712 +	{
   1.713 +	ValidateWin(TestWin,TRgb::Gray256(255));
   1.714 +// Check it with a static sprite
   1.715 +	CTSprite * sprite_static = CreateTestSpriteLC(*TestWin->Win(), TPoint(10,20), 1);
   1.716 +	doMoveWindowTestL();
   1.717 +	(sprite_static->Sprite()).SetPosition(TPoint(500,500)); //move the sprite out of the viewing area before the window comparison 
   1.718 +	CleanupStack::PopAndDestroy(1);	// sprite
   1.719 +// Check it an animated sprite
   1.720 +	CTSprite * sprite_anim = CreateTestSpriteLC(*TestWin->Win(), TPoint(10,20), 2);
   1.721 +	doMoveWindowTestL();
   1.722 +	(sprite_anim->Sprite()).SetPosition(TPoint(500,500)); //move the sprite out of the viewing area before the window comparison
   1.723 +	CleanupStack::PopAndDestroy(1);	// sprite
   1.724 +	}
   1.725 +
   1.726 +void CTCursorTest::MoveWindowTest2L()
   1.727 +	{
   1.728 +	const TSize size(20,40);
   1.729 +// Check it with a text cursor
   1.730 +	ValidateWin(TestWin,TRgb::Gray256(255));
   1.731 +	SetCursor(TPoint(10,25),size,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
   1.732 +	doMoveWindowTestL();
   1.733 +	CancelTextCursor();
   1.734 +// Check it with an anaimated sprite and a text cursor
   1.735 +	ValidateWin(TestWin,TRgb::Gray256(255));
   1.736 +	CTSprite * sprite_anim = CreateTestSpriteLC(*TestWin->Win(), TPoint(10,20), 2);
   1.737 +	SetCursor(TPoint(10,45),size,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
   1.738 +	doMoveWindowTestL();
   1.739 +	(sprite_anim->Sprite()).SetPosition(TPoint(500,500));
   1.740 +	CancelTextCursor();
   1.741 +	CleanupStack::PopAndDestroy(1);	// sprite
   1.742 +	}
   1.743 +
   1.744 +TBool CTCursorTest::IncrementCursorType()
   1.745 +	{
   1.746 +	// each screen has it own set of cursor
   1.747 +	//
   1.748 +	// the values would be ETypeLast=2 ETypeLastBasic=1009
   1.749 +	//
   1.750 +	if (iCursorType == TTextCursor::ETypeFirst)
   1.751 +		{
   1.752 +		iCursorType = (TTextCursor::EType)(TTextCursor::ETypeLastBasic + 1 + iTest->iScreenNumber*KNumberOfCustoTextCursors);
   1.753 +		return ETrue;
   1.754 +		}
   1.755 +	else if (iCursorType >= TTextCursor::ETypeLastBasic + (iTest->iScreenNumber+1)*KNumberOfCustoTextCursors)
   1.756 +		{
   1.757 +		iCursorType = TTextCursor::ETypeFirst;
   1.758 +		return EFalse;
   1.759 +		}
   1.760 +	else
   1.761 +		{
   1.762 +		iCursorType = (TTextCursor::EType)(iCursorType + 1);
   1.763 +		return ETrue;
   1.764 +		}
   1.765 +	}
   1.766 +
   1.767 +void CTCursorTest::GeneralTestsL()
   1.768 +	{
   1.769 +	const TInt winColor=255;		//Best to use Light Grey that is 170, but this code is bugged and doing so shows them up.
   1.770 +	ValidateWin(BaseWin,TRgb::Gray256(255));
   1.771 +	ValidateWin(TestWin,TRgb::Gray256(255));
   1.772 +	SetCursor(TPoint(-1000,10),TSize(10,30),TRgb::Gray256(255));
   1.773 +	TheClient->iWs.Flush();
   1.774 +	SetCursor(TPoint(10,10),TSize(10,30),TRgb::Gray256(255));
   1.775 +	TheClient->iWs.Flush();
   1.776 +	TRect rect(15,15,18,25);
   1.777 +	SetCursorPlusBox(TPoint(10,10),TSize(10,30),TRgb::Gray256(255), &rect);
   1.778 +	CancelTextCursor();
   1.779 +//
   1.780 +	ValidateWin(BaseWin,TRgb::Gray256(255));
   1.781 +	ValidateWin(TestWin,TRgb::Gray256(255));
   1.782 +	TheClient->iWs.Flush();
   1.783 +	for(TInt winType=0;winType<3;winType++)
   1.784 +		{
   1.785 +		RWindowBase *cursorwin=NULL;
   1.786 +		RBackedUpWindow backcursorwin(TheClient->iWs);
   1.787 +		RWindow backwindow(TheClient->iWs);
   1.788 +		RBlankWindow backblankwin(TheClient->iWs);
   1.789 +		switch(winType)
   1.790 +			{
   1.791 +			case 0:
   1.792 +				cursorwin=&backcursorwin;
   1.793 +				User::LeaveIfError(backcursorwin.Construct(*TestWin->BaseWin(),EGray4,1));
   1.794 +				break;
   1.795 +			case 1:
   1.796 +				cursorwin=&backwindow;
   1.797 +				User::LeaveIfError(backwindow.Construct(*TestWin->BaseWin(),1));
   1.798 +				break;
   1.799 +			case 2:
   1.800 +				cursorwin=&backblankwin;
   1.801 +				User::LeaveIfError(backblankwin.Construct(*TestWin->BaseWin(),1));
   1.802 +				break;
   1.803 +			}
   1.804 +		CleanupStack::PushL(TCleanupItem(CleanUpWindow,cursorwin));
   1.805 +		User::LeaveIfError(cursorwin->SetSizeErr(TestWin->BaseWin()->Size()));
   1.806 +		cursorwin->Activate();
   1.807 +//
   1.808 +		TTextCursor tc;
   1.809 +		tc.iType=iCursorType;
   1.810 +		tc.iHeight=30;
   1.811 +		tc.iAscent=0;
   1.812 +		tc.iWidth=50;
   1.813 +		tc.iFlags=0;
   1.814 +		tc.iColor=TRgb::Gray256(255);
   1.815 +		TheClient->iGroup->GroupWin()->SetTextCursor(*cursorwin,TPoint(10,10),tc);
   1.816 +//
   1.817 +		CreateTestSpriteLC(*cursorwin, TPoint(10,20), 2);
   1.818 +//
   1.819 +		if (cursorwin==&backwindow)
   1.820 +			RedrawWin(backwindow,TRgb::Gray256(255));
   1.821 +		for(TInt count=0;count<9;count++)
   1.822 +			{
   1.823 +			RWindowBase *pwin=NULL;
   1.824 +			RBackedUpWindow backedup(TheClient->iWs);
   1.825 +			RWindow window(TheClient->iWs);
   1.826 +			RBlankWindow blankwin(TheClient->iWs);
   1.827 +			switch(count%3)
   1.828 +				{
   1.829 +				case 0:
   1.830 +					pwin=&window;
   1.831 +					window.Construct(*cursorwin,2);
   1.832 +					window.SetBackgroundColor(TRgb(winColor,winColor,winColor));
   1.833 +					break;
   1.834 +				case 1:
   1.835 +					pwin=&backedup;
   1.836 +					backedup.Construct(*cursorwin,EGray4,2);
   1.837 +					break;
   1.838 +				case 2:
   1.839 +					pwin=&blankwin;
   1.840 +					blankwin.Construct(*cursorwin,2);
   1.841 +					blankwin.SetColor(TRgb(winColor,winColor,winColor));
   1.842 +					break;
   1.843 +				}
   1.844 +			CleanupStack::PushL(TCleanupItem(CleanUpWindow,pwin));
   1.845 +			pwin->SetExtentErr(TPoint(30,30),TSize(50,80));
   1.846 +			pwin->Activate();
   1.847 +			TheClient->iWs.Flush();
   1.848 +			CleanupStack::PopAndDestroy();	// window
   1.849 +			if (cursorwin==&backwindow)
   1.850 +				RedrawWin(backwindow,TRgb::Gray256(255));
   1.851 +			TheClient->iWs.Flush();
   1.852 +			TheClient->WaitForRedrawsToFinish();
   1.853 +			COMPARE_WINDOWS_SOFTFAIL_WINSCW;
   1.854 +			User::After(200000);	// Wait a fifth of a second to make sure the test is run during different states of flashing
   1.855 +			}
   1.856 +		for(TInt count2=0;count2<4;count2++)
   1.857 +			{
   1.858 +			cursorwin->SetPosition(TPoint(10,5));
   1.859 +			TheClient->iWs.Flush();
   1.860 +			User::After(100000);
   1.861 +			cursorwin->SetPosition(TPoint(5,10));
   1.862 +			TheClient->iWs.Flush();
   1.863 +			User::After(100000);
   1.864 +			cursorwin->SetPosition(TPoint(0,0));
   1.865 +			TheClient->iWs.Flush();
   1.866 +			User::After(100000);
   1.867 +			TheClient->WaitForRedrawsToFinish();
   1.868 +			COMPARE_WINDOWS_SOFTFAIL_WINSCW;
   1.869 +			}
   1.870 +		CleanupStack::PopAndDestroy(2);	// sprite & window containing sprite and cursor
   1.871 +		}
   1.872 +	CancelTextCursor();
   1.873 +	}
   1.874 +
   1.875 +void CTCursorTest::INC040489L()
   1.876 +	{
   1.877 +	INFO_PRINTF1(_L("AUTO_TCur INC040489 "));
   1.878 +	RWindowGroup group1(TheClient->iWs);
   1.879 +	PushWindowL(&group1);
   1.880 +	User::LeaveIfError(group1.Construct(ENullWsHandle));
   1.881 +	RBlankWindow blank1(TheClient->iWs);
   1.882 +	PushWindowL(&blank1);
   1.883 +	User::LeaveIfError(blank1.Construct(group1,ENullWsHandle));
   1.884 +	blank1.SetRequiredDisplayMode(EColor4K);
   1.885 +	blank1.SetColor(TRgb(250,150,0));
   1.886 +	blank1.Activate();
   1.887 +	RWindowGroup group2(TheClient->iWs);
   1.888 +	PushWindowL(&group2);
   1.889 +	User::LeaveIfError(group2.Construct(ENullWsHandle));
   1.890 +	RBlankWindow blank2(TheClient->iWs);
   1.891 +	PushWindowL(&blank2);
   1.892 +	User::LeaveIfError(blank2.Construct(group2,ENullWsHandle));
   1.893 +	blank2.SetRequiredDisplayMode(EColor4K);
   1.894 +	blank2.SetColor(TRgb(75,200,125));
   1.895 +	blank2.Activate();
   1.896 +	TheClient->Flush();
   1.897 +	INFO_PRINTF1(_L(" Created Windows "));
   1.898 +	TTextCursor tc;
   1.899 +	tc.iType=KTextCursorInitialIdValue + iTest->iScreenNumber*KNumberOfCustoTextCursors;
   1.900 +	tc.iHeight=80;
   1.901 +	tc.iAscent=10;
   1.902 +	tc.iWidth=30;
   1.903 +	tc.iFlags=0;
   1.904 +	tc.iColor=TRgb::Gray256(255);
   1.905 +	INFO_PRINTF1(_L(" About to Set Text Cursor 1 "));
   1.906 +	group2.SetTextCursor(blank2,TPoint(20,20),tc);
   1.907 +	TheClient->Flush();
   1.908 +	INFO_PRINTF1(_L(" Set Text Cursor 1 "));
   1.909 +	User::After(2000000);		//2sec
   1.910 +	TheClient->iWs.PrepareForSwitchOff();
   1.911 +	TheClient->Flush();
   1.912 +	User::After(2000000);		//2sec
   1.913 +	group1.SetOrdinalPosition(0);
   1.914 +	group2.CancelTextCursor();
   1.915 +	TheClient->Flush();
   1.916 +	INFO_PRINTF1(_L(" Canceled Text Cursor "));
   1.917 +	User::After(2000000);		//2sec
   1.918 +	//
   1.919 +	// Before applying the fix, the following operations makes the Custom Text 
   1.920 +	// Cursor Sprite invisible (happens even without wserv heartbeat suppression)
   1.921 +	INFO_PRINTF1(_L(" About to Set Text Cursor 2 "));
   1.922 +	group1.SetOrdinalPosition(2);
   1.923 +	group2.SetTextCursor(blank2,TPoint(20,20),tc);
   1.924 +	TheClient->Flush();
   1.925 +	INFO_PRINTF1(_L(" Set Text Cursor 2 "));
   1.926 +	User::After(2000000);		//2sec
   1.927 +	TRawEvent event;
   1.928 +	event.Set(TRawEvent::EActive);
   1.929 +	TheClient->iWs.SimulateRawEvent(event);
   1.930 +	TheClient->Flush();
   1.931 +	INFO_PRINTF1(_L(" Simulated Active Event "));
   1.932 +	User::After(2000000);		//2sec
   1.933 +	CleanupStack::PopAndDestroy(4, &group1);
   1.934 +	INFO_PRINTF1(_L(" End of test "));
   1.935 +	}
   1.936 +
   1.937 +void CTCursorTest::CursorUpdatedBeforeWindowRenderedL()
   1.938 +	{
   1.939 +	INFO_PRINTF1(_L("CursorUpdatedBeforeWindowRenderedL"));
   1.940 +	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0);
   1.941 +	// We use some unique looking colors otherwise its harder
   1.942 +	// to spot which test is which
   1.943 +	TRgb kAqua(134, 242, 251);
   1.944 +	
   1.945 +	iWorkInProgress = new(ELeave) CBlankWindow(kAqua);
   1.946 +	iComparisonWindow = new(ELeave) CBlankWindow(kAqua);
   1.947 +	CancelTextCursor();
   1.948 +	
   1.949 +	const TSize screenSize=TheClient->iGroup->Size();
   1.950 +	const TInt kPad = 5;
   1.951 +	const TInt kThirdOfScreenWidth = screenSize.iWidth/3;
   1.952 +	const TInt kWinWidth = kThirdOfScreenWidth - 2*kPad;
   1.953 +	const TInt kWinHeight = screenSize.iHeight - 2*kPad;
   1.954 +	const TSize kWinSize(kWinWidth, kWinHeight);
   1.955 +	const TPoint kCursorPos(30, 30);
   1.956 +	iComparisonWindow->SetUpL(TPoint(2*kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
   1.957 +	iWorkInProgress->SetUpL(  TPoint(  kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
   1.958 +	
   1.959 +	TTextCursor nonFlashingCursor;
   1.960 +	nonFlashingCursor.iType = TTextCursor::ETypeRectangle;
   1.961 +	nonFlashingCursor.iHeight=kCursorHeight;
   1.962 +	nonFlashingCursor.iAscent=0;
   1.963 +	nonFlashingCursor.iWidth=kCursorWidth;
   1.964 +	nonFlashingCursor.iFlags=TTextCursor::EFlagNoFlash;
   1.965 +	nonFlashingCursor.iColor = KRgbBlack; 
   1.966 +	TheClient->iGroup->GroupWin()->SetTextCursor(*iWorkInProgress->BaseWin(), kCursorPos, nonFlashingCursor);
   1.967 +	
   1.968 +	// Up till this point, there has not been a CWsWindow::Render() for iWorkInProgress
   1.969 +	// because the window has not been invalid
   1.970 +	
   1.971 +	/*
   1.972 +	 * Here is the crux of the test.  We want to create the following condition in a window group:
   1.973 +	 * 1) None of its windows have yet been Rendered using CWsWindow::Render()
   1.974 +	 * 2) A text cursor is present
   1.975 +	 * 3) Focus is lost then received
   1.976 +	 * 
   1.977 +	 * It used to be the case that Wserv picked up the handle to the Render Stage Text Cursor
   1.978 +	 * drawer upon a Refresh caused by Rendering the window.  But drawing the Text Cursor could
   1.979 +	 * come either from a Window Render or a change to the state of the Text Cursor, such as
   1.980 +	 * receiving focus in the window.  A bug was experienced when the Text Cursor was drawn in
   1.981 +	 * a window which never had been rendered.  This meant that the handle was not set up causing
   1.982 +	 * an assert.
   1.983 +	 * 
   1.984 +	 * The code has been modified since then, to setup the handle to the Render Stage Text
   1.985 +	 * Cursor during Wserv initialisation.  However, to guard against future changes, its
   1.986 +	 * worthwhile to have this corner case test to ensure it is possible to receive focus
   1.987 +	 * in a window which has never been rendered.  That is because the text cursor state
   1.988 +	 * is updated in such circumstances, and that might trigger a draw of the cursor in a
   1.989 +	 * future version of the text cursor code.
   1.990 +	 */
   1.991 +	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(1);  // lose focus
   1.992 +	TheClient->iWs.Finish();
   1.993 +	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0); // gain focus
   1.994 +	TheClient->iWs.Finish();
   1.995 +	
   1.996 +	// If we get this far without a panic or assert, we have passed this test.
   1.997 +	
   1.998 +	// Now allow CWsWindow::Render() to occur in iWorkInProgress
   1.999 +	// The reason for doing this is so that when you watch the test
  1.1000 +	// progress you can see visual confirmation via the progress message and
  1.1001 +	// the coloured windows appear on the screen.  Otherwise you would think
  1.1002 +	// that the test had either been skipped or had broken.
  1.1003 +	iWorkInProgress->Invalidate();
  1.1004 +	iWorkInProgress->Redraw();
  1.1005 +	iComparisonWindow->Invalidate();
  1.1006 +	iComparisonWindow->Redraw();
  1.1007 +	TheClient->iWs.Finish();
  1.1008 +	delete iWorkInProgress;
  1.1009 +	iWorkInProgress = NULL;
  1.1010 +	delete iComparisonWindow;
  1.1011 +	iComparisonWindow = NULL;
  1.1012 +	INFO_PRINTF1(_L("End of test"));
  1.1013 +	}
  1.1014 +
  1.1015 +void CTCursorTest::INC097774()
  1.1016 +	{
  1.1017 +	TTimeIntervalMicroSeconds32 initialRepeatRate;
  1.1018 +	TTimeIntervalMicroSeconds32 repeatRate;
  1.1019 +	TheClient->iWs.GetKeyboardRepeatRate(initialRepeatRate,repeatRate);
  1.1020 +	
  1.1021 +	//simulates a text cursor moving across the screen as if a user was holding down
  1.1022 +	//a key to scroll the cursor through a section of text.
  1.1023 +	//before applying the fix the cursor only shows up intermittently instead of smoothly
  1.1024 +	//scrolling across the screen.
  1.1025 +	const TSize cursorSize(3,20);
  1.1026 +	const TInt moveInterval=10;
  1.1027 +	SetCursor(TPoint(0,20),cursorSize,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
  1.1028 +	TheClient->Flush();
  1.1029 +	User::After(initialRepeatRate);
  1.1030 +	for(TInt offset=10;offset<=100;offset+=moveInterval)
  1.1031 +		{
  1.1032 +		SetCursor(TPoint(offset,20),cursorSize,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
  1.1033 +		TheClient->Flush();
  1.1034 +		User::After(repeatRate);
  1.1035 +		}
  1.1036 +		
  1.1037 +	//simulate clipped text cursor moving accross the screen
  1.1038 +	TRect rect(0,20,3,40);
  1.1039 +	SetCursor(TPoint(0,20),cursorSize,TRgb::Gray256(255),rect,TTextCursor::EFlagNoFlash);
  1.1040 +	TheClient->Flush();
  1.1041 +	User::After(initialRepeatRate);
  1.1042 +	for(TInt offset=10;offset<=100;offset+=moveInterval)
  1.1043 +		{
  1.1044 +		rect.Move(moveInterval,0);
  1.1045 +		SetCursor(TPoint(offset,20),cursorSize,TRgb::Gray256(255),rect,TTextCursor::EFlagNoFlash);
  1.1046 +		TheClient->Flush();
  1.1047 +		User::After(repeatRate);
  1.1048 +		}	
  1.1049 +	}
  1.1050 +/** What happens when a cursor becomes off-screen when the screen is resized/rotated? 
  1.1051 + * 
  1.1052 + * 
  1.1053 + **/
  1.1054 +void CTCursorTest::INC117232()
  1.1055 +	{
  1.1056 +	const TInt initialRepeatRate=300000;	// 3/10 seconds should be long enough to update everything!
  1.1057 +	TInt currMode=TheClient->iScreen->CurrentScreenMode();
  1.1058 +	TInt testMode=currMode;
  1.1059 +	TPixelsTwipsAndRotation currModeSize;
  1.1060 +	TheClient->iScreen->GetScreenModeSizeAndRotation(currMode, currModeSize);
  1.1061 +	//find a (rotated) mode where the dimensions of the screen shrank
  1.1062 +	for (TInt mode=0;mode<TheClient->iScreenModes.Count();mode++)
  1.1063 +		{
  1.1064 +		TPixelsTwipsAndRotation testModeSize;
  1.1065 +		TheClient->iScreen->GetScreenModeSizeAndRotation(mode,testModeSize);
  1.1066 +		if (	testModeSize.iPixelSize.iWidth<currModeSize.iPixelSize.iWidth-10
  1.1067 +			||	testModeSize.iPixelSize.iHeight<currModeSize.iPixelSize.iHeight-10
  1.1068 +			)
  1.1069 +			{
  1.1070 +			testMode=mode;
  1.1071 +			break;
  1.1072 +			}
  1.1073 +		}
  1.1074 +	if (testMode==currMode)
  1.1075 +		{
  1.1076 +		_LIT(KLog,"No smaller screen-size modes available - INC117232 test skipped");
  1.1077 +		LOG_MESSAGE(KLog);
  1.1078 +		//iStep->SetTestStepResult(EInconclusive);		//With this line the whole test fails which is too drastic
  1.1079 +		return;
  1.1080 +		}
  1.1081 +	//enable a cursor on the bottom right corner of the screen
  1.1082 +	TestWin->SetFullScreenExtL();
  1.1083 +	TheClient->Flush();
  1.1084 +	iCursorType=TTextCursor::ETypeRectangle;
  1.1085 +	SetCursor(TPoint(-20,-20)+TestWin->Size(),TSize(40,40),KRgbDarkMagenta,TTextCursor::EFlagNoFlash);
  1.1086 +	TheClient->Flush();
  1.1087 +	User::After(initialRepeatRate);
  1.1088 +	//shrink the screen
  1.1089 +	TheClient->iScreen->SetScreenMode(testMode);
  1.1090 +	TheClient->iScreen->SetAppScreenMode(testMode);
  1.1091 +	//The defect was that WServ would now crash! 
  1.1092 +	TheClient->Flush();
  1.1093 +	User::After(initialRepeatRate);
  1.1094 +	//Set everything back
  1.1095 +	TheClient->iScreen->SetScreenMode(currMode);
  1.1096 +	TheClient->iScreen->SetAppScreenMode(currMode);
  1.1097 +	TheClient->Flush();
  1.1098 +	User::After(initialRepeatRate);
  1.1099 +	}
  1.1100 +
  1.1101 +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
  1.1102 +/**
  1.1103 + * Sets up a text cursor whose attributes indicate it should not be flashing
  1.1104 + * and then checks to ensure this is the actual behaviour.
  1.1105 + */
  1.1106 +void CTCursorTest::TextCursorNoFlashTestL()
  1.1107 +	{
  1.1108 +	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0);
  1.1109 +	// We use some unique looking colors otherwise its harder
  1.1110 +	// to spot which test is which
  1.1111 +	TRgb kGentleYellow(251, 249, 198);
  1.1112 +	TRgb kGentlePink(253, 196, 221);
  1.1113 +	
  1.1114 +	iWorkInProgress = new(ELeave) CBlankWindow(kGentleYellow);
  1.1115 +	iComparisonWindow = new(ELeave) CBlankWindow(kGentleYellow);
  1.1116 +	CancelTextCursor();
  1.1117 +	TheClient->Flush();
  1.1118 +	
  1.1119 +	const TSize screenSize=TheClient->iGroup->Size();
  1.1120 +	const TInt kPad = 5;
  1.1121 +	const TInt kThirdOfScreenWidth = screenSize.iWidth/3;
  1.1122 +	const TInt kWinWidth = kThirdOfScreenWidth - 2*kPad;
  1.1123 +	const TInt kWinHeight = screenSize.iHeight - 2*kPad;
  1.1124 +	const TSize kWinSize(kWinWidth, kWinHeight);
  1.1125 +	const TPoint kCursorPos(30, 30);
  1.1126 +	iWorkInProgress->SetUpL(  TPoint(  kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
  1.1127 +	iComparisonWindow->SetUpL(TPoint(2*kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
  1.1128 +	
  1.1129 +	TTextCursor nonFlashingCursor;
  1.1130 +	
  1.1131 +	nonFlashingCursor.iType = TTextCursor::ETypeRectangle;
  1.1132 +	nonFlashingCursor.iHeight=kCursorHeight;
  1.1133 +	nonFlashingCursor.iAscent=0;
  1.1134 +	nonFlashingCursor.iWidth=kCursorWidth;
  1.1135 +	nonFlashingCursor.iFlags=TTextCursor::EFlagNoFlash;
  1.1136 +	nonFlashingCursor.iColor = kGentlePink; // We expect a Flicker Buffer Render Stage to ignore this color
  1.1137 +	
  1.1138 +	iWorkInProgress->Invalidate();
  1.1139 +	iWorkInProgress->Redraw();
  1.1140 +	iComparisonWindow->Invalidate();
  1.1141 +	iComparisonWindow->Redraw();
  1.1142 +	
  1.1143 +	DrawTextCursorSimilarToRenderStage(*TheClient->iGc, *iComparisonWindow->Win(), kCursorPos, nonFlashingCursor);
  1.1144 +	TheClient->iGroup->GroupWin()->SetTextCursor(*iWorkInProgress->BaseWin(), kCursorPos, nonFlashingCursor);
  1.1145 +	TheClient->Flush();
  1.1146 +		
  1.1147 +	CheckCursorDoesNotFlash(iWorkInProgress->BaseWin()->Size());
  1.1148 +	
  1.1149 +	delete iWorkInProgress;
  1.1150 +	iWorkInProgress = NULL;
  1.1151 +	delete iComparisonWindow;
  1.1152 +	iComparisonWindow = NULL;
  1.1153 +	}
  1.1154 +
  1.1155 +void CTCursorTest::TextCursorFlashTestL()
  1.1156 +	{
  1.1157 +	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0);
  1.1158 +	// We use some unique looking colors otherwise its harder
  1.1159 +	// to spot which test is which
  1.1160 +	TRgb kMildPurple(218, 155, 244);
  1.1161 +	TRgb kPaleGreen(146, 190, 12);
  1.1162 +	
  1.1163 +	iWorkInProgress = new(ELeave) CBlankWindow(kMildPurple);
  1.1164 +	iComparisonWindow = new(ELeave) CBlankWindow(kMildPurple);
  1.1165 +	CancelTextCursor();
  1.1166 +	TheClient->Flush();
  1.1167 +	
  1.1168 +	const TSize screenSize=TheClient->iGroup->Size();
  1.1169 +	const TInt kPad = 5;
  1.1170 +	const TInt kThirdOfScreenWidth = screenSize.iWidth/3;
  1.1171 +	const TInt kWinWidth = kThirdOfScreenWidth - 2*kPad;
  1.1172 +	const TInt kWinHeight = screenSize.iHeight - 2*kPad;
  1.1173 +	const TSize kWinSize(kWinWidth, kWinHeight);
  1.1174 +	const TPoint kCursorPos(30, 30);
  1.1175 +	iWorkInProgress->SetUpL(  TPoint(  kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
  1.1176 +	iComparisonWindow->SetUpL(TPoint(2*kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
  1.1177 +	
  1.1178 +	TTextCursor flashingCursor;
  1.1179 +	
  1.1180 +	flashingCursor.iType = TTextCursor::ETypeRectangle;
  1.1181 +	flashingCursor.iHeight=kCursorHeight;
  1.1182 +	flashingCursor.iAscent=0;
  1.1183 +	flashingCursor.iWidth=kCursorWidth;
  1.1184 +	flashingCursor.iFlags=0; // implies that cursor SHOULD flash
  1.1185 +	flashingCursor.iColor = kPaleGreen; // We expect a Flicker Buffer Render Stage to ignore this color
  1.1186 +
  1.1187 +	iWorkInProgress->Invalidate();
  1.1188 +	iWorkInProgress->Redraw();
  1.1189 +	iComparisonWindow->Invalidate();
  1.1190 +	iComparisonWindow->Redraw();
  1.1191 +	
  1.1192 +	DrawTextCursorSimilarToRenderStage(*TheClient->iGc, *iComparisonWindow->Win(), kCursorPos, flashingCursor);
  1.1193 +	TheClient->iGroup->GroupWin()->SetTextCursor(*iWorkInProgress->BaseWin(), kCursorPos, flashingCursor);
  1.1194 +	TheClient->Flush();
  1.1195 +	
  1.1196 +	CheckCursorDoesFlash(kCursorPos, flashingCursor, kMildPurple);
  1.1197 +	CancelTextCursor();
  1.1198 +	TheClient->Flush();
  1.1199 +	
  1.1200 +	delete iWorkInProgress;
  1.1201 +	iWorkInProgress = NULL;
  1.1202 +	delete iComparisonWindow;
  1.1203 +	iComparisonWindow = NULL;
  1.1204 +	}
  1.1205 +
  1.1206 +void CTCursorTest::DrawTextCursorSimilarToRenderStage(CWindowGc& aGc, RWindow& aWin, const TPoint& aPos, const TTextCursor& aTextCursor)
  1.1207 +	{
  1.1208 +	// This method duplicates the way in which the default FlickerBuffer Render
  1.1209 +	// Stage draws a Text Cursor of ETypeRectangle.  @see CFbRenderStage::DrawTextCursor
  1.1210 +	// This code must be kept in sync with the FlickerBuffer Render Stage
  1.1211 +	
  1.1212 +	ASSERT(aTextCursor.iType == TTextCursor::ETypeRectangle);
  1.1213 +	const TRect updatedRegion(aPos,TSize(aTextCursor.iWidth,aTextCursor.iHeight));
  1.1214 +	aWin.Invalidate();
  1.1215 +	aWin.BeginRedraw();
  1.1216 +	aGc.Activate(aWin);
  1.1217 +	aGc.Clear();
  1.1218 +	aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
  1.1219 +	aGc.SetBrushColor(KRgbBlack);
  1.1220 +	aGc.SetPenStyle(CGraphicsContext::ENullPen);
  1.1221 +	aGc.Clear(updatedRegion);
  1.1222 +	aGc.Deactivate();
  1.1223 +	aWin.EndRedraw();
  1.1224 +	}
  1.1225 +
  1.1226 +void CTCursorTest::CheckCursorDoesNotFlash(const TSize& aSize)
  1.1227 +	{
  1.1228 +	const TInt kSampleTime = 100000; // one tenth of a second
  1.1229 +	const TInt kSampleLimit = 100;
  1.1230 +	TInt sampleIteration = 0;
  1.1231 +	TBool comparisonOkay = EFalse;
  1.1232 +	
  1.1233 +	while (sampleIteration < kSampleLimit)
  1.1234 +		{	
  1.1235 +		comparisonOkay = DoCheckRect(iWorkInProgress, iComparisonWindow, TRect(TPoint(), aSize), CWsScreenDevice::EIncludeTextCursor);
  1.1236 +		if (!comparisonOkay)
  1.1237 +			{
  1.1238 +			INFO_PRINTF2(_L("CheckCursorDoesNotFlash difference found after %d milliseconds"), sampleIteration*100);
  1.1239 +			break;
  1.1240 +			}
  1.1241 +		sampleIteration++;
  1.1242 +		User::After(kSampleTime);
  1.1243 +		}
  1.1244 +	TEST(comparisonOkay);
  1.1245 +	}
  1.1246 +
  1.1247 +void CTCursorTest::UpdateCountersOnCursorTransition(
  1.1248 +		const TBool	aTransitionedToOn,
  1.1249 +		TTime& 		aNow,
  1.1250 +		TInt64&		aDeltaTime,
  1.1251 +		TTime&		aLastDeltaTime,
  1.1252 +		TInt&		aWarmUpIterations,
  1.1253 +		const TInt&	aFlashChangeTime,
  1.1254 +		const TInt&	aToleranceMargin,
  1.1255 +		TInt&		aSampleNumber,
  1.1256 +		TInt&		aToleranceViolations
  1.1257 +		)
  1.1258 +	{
  1.1259 +	_LIT(KTxtOn,	" On");
  1.1260 +	_LIT(KTxtOff,	"Off");
  1.1261 +	TBufC<3> transitionType;	
  1.1262 +	transitionType = aTransitionedToOn ? KTxtOn : KTxtOff;
  1.1263 +	
  1.1264 +	aNow.UniversalTime();
  1.1265 +	aDeltaTime = aNow.MicroSecondsFrom(aLastDeltaTime).Int64();
  1.1266 +	aLastDeltaTime = aNow;
  1.1267 +	
  1.1268 +	if (aWarmUpIterations > 0)
  1.1269 +		{
  1.1270 +		aWarmUpIterations--;
  1.1271 +		}
  1.1272 +	else
  1.1273 +		{
  1.1274 +		if (aDeltaTime > aFlashChangeTime + aToleranceMargin ||
  1.1275 +				aDeltaTime < aFlashChangeTime - aToleranceMargin)
  1.1276 +			{
  1.1277 +			INFO_PRINTF5(_L(" Iteration %d, Cursor %S after %d, errorDelta %d microseconds"),
  1.1278 +					aSampleNumber, &transitionType, I64INT(aDeltaTime), I64INT(aDeltaTime - aFlashChangeTime));
  1.1279 +			aToleranceViolations++;
  1.1280 +			}
  1.1281 +		}
  1.1282 +	}
  1.1283 +void CTCursorTest::CheckCursorDoesFlash(const TPoint& aPos, const TTextCursor& aTextCursor, TRgb /* aBackgroundColor */)
  1.1284 +	{	
  1.1285 +	
  1.1286 +	/**
  1.1287 +	 * Quality of Service based thresholding
  1.1288 +	 * 
  1.1289 +	 * The idea behind this test is to identify tolerances which would either
  1.1290 +	 * cause the test to fail when the user would perceive the text cursor as
  1.1291 +	 * not flashing uniformly, or would point to an unexpected delay outside
  1.1292 +	 * the way the flashing (and scheduling of animations) is supposed to work.
  1.1293 +	 * 
  1.1294 +	 * Potentially the cursor can be late if we miss a V-SYNC from hardware.  In
  1.1295 +	 * such cases we expect to see the cursor on the next frame.  Since the V-SYNC
  1.1296 +	 * is typically 1/50 second, a tolerance of two frames, or 1/25 second is reasonable.
  1.1297 +	 * 
  1.1298 +	 * If the cursor is delayed longer than this, say a long time of 1 second, but this
  1.1299 +	 * does not happen too often, then the user is likely to still be happy.  So we
  1.1300 +	 * set the period of testing to 60 seconds, and set the violations limit to 2.
  1.1301 +	 */
  1.1302 +	const TInt kOneSecond = 1000000;
  1.1303 +	const TInt kFlashPeriod = kOneSecond; 		// comprises one "ON" and one "OFF"
  1.1304 +	const TInt kToleranceFactor = 25; 			// meaning 1/25 of a Flash Period
  1.1305 +	const TInt kNumberTestFlashPeriods = 60;	// meaning 60 Flash Periods worth of testing
  1.1306 +	const TInt kMaximumToleranceViolations = 2;	// number of times an occassional flash may be late or early
  1.1307 +	
  1.1308 +	const TInt kToleranceMargin = kFlashPeriod / kToleranceFactor;
  1.1309 +	const TInt kNumberSamples = kNumberTestFlashPeriods * kToleranceFactor;
  1.1310 +	const TInt kFlashChangeTime = kFlashPeriod / 2;
  1.1311 +	
  1.1312 +	// The first couple of changes to the cursor should be ignored because
  1.1313 +	// when the test is started, the cursor may have been on for a while.
  1.1314 +	// Then when the cursor goes off, it appears to have switched to the
  1.1315 +	// off state too early.  We therefore ignore the first two changes
  1.1316 +	// so we start cleanly.
  1.1317 +	TInt warmUpIterations = 2;
  1.1318 +	
  1.1319 +	// Empirically we see that cursors mostly flash with good timeliness apart from
  1.1320 +	// occasional events causing them to be either early or late.  In order to keep
  1.1321 +	// a tight tolerance (1/50 second is around the screen refresh time) but still
  1.1322 +	// allow for the occasional variance (seen to be 1/23 second) we use a counter
  1.1323 +	// toleranceViolations < kMaximumToleranceViolations
  1.1324 +	TInt toleranceViolations = 0;
  1.1325 +	TBool cursorShownLastTime = EFalse;
  1.1326 +	TBool cursorShown = EFalse;
  1.1327 +	TTime lastDeltaTime;
  1.1328 +	TTime now;
  1.1329 +	TInt64 deltaTime = 0;
  1.1330 +	lastDeltaTime.UniversalTime();
  1.1331 +	now.UniversalTime();
  1.1332 +
  1.1333 +	TRect textCursorRect(TRect(aPos, TSize(aTextCursor.iWidth, aTextCursor.iHeight)));
  1.1334 +
  1.1335 +	for (TInt sampleNumber = 0; sampleNumber < kNumberSamples; sampleNumber++)
  1.1336 +		{
  1.1337 +		cursorShown = DoCheckRect(iWorkInProgress, iComparisonWindow, textCursorRect, CWsScreenDevice::EIncludeTextCursor);
  1.1338 +
  1.1339 +		if (cursorShown && !cursorShownLastTime)
  1.1340 +			{
  1.1341 +			cursorShownLastTime = ETrue;
  1.1342 +			UpdateCountersOnCursorTransition(
  1.1343 +					cursorShownLastTime, now, deltaTime, lastDeltaTime, warmUpIterations, kFlashChangeTime,
  1.1344 +					kToleranceMargin, sampleNumber, toleranceViolations);
  1.1345 +			}
  1.1346 +		else if (!cursorShown && cursorShownLastTime)
  1.1347 +			{
  1.1348 +			cursorShownLastTime = EFalse;
  1.1349 +			UpdateCountersOnCursorTransition(
  1.1350 +					cursorShownLastTime, now, deltaTime, lastDeltaTime, warmUpIterations, kFlashChangeTime,
  1.1351 +					kToleranceMargin, sampleNumber, toleranceViolations);
  1.1352 +			}
  1.1353 +
  1.1354 +		if (toleranceViolations > kMaximumToleranceViolations)
  1.1355 +			break;
  1.1356 +
  1.1357 +		User::After(kToleranceMargin);
  1.1358 +		}
  1.1359 +	// Check was some flashing
  1.1360 +	TEST_SOFTFAIL_WINSCW(warmUpIterations == 0);
  1.1361 +	// Check cursor flashed on and off, regularly and on-time
  1.1362 +	TEST_SOFTFAIL_WINSCW(toleranceViolations <= kMaximumToleranceViolations);
  1.1363 +	}
  1.1364 +#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
  1.1365 +
  1.1366 +void CTCursorTest::MakeCursors(TTextCursor& aTextCursor, TTextCursor& aCustomCursor)
  1.1367 +	{
  1.1368 +	aCustomCursor.iType = KTextCursorInitialIdValue + iTest->iScreenNumber*KNumberOfCustoTextCursors; // custom text cursor
  1.1369 +	aCustomCursor.iAscent=0;
  1.1370 +	aCustomCursor.iHeight=kCursorHeight;
  1.1371 +	aCustomCursor.iWidth=kCursorWidth;
  1.1372 +	aCustomCursor.iFlags=TTextCursor::EFlagNoFlash; 
  1.1373 +	aCustomCursor.iColor=TRgb::Color256(217);	
  1.1374 +		
  1.1375 +	// Create a standard cursor for the tests
  1.1376 +	aTextCursor.iType = TTextCursor::ETypeRectangle; // Normal rectangular text cursor
  1.1377 +	aTextCursor.iHeight=kCursorHeight;
  1.1378 +	aTextCursor.iAscent=0;
  1.1379 +	aTextCursor.iWidth=kCursorWidth;
  1.1380 +	aTextCursor.iFlags=TTextCursor::EFlagNoFlash;
  1.1381 +	}
  1.1382 +
  1.1383 +void CTCursorTest::StartDoubleCursorTestL(TInt aTestNumber)
  1.1384 +	{
  1.1385 +	// general setup
  1.1386 +	CBlankWindow* win1=new(ELeave) CBlankWindow(KRgbWhite);
  1.1387 +	CleanupStack::PushL(win1);
  1.1388 +
  1.1389 +	win1->SetUpL(kWin1TopLeft,kWinSize,TheClient->iGroup,*TheClient->iGc,EColor64K);
  1.1390 +	
  1.1391 +	win1->Redraw();
  1.1392 +	
  1.1393 +	// Create the second window
  1.1394 +	CBlankWindow* win2=new(ELeave) CBlankWindow(KRgbWhite);
  1.1395 +	CleanupStack::PushL(win2);
  1.1396 +
  1.1397 +	win2->SetUpL(kWin2TopLeft,kWinSize,TheClient->iGroup,*TheClient->iGc,EColor64K);
  1.1398 +	win2->Redraw();
  1.1399 +
  1.1400 +	// Create normal and custom cursor for the tests
  1.1401 +	TTextCursor textCursor;
  1.1402 +	TTextCursor customCursor;
  1.1403 +	MakeCursors(textCursor, customCursor);
  1.1404 +
  1.1405 +	TheClient->Flush();
  1.1406 +	CWindowGc* winGc = TheClient->iGc;	
  1.1407 +
  1.1408 +	switch(aTestNumber)
  1.1409 +		{
  1.1410 +		case 1:
  1.1411 +		CheckNoDoubleCursorTest1L(win1, win2, textCursor, customCursor, winGc);
  1.1412 +		break;
  1.1413 +		
  1.1414 +		case 2:
  1.1415 +		CheckNoDoubleCursorTest2L(win1, win2, textCursor, customCursor, winGc);
  1.1416 +		break;
  1.1417 +		
  1.1418 +		case 3:
  1.1419 +		CheckNoDoubleCursorTest3L(win1, win2, textCursor, customCursor, winGc);
  1.1420 +		break;
  1.1421 +		
  1.1422 +		default:
  1.1423 +		TEST(EFalse);
  1.1424 +		break;
  1.1425 +		}
  1.1426 +	CleanupStack::PopAndDestroy(2); 	
  1.1427 +	}
  1.1428 +
  1.1429 +// DEF098704
  1.1430 +void CTCursorTest::CheckNoDoubleCursorTest1L(CBlankWindow* aWin1, CBlankWindow* aWin2, TTextCursor& /*aTextCursor*/, TTextCursor& aCustomCursor, CWindowGc* aWinGc)
  1.1431 +	{
  1.1432 +	// Test that changing the focus of a custom text cursor does not leave that cursor drawn where it was (INC093898)
  1.1433 +
  1.1434 +	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),TPoint(),aCustomCursor);
  1.1435 +		
  1.1436 +	// Bit blit the TEST_BITMAP_NAME image to the second window to use as a comparison
  1.1437 +	// this is the same image that the custom cursor is using
  1.1438 +	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
  1.1439 +	CleanupStack::PushL(bitmap);
  1.1440 +	TEST(KErrNone == bitmap->Load(TEST_BITMAP_NAME,0,ETrue)); 
  1.1441 +
  1.1442 +	aWinGc->Activate(*aWin2->Win());
  1.1443 +	TRect updateArea(TPoint(0,0), bitmap->SizeInPixels());
  1.1444 +	aWin2->Win()->Invalidate(updateArea);
  1.1445 +	aWin2->Win()->BeginRedraw(updateArea);
  1.1446 +	aWinGc->BitBlt(TPoint(0,0),bitmap); 
  1.1447 +	aWinGc->Deactivate();
  1.1448 +	aWin2->Win()->EndRedraw();
  1.1449 +	TheClient->Flush();
  1.1450 +	doCheckNoDoubleCursor(aWin1,aWin2,kWin1TopLeft,kWin2TopLeft,aCustomCursor,bitmap->SizeInPixels(),CWsScreenDevice::EIncludeSprite);
  1.1451 +	CleanupStack::PopAndDestroy(1); // bitmap
  1.1452 +	}
  1.1453 +
  1.1454 +// DEF098704
  1.1455 +void CTCursorTest::CheckNoDoubleCursorTest2L(CBlankWindow* aWin1, CBlankWindow* aWin2, TTextCursor& /*aTextCursor*/, TTextCursor& aCustomCursor, CWindowGc* aWinGc)
  1.1456 +	{
  1.1457 +	//TEST 2: Checks that no artifacts are left behind when a text cursor is moved from under a transparent sprite
  1.1458 +	
  1.1459 +	// Construct the window win1 with a transparent sprite
  1.1460 +	
  1.1461 +	// Clear the top and bottom windows
  1.1462 +	ResetWindows(aWinGc,aWin1,aWin2);	
  1.1463 +	
  1.1464 +	// Create a bitmap and a corresponding bitmap mask
  1.1465 +	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
  1.1466 +	CleanupStack::PushL(bitmap);
  1.1467 +	TEST(KErrNone == bitmap->Load(TEST_BITMAP_NAME,0,ETrue)); 
  1.1468 +	CBitmap* spriteBitmap=CBitmap::NewL(kWinSize,EColor256);
  1.1469 +	CleanupStack::PushL(spriteBitmap);
  1.1470 +	spriteBitmap->Gc().SetBrushColor(KRgbBlack);
  1.1471 +	spriteBitmap->Gc().SetBrushStyle(CGraphicsContext::ESolidBrush);
  1.1472 +	spriteBitmap->Gc().SetPenStyle(CGraphicsContext::ESolidPen); 
  1.1473 +	spriteBitmap->Gc().DrawRect(TRect(kWinSize));
  1.1474 +	CBitmap* mask=CBitmap::NewL(kWinSize,EColor256);
  1.1475 +	CleanupStack::PushL(mask);
  1.1476 +	mask->Gc().SetBrushStyle(CGraphicsContext::ESolidBrush);
  1.1477 +	mask->Gc().SetBrushColor(KRgbBlack);
  1.1478 +	mask->Gc().DrawRect(TRect(kWinSize));	
  1.1479 +	
  1.1480 +	// Create a sprite
  1.1481 +	RWsSprite sprite = RWsSprite(TheClient->iWs);
  1.1482 +	CleanupClosePushL(sprite);
  1.1483 +	TEST(KErrNone == sprite.Construct(*aWin1->BaseWin(),TPoint(),0));
  1.1484 +	
  1.1485 +	// Add the bitmap to the sprite
  1.1486 +	TSpriteMember member;
  1.1487 +	member.iInvertMask=EFalse;
  1.1488 +	member.iDrawMode=CGraphicsContext::EDrawModePEN;
  1.1489 +	member.iOffset=TPoint();
  1.1490 +	member.iInterval=TTimeIntervalMicroSeconds32(0);
  1.1491 +	member.iBitmap = &spriteBitmap->Bitmap();
  1.1492 +	member.iMaskBitmap = &mask->Bitmap(); 
  1.1493 +	TEST(KErrNone == sprite.AppendMember(member));
  1.1494 +	
  1.1495 +	// Activate the sprite in win1
  1.1496 +	TEST(KErrNone == sprite.Activate());
  1.1497 +	
  1.1498 +	// Put a cursor in win1
  1.1499 +	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),TPoint(),aCustomCursor);
  1.1500 +	
  1.1501 +	// Bit blit the matching bitmap to the bottom window
  1.1502 +	TRect bitmapArea(TPoint(0,0), bitmap->SizeInPixels());
  1.1503 +	aWin2->Win()->Invalidate(bitmapArea);
  1.1504 +	aWin2->Win()->BeginRedraw(bitmapArea);
  1.1505 +	aWinGc->Activate(*aWin2->Win());
  1.1506 +	aWinGc->BitBlt(TPoint(),bitmap); 
  1.1507 +	aWinGc->Deactivate();
  1.1508 +	aWin2->Win()->EndRedraw();
  1.1509 +		
  1.1510 +	TheClient->Flush();
  1.1511 +	doCheckNoDoubleCursor(aWin1,aWin2,kWin1TopLeft,kWin2TopLeft,aCustomCursor,bitmap->SizeInPixels(),CWsScreenDevice::EIncludeSprite);
  1.1512 +	CleanupStack::PopAndDestroy(4); // sprite, mask, spriteBitmap, bitmap
  1.1513 +	}
  1.1514 +
  1.1515 +// DEF098704		
  1.1516 +void CTCursorTest::CheckNoDoubleCursorTest3L(CBlankWindow* aWin1, CBlankWindow* aWin2, TTextCursor& aTextCursor,TTextCursor& aCustomCursor, CWindowGc* aWinGc)
  1.1517 +	{
  1.1518 +	//
  1.1519 +	// TEST 3: Test a flashing text cursor does not leave artifacts when a redraw + change position happens during
  1.1520 +	// the time the cursor flashing 'off'
  1.1521 +	// 
  1.1522 +	// This test moves a flashing cursor a number of times over a two second period to a seconds position.
  1.1523 +	// it does it a number of times so some of the redraws will occur during the 'flash off' period
  1.1524 +	// We then compare the 'after' position to what we expect
  1.1525 +	// 
  1.1526 +	// There are four possible outcomes when we look at the bitmap after the redraw + move
  1.1527 +	// Position 1 is the original position, position 2 is the new position after the redraw
  1.1528 +	// 
  1.1529 +	// cursor artifact @ pos1 and flashed on cursor @ pos2
  1.1530 +	// cursor artifact at pos1 and flashed off cursor @ pos2
  1.1531 +	// no artifact at pos1 and flashed off cursor @ pos2
  1.1532 +	// no artifact at pos1 and flashed on cursor @ pos2
  1.1533 +	// 
  1.1534 +	// any artifacts left over will cause the complete test to fail.
  1.1535 +	//
  1.1536 +	
  1.1537 +	//
  1.1538 +	// PART A: 
  1.1539 +	aTextCursor.iFlags=0; 	// flashing
  1.1540 +
  1.1541 +	ResetWindows(aWinGc,aWin1,aWin2);	
  1.1542 +	TestForArtifacts(aWin1, aTextCursor);
  1.1543 +	
  1.1544 +	//
  1.1545 +	// PART B - For a non-custom text cursor
  1.1546 +	aCustomCursor.iFlags=0; // flashing
  1.1547 +
  1.1548 +	ResetWindows(aWinGc,aWin1,aWin2);	
  1.1549 +	TestForArtifacts(aWin1, aCustomCursor);	
  1.1550 +	}
  1.1551 +	
  1.1552 +// moves the cursor between two positions while flashing and tests no artifacts are left at the position it moved from
  1.1553 +// The moves take place in a loop so it is tested happening when the cursor is flashed on and also off
  1.1554 +void CTCursorTest::TestForArtifacts(CBlankWindow* aWin1, TTextCursor& aCursor)
  1.1555 +	{
  1.1556 +	const TInt KIterations = 30;
  1.1557 +	const TPoint kStartPos(0,0);
  1.1558 +	const TPoint kMoveToPos(200,0);
  1.1559 +	TRect r1(kWin1TopLeft,kCursorSize);
  1.1560 +	TRect r2(kWin2TopLeft,kCursorSize);
  1.1561 +	const TPoint kWin1TopLeft; 
  1.1562 +	const TPoint kWin2TopLeft; 
  1.1563 +	const TSize aCursorSize;
  1.1564 +
  1.1565 +	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),kStartPos,aCursor);
  1.1566 +	TheClient->Flush();
  1.1567 +
  1.1568 +	TInt initialRepeatRate = 1000000; 
  1.1569 +	const TInt KIncrement = 30000;
  1.1570 +	TInt i=0;
  1.1571 +
  1.1572 +	for(i=0; i<KIterations; i++)		
  1.1573 +		{
  1.1574 +		// move the cursor to its new position
  1.1575 +		TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),kMoveToPos,aCursor);
  1.1576 +		TheClient->Flush();
  1.1577 +
  1.1578 +		User::After(initialRepeatRate);
  1.1579 +		
  1.1580 +		// check no artifact was left in position 1 by comparing against (blank) win2
  1.1581 +		if(!TheClient->iScreen->RectCompare( r1,r2, CWsScreenDevice::EIncludeTextCursor))
  1.1582 +			{
  1.1583 +			break; // detected an artifact remaining, test failed
  1.1584 +			}
  1.1585 +
  1.1586 +		// move the cursor back to its start position, this resets the flash timer which is why we increment initialRepeatRate 
  1.1587 +		TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),kStartPos,aCursor);
  1.1588 +		TheClient->Flush();
  1.1589 +		initialRepeatRate += KIncrement;
  1.1590 +		}
  1.1591 +		
  1.1592 +		// if all went well i should equal KIterations, if it doesnt its because we detected 
  1.1593 +		// an artifact and quit the test early
  1.1594 +	TEST_SOFTFAIL_WINSCW(i==KIterations);
  1.1595 +	}
  1.1596 +	
  1.1597 +
  1.1598 +// Tests the two windows match, moves the cursor off win 1 then tests they no longer match 		
  1.1599 +void CTCursorTest::doCheckNoDoubleCursor(CBlankWindow* aWin1,
  1.1600 +											CBlankWindow* aWin2,
  1.1601 +											const TPoint& aWin1Tl,
  1.1602 +											const TPoint& aWin2Tl,
  1.1603 +											const TTextCursor& aCursor,
  1.1604 +											const TSize& aCursorSize,
  1.1605 +											CWsScreenDevice::TSpriteInCompare aFlags)
  1.1606 +	{
  1.1607 +	TRect r1(aWin1Tl,aCursorSize);
  1.1608 +	TRect r2(aWin2Tl,aCursorSize);
  1.1609 +	
  1.1610 +	TInt compareTries = 0;
  1.1611 +	const TInt compareLimit = 5;
  1.1612 +	
  1.1613 +	TBool correctComparison = EFalse;
  1.1614 +	while (!correctComparison && compareTries < compareLimit)
  1.1615 +		{
  1.1616 +		compareTries++;
  1.1617 +		User::After(500000);
  1.1618 +		correctComparison = TheClient->iScreen->RectCompare(r1,r2, aFlags);
  1.1619 +		}
  1.1620 +
  1.1621 +	INFO_PRINTF3(_L("Result Before %d (attempts %d)"), correctComparison, compareTries);
  1.1622 +	TEST_SOFTFAIL_WINSCW(correctComparison);
  1.1623 +
  1.1624 +	
  1.1625 +	// Change the focus off win1, by drawing the text cursor on the second window
  1.1626 +	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin2->BaseWin(),aWin2Tl,aCursor);
  1.1627 +	TheClient->Flush();
  1.1628 +
  1.1629 +	// Cause a redraw
  1.1630 +	aWin1->CTWin::DrawNow();
  1.1631 +	TheClient->WaitForRedrawsToFinish();
  1.1632 +
  1.1633 +	// make sure any cursor has actually moved	
  1.1634 +	User::After(1000000); // 1 sec
  1.1635 +	
  1.1636 +	TBool resultAfter;
  1.1637 +	resultAfter = !TheClient->iScreen->RectCompare(r1,r2, aFlags);
  1.1638 +	INFO_PRINTF2(_L("Result After %d"), resultAfter);
  1.1639 +	TEST_SOFTFAIL_WINSCW(resultAfter);
  1.1640 +	}	
  1.1641 +
  1.1642 +// resets the windows to their initial state
  1.1643 +void CTCursorTest::ResetWindows(CWindowGc* aWinGc,CBlankWindow* aWin1,CBlankWindow* aWin2)
  1.1644 +	{
  1.1645 +	TheClient->iGroup->GroupWin()->CancelTextCursor();
  1.1646 +	aWinGc->Activate(*aWin1->Win());
  1.1647 +	aWinGc->Reset();
  1.1648 +	aWinGc->Clear();
  1.1649 +	aWinGc->Deactivate();
  1.1650 +
  1.1651 +	aWin1->Invalidate();
  1.1652 +	aWin1->Redraw();
  1.1653 +	aWin2->Invalidate();
  1.1654 +	aWin2->Redraw();
  1.1655 +	TheClient->Flush();
  1.1656 +	}
  1.1657 +	
  1.1658 +void CTCursorTest::RunTestCaseL(TInt /*aCurTestCase*/)
  1.1659 +	{
  1.1660 +	TBool deleteMove=EFalse;
  1.1661 +	((CTCursorTestStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
  1.1662 +
  1.1663 +	switch(++iTest->iState)
  1.1664 +		{
  1.1665 +/**
  1.1666 +@SYMTestCaseID		GRAPHICS-WSERV-0241
  1.1667 +
  1.1668 +@SYMDEF				DEF081259
  1.1669 +
  1.1670 +@SYMTestCaseDesc    Test the text cursor functions properly as a window is moved
  1.1671 +
  1.1672 +@SYMTestPriority    High
  1.1673 +
  1.1674 +@SYMTestStatus      Implemented
  1.1675 +
  1.1676 +@SYMTestActions     Move a window about the screen and meanwhile check the text
  1.1677 +					cursor functions correctly
  1.1678 +
  1.1679 +@SYMTestExpectedResults The text cursor functions correctly as the window is moved
  1.1680 +*/
  1.1681 +	case 1:
  1.1682 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0241"));
  1.1683 +		while (!deleteMove)
  1.1684 +			{
  1.1685 +			if (iCursorType==TTextCursor::ETypeFirst)
  1.1686 +				iTest->LogSubTest(_L("Cursor 1"));
  1.1687 +			if (MoveWindow())
  1.1688 +				{
  1.1689 +				if (IncrementCursorType())
  1.1690 +					{
  1.1691 +					ResetMoveWindowsL();
  1.1692 +					}
  1.1693 +				else
  1.1694 +					{
  1.1695 +					DeleteMoveWindows();
  1.1696 +					deleteMove =true;
  1.1697 +					}
  1.1698 +				}
  1.1699 +			}
  1.1700 +		break;
  1.1701 +
  1.1702 +/**
  1.1703 +@SYMTestCaseID		GRAPHICS-WSERV-0242
  1.1704 +
  1.1705 +@SYMDEF				DEF081259
  1.1706 +
  1.1707 +@SYMTestCaseDesc    Test the text cursor functions properly as the window is scrolled
  1.1708 +
  1.1709 +@SYMTestPriority    High
  1.1710 +
  1.1711 +@SYMTestStatus      Implemented
  1.1712 +
  1.1713 +@SYMTestActions     Scroll the window and meanwhile check the text cursor functions correctly
  1.1714 +
  1.1715 +@SYMTestExpectedResults The text cursor functions correctly as the window is scrolled
  1.1716 +*/
  1.1717 +		case 2:
  1.1718 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0242"));
  1.1719 +			iTest->LogSubTest(_L("Cursor 2"));
  1.1720 +			iCursorType=TTextCursor::ETypeRectangle;
  1.1721 +			ScrollTest();
  1.1722 +			iCursorType=TTextCursor::ETypeFirst;
  1.1723 +			break;
  1.1724 +/**
  1.1725 +@SYMTestCaseID		GRAPHICS-WSERV-0244
  1.1726 +
  1.1727 +@SYMDEF				DEF081259
  1.1728 +
  1.1729 +@SYMTestCaseDesc    Test the text cursor functions properly as a blank window is moved
  1.1730 +
  1.1731 +@SYMTestPriority    High
  1.1732 +
  1.1733 +@SYMTestStatus      Implemented
  1.1734 +
  1.1735 +@SYMTestActions     Move a blank window about the screen and meanwhile check the text
  1.1736 +					cursor functions correctly
  1.1737 +
  1.1738 +@SYMTestExpectedResults The text cursor functions correctly as the blank window is moved
  1.1739 +*/
  1.1740 +		case 3:
  1.1741 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0244"));
  1.1742 +			iTest->LogSubTest(_L("Move window1"));
  1.1743 +			MoveWindowTest1L();
  1.1744 +			break;
  1.1745 +/**
  1.1746 +@SYMTestCaseID		GRAPHICS-WSERV-0245
  1.1747 +
  1.1748 +@SYMDEF				DEF081259
  1.1749 +
  1.1750 +@SYMTestCaseDesc    Test that a non flashing text cursor functions properly as a 
  1.1751 +					blank window is moved
  1.1752 +
  1.1753 +@SYMTestPriority    High
  1.1754 +
  1.1755 +@SYMTestStatus      Implemented
  1.1756 +
  1.1757 +@SYMTestActions     Move a blank window about the screen and meanwhile check that a non
  1.1758 +					flashing text cursor functions correctly
  1.1759 +
  1.1760 +@SYMTestExpectedResults The text cursor functions correctly as the blank window is moved
  1.1761 +*/
  1.1762 +		case 4:
  1.1763 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0245"));
  1.1764 +			while (IncrementCursorType())
  1.1765 +				{
  1.1766 +				iTest->LogSubTest(_L("Move window2"));
  1.1767 +				MoveWindowTest2L();
  1.1768 +				}
  1.1769 +			break;		
  1.1770 +/**
  1.1771 +@SYMTestCaseID		GRAPHICS-WSERV-0247
  1.1772 +
  1.1773 +@SYMDEF				DEF081259
  1.1774 +
  1.1775 +@SYMTestCaseDesc    Tests a Custom Text Cursor Sprite visibility after wserv hearbeat suppression
  1.1776 +					REQUIREMENT:	INC040489.
  1.1777 +
  1.1778 +@SYMTestPriority    High
  1.1779 +
  1.1780 +@SYMTestStatus      Implemented
  1.1781 +
  1.1782 +@SYMTestActions     Create a window group with an associated window for it, then activate it.
  1.1783 +					Create another window group with an associated window along with a custom cursor, 
  1.1784 +					then active it. Make a call to suppress the wserv hearbeat, which will stop 
  1.1785 +					the custom cursor from flashing with flash ON state. Bring the first window 
  1.1786 +					group to the foreground and cancel the custom test cursor in the second window group.
  1.1787 +					After that, put the first window group to the background and set the custom test 
  1.1788 +					cursor in the second window group. Simulate a raw key event to start 
  1.1789 +					the wserv heartbeat, which will make the custom cursor flashing.
  1.1790 +
  1.1791 +@SYMTestExpectedResults The Custom text cursor in the second window group should be visible and flashing, 
  1.1792 +						when it comes to the foreground after the first window group sent to the background.
  1.1793 +*/
  1.1794 +		case 5:
  1.1795 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0247"));
  1.1796 +			iTest->LogSubTest(_L("Custom Text Cursor Sprite visibility"));
  1.1797 +			INC040489L();
  1.1798 +			break;
  1.1799 +/**
  1.1800 +@SYMTestCaseID		GRAPHICS-WSERV-2095-0015
  1.1801 +
  1.1802 +@SYMTestCaseDesc    Text Cursor allows Update before Rendering the owning window
  1.1803 +
  1.1804 +@SYMTestPriority    Normal
  1.1805 +
  1.1806 +@SYMTestStatus      Implemented
  1.1807 +
  1.1808 +@SYMTestActions     Create a window group and two windows, one with a Text Cursor.
  1.1809 +					Stimulate a state change in the Text Cursor by receiving
  1.1810 +					window focus, but before the Window has ever been Rendered.
  1.1811 +					This shakes out logic in RWsTextCursor which depends on
  1.1812 +					side effects arising from having executed CWsWindow::Render()
  1.1813 +					
  1.1814 +@SYMTestExpectedResults 
  1.1815 +					There should be no panic or assertion.
  1.1816 +*/
  1.1817 +		case 6:
  1.1818 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0015"));
  1.1819 +			iTest->LogSubTest(_L("Update before Render"));
  1.1820 +			CursorUpdatedBeforeWindowRenderedL();
  1.1821 +			break;
  1.1822 +
  1.1823 +/**
  1.1824 +@SYMTestCaseID		GRAPHICS-WSERV-0248
  1.1825 +
  1.1826 +@SYMDEF  			DEF081259
  1.1827 +
  1.1828 +@SYMTestCaseDesc    Tests a bad use of text cursor functionality from a client.
  1.1829 +					REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
  1.1830 +
  1.1831 +@SYMTestPriority    High
  1.1832 +
  1.1833 +@SYMTestStatus      Implemented
  1.1834 +
  1.1835 +@SYMTestActions     This test case checks whether the window server is able to detect a bad
  1.1836 +					use of the text cursor functionality (including the custom text cursor)
  1.1837 +					by a client.
  1.1838 +					This test case launches several threads and each of them will try
  1.1839 +					to use the text cursor functionality in a non-proper way.
  1.1840 +
  1.1841 +@SYMTestExpectedResults Each new thread has panic code associated to it. This is the expected panic when
  1.1842 +						the thread dies.
  1.1843 +						The thread once launched is expected to panic and the returning panic code should
  1.1844 +						match the expected one.
  1.1845 +*/
  1.1846 +		case 7:
  1.1847 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0248"));
  1.1848 +			iTest->LogSubTest(_L("Panic"));
  1.1849 +			TestPanicsL();
  1.1850 +			break;
  1.1851 +/**
  1.1852 +@SYMTestCaseID		GRAPHICS-WSERV-0400
  1.1853 +
  1.1854 +@SYMDEF				PDEF099013
  1.1855 +
  1.1856 +@SYMTestCaseDesc    Cursor moves slowly in text editors. 
  1.1857 +
  1.1858 +@SYMTestPriority    High
  1.1859 +
  1.1860 +@SYMTestStatus      Implemented
  1.1861 +
  1.1862 +@SYMTestActions     This test case is a VISUAL TEST only on whether a scrolling text cursor is drawn to the
  1.1863 +					screen correctly. 2 types of cursor are checked both clipped and non clipped cursors.
  1.1864 +					In each case the test simulates a text cursor moving across the screen as if a user were
  1.1865 +					holding down a key to scroll the cursor through a section of text.
  1.1866 +
  1.1867 +@SYMTestExpectedResults The text cursor in both cases should scroll smoothly to the centre of the screen.
  1.1868 +						In versions prior to this fix the cursor was not correctly drawn and appeared to move 	
  1.1869 +						slowly.
  1.1870 +*/
  1.1871 +		case 8:
  1.1872 +			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0400"));
  1.1873 +			iTest->LogSubTest(_L("Text Cursor Update Tests"));
  1.1874 +			INC097774();
  1.1875 +			break;	
  1.1876 +		
  1.1877 +/**
  1.1878 +@SYMTestCaseID		GRAPHICS-WSERV-0401
  1.1879 +
  1.1880 +@SYMDEF  			DEF098704
  1.1881 +
  1.1882 +@SYMTestCaseDesc    Test code for implemented fix to remove double cursors 
  1.1883 +					
  1.1884 +@SYMTestPriority    Normal
  1.1885 +
  1.1886 +@SYMTestStatus      Implemented
  1.1887 +
  1.1888 +@SYMTestActions     This test case tests for artifacts left over when normal/custon flashing/non-flashing cursors are drawn.
  1.1889 +					Test that changing the focus of a custom text cursor does not leave that cursor drawn where it was (INC093898)
  1.1890 +
  1.1891 +@SYMTestExpectedResults 
  1.1892 +*/			
  1.1893 +	case 9:
  1.1894 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0401"));
  1.1895 +		iTest->LogSubTest(_L("Double cursors test 1"));
  1.1896 +		StartDoubleCursorTestL(1);
  1.1897 +		break;
  1.1898 +
  1.1899 +	/**
  1.1900 +	@SYMTestCaseID		GRAPHICS-WSERV-0402
  1.1901 +
  1.1902 +	@SYMDEF				DEF098704
  1.1903 +
  1.1904 +	@SYMTestCaseDesc    Test code for implemented fix to remove double cursors 
  1.1905 +
  1.1906 +	@SYMTestPriority    Normal
  1.1907 +
  1.1908 +	@SYMTestStatus      Implemented
  1.1909 +
  1.1910 +	@SYMTestActions     Checks that no artifacts are left behind when a text cursor is moved from under a transparent sprite
  1.1911 +
  1.1912 +	@SYMTestExpectedResults 
  1.1913 +	*/
  1.1914 +	case 10:
  1.1915 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0402"));
  1.1916 +		iTest->LogSubTest(_L("Double cursors test 2"));
  1.1917 +		StartDoubleCursorTestL(2);
  1.1918 +		break;
  1.1919 +
  1.1920 +	/**
  1.1921 +	@SYMTestCaseID		GRAPHICS-WSERV-0403
  1.1922 +
  1.1923 +	@SYMDEF				DEF098704
  1.1924 +
  1.1925 +	@SYMTestCaseDesc    Test code for implemented fix to remove double cursors 
  1.1926 +						
  1.1927 +	@SYMTestPriority    Normal
  1.1928 +
  1.1929 +	@SYMTestStatus      Implemented
  1.1930 +
  1.1931 +	@SYMTestActions     This test moves a flashing cursor a number of times over a two second period to a seconds position.
  1.1932 +						it does it a number of times so some of the redraws will occur during the 'flash off' period
  1.1933 +						We then compare the 'after' position to what we expect
  1.1934 +
  1.1935 +	@SYMTestExpectedResults 
  1.1936 +	*/
  1.1937 +	case 11:
  1.1938 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0403"));
  1.1939 +		iTest->LogSubTest(_L("Double cursors test 3"));
  1.1940 +		StartDoubleCursorTestL(3);
  1.1941 +		break;
  1.1942 +
  1.1943 +	/**
  1.1944 +	@SYMTestCaseID		GRAPHICS-WSERV-0483
  1.1945 +
  1.1946 +	@SYMDEF				INC117232
  1.1947 +
  1.1948 +	@SYMTestCaseDesc    Test code: Refreshing cursors becoming offscreen due to screen size change should not panic 
  1.1949 +
  1.1950 +	@SYMTestPriority    Normal
  1.1951 +
  1.1952 +	@SYMTestStatus      Implemented
  1.1953 +
  1.1954 +	@SYMTestActions     Create a cursor on bottom right of screen, change to a screen mode that excludes that coordinate
  1.1955 +
  1.1956 +	@SYMTestExpectedResults 
  1.1957 +						The server should not panic.
  1.1958 +	*/
  1.1959 +	case 12:
  1.1960 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0483"));
  1.1961 +		iTest->LogSubTest(_L("Screen resize invalidate cursor off-screen"));
  1.1962 +		INC117232();
  1.1963 +		break;
  1.1964 +
  1.1965 +	/**
  1.1966 +	@SYMTestCaseID		GRAPHICS-WSERV-2095-0016
  1.1967 +
  1.1968 +	@SYMTestCaseDesc    Text Cursor flag TTextCursor::EFlagNoFlash honored 
  1.1969 +
  1.1970 +	@SYMTestPriority    Normal
  1.1971 +
  1.1972 +	@SYMTestStatus      Implemented
  1.1973 +
  1.1974 +	@SYMTestActions     Create a text cursor with the TTextCursor::EFlagNoFlash setting.  Observe the screen over
  1.1975 +						a short period of time to verify that it remains continuously in the Flash ON state.
  1.1976 +
  1.1977 +	@SYMTestExpectedResults 
  1.1978 +						The text cursor should be always shown.
  1.1979 +	*/
  1.1980 +	case 13:
  1.1981 +	#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
  1.1982 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0016"));
  1.1983 +		iTest->LogSubTest(_L("Text cursor EFlagNoFlash test"));
  1.1984 +		TextCursorNoFlashTestL();
  1.1985 +	#endif
  1.1986 +		break;
  1.1987 +
  1.1988 +	/**
  1.1989 +	@SYMTestCaseID		GRAPHICS-WSERV-2095-0009
  1.1990 +
  1.1991 +	@SYMTestCaseDesc    Text Cursor flashes when flag value is 0
  1.1992 +
  1.1993 +	@SYMTestPriority    Normal
  1.1994 +
  1.1995 +	@SYMTestStatus      Implemented
  1.1996 +
  1.1997 +	@SYMTestActions     Create a text cursor with the 0 flag setting.  Observe the screen over
  1.1998 +						a short period of time to verify that the cursor flashes ON and OFF at
  1.1999 +						the correct period of one second.
  1.2000 +
  1.2001 +	@SYMTestExpectedResults 
  1.2002 +						The text cursor should flash.
  1.2003 +	*/
  1.2004 +	case 14:
  1.2005 +	#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
  1.2006 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0009"));
  1.2007 +		iTest->LogSubTest(_L("Text cursor will Flash test"));
  1.2008 +		TextCursorFlashTestL();
  1.2009 +	#endif
  1.2010 +		break;
  1.2011 +
  1.2012 +	/**
  1.2013 +	@SYMTestCaseID		GRAPHICS-WSERV-2095-0017
  1.2014 +
  1.2015 +	@SYMTestCaseDesc    Text Cursor handles different valid Cursor Setttings
  1.2016 +
  1.2017 +	@SYMTestPriority    Normal
  1.2018 +
  1.2019 +	@SYMTestStatus      Implemented
  1.2020 +
  1.2021 +	@SYMTestActions     Create a text cursor and then issue a SetTextCursor.  Then repeatedly
  1.2022 +						call SetTextCursor, varying the arguments relating to the Text Cursor
  1.2023 +						as well as keeping the arguments the same on one occassion.
  1.2024 +
  1.2025 +	@SYMTestExpectedResults 
  1.2026 +						The system should not panic as the arguments supplied are never invalid.
  1.2027 +	*/
  1.2028 +	case 15:
  1.2029 +		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0017"));
  1.2030 +		iTest->LogSubTest(_L("SetTextCursor test"));
  1.2031 +		TextCursorSetLCoverageTests();
  1.2032 +		break;
  1.2033 +
  1.2034 +		default:
  1.2035 +			((CTCursorTestStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
  1.2036 +			((CTCursorTestStep*)iStep)->CloseTMSGraphicsStep();
  1.2037 +			TestComplete();
  1.2038 +			break;
  1.2039 +		}
  1.2040 +	((CTCursorTestStep*)iStep)->RecordTestResultL();
  1.2041 +	}
  1.2042 +
  1.2043 +__WS_CONSTRUCT_STEP__(CursorTest)