windowing/windowserver/tauto/TTEXTCURS.CPP
changeset 116 171fae344dd4
parent 103 2717213c588a
equal deleted inserted replaced
103:2717213c588a 116:171fae344dd4
     1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Test the text cursor.
       
    15 //
       
    16 // This suite of tests checks to see if the TextCursors are operating
       
    17 // correctly for a number of use case scenarios; see doxygen comments
       
    18 // for each sub-test.  This test suite is applicable on both winscw
       
    19 // emulator and armv5 target hardware.  However, it must be noted that
       
    20 // text cursors are special due to their timeliness.  The text cursor
       
    21 // must flash every second: half a second ON, half a second OFF.  One
       
    22 // consequence of this is that when the test suite is run on emulator,
       
    23 // the PC must be otherwise quiescent.  No other IO or CPU intensive
       
    24 // activities may occur on the system, because these will cause delays
       
    25 // to the flashing of the text cursor giving unreliable results.
       
    26 // Where timeliness is a consideration, we use TEST_SOFTFAIL_WINSCW so
       
    27 // that if the test fails and we are running on the PC emulator, we only
       
    28 // record the fact, but don't mark the test as failing.
       
    29 
       
    30 /**
       
    31  @file
       
    32  @test
       
    33  @internalComponent - Internal Symbian test code
       
    34 */
       
    35 
       
    36 #include "TTEXTCURS.H"
       
    37 #include "graphics/windowserverconstants.h"
       
    38 
       
    39 const TInt KNumberOfCustoTextCursors	= 3;
       
    40 const TInt KTextCursorInitialIdValue	= 1001;
       
    41 const TInt KTextCursorPanicUid1			= 200;
       
    42 const TInt KTextCursorPanicUid2			= 2000;
       
    43 const TInt KTextCursorPanicUid3			= 3000;
       
    44 const TInt KTextCursorPanicUid4			= 4000;
       
    45 const TInt KTextCursorPanicUid5			= 5000;
       
    46 
       
    47 CTestBase* CTCursorTest::iStaticTest = NULL;
       
    48 const TInt kWinWidth=400;
       
    49 const TInt kWinHeight=100;
       
    50 const TSize kWinSize(kWinWidth,kWinHeight);
       
    51 const TInt kWinXPos=150;
       
    52 const TInt kCursorWidth = 10;
       
    53 const TInt kCursorHeight = 20;
       
    54 const TSize kCursorSize(kCursorWidth,kCursorHeight);
       
    55 const TPoint kWin1TopLeft(kWinXPos,0);
       
    56 const TPoint kWin2TopLeft(kWinXPos,kWinHeight+10);
       
    57 
       
    58 LOCAL_D void DeleteSpriteMember(TAny* aSpriteMember)
       
    59 	{
       
    60 	TSpriteMember* member=reinterpret_cast<TSpriteMember*>(aSpriteMember);
       
    61 	delete member->iBitmap;
       
    62 	member->iBitmap=NULL;
       
    63 	delete member->iMaskBitmap;
       
    64 	member->iMaskBitmap=NULL;
       
    65 	}
       
    66 
       
    67 CCustomTextCursor::~CCustomTextCursor()
       
    68 	{
       
    69 	const TInt count = iSpriteMemberArray.Count();
       
    70 	for (TInt index=0; index<count; ++index)
       
    71 		{
       
    72 		DeleteSpriteMember(&iSpriteMemberArray[index]);
       
    73 		}
       
    74 	iSpriteMemberArray.Close();
       
    75 	}
       
    76 	
       
    77 CCustomTextCursor::CCustomTextCursor(CTestBase* aTest)
       
    78 	: iTest(aTest)
       
    79 	{	
       
    80 	}
       
    81 
       
    82 void CCustomTextCursor::ConstructL(TInt aScreenNumber,TInt aBmpIndex)
       
    83 	{
       
    84 	ASSERT(aBmpIndex < KNumberOfCustoTextCursors);
       
    85 	
       
    86 
       
    87 	TSpriteMember spriteMember;
       
    88 	spriteMember.iBitmap = NULL;
       
    89 	spriteMember.iMaskBitmap = NULL;
       
    90 	spriteMember.iInvertMask =EFalse;
       
    91 	spriteMember.iDrawMode = CGraphicsContext::EDrawModePEN;
       
    92 	spriteMember.iOffset = TPoint();
       
    93 	spriteMember.iInterval = TTimeIntervalMicroSeconds32(0);
       
    94 	CleanupStack::PushL(TCleanupItem(DeleteSpriteMember, &spriteMember));
       
    95 	spriteMember.iBitmap = new (ELeave) CFbsBitmap;
       
    96 	User::LeaveIfError(spriteMember.iBitmap->Load(TEST_BITMAP_NAME, EMbmWsautotestBmp1));
       
    97 	spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap;
       
    98 	User::LeaveIfError(spriteMember.iMaskBitmap->Load(TEST_BITMAP_NAME, EMbmWsautotestBmp1mask));
       
    99 
       
   100 	User::LeaveIfError(iSpriteMemberArray.Append(spriteMember));
       
   101 	CleanupStack::Pop(&spriteMember);
       
   102 
       
   103 	// create unique-id accross screens
       
   104 	//
       
   105 	iIdentifier = KTextCursorInitialIdValue + aScreenNumber*KNumberOfCustoTextCursors + aBmpIndex;
       
   106 	iAlignment = (RWsSession::TCustomTextCursorAlignment)(aBmpIndex);
       
   107 	}
       
   108 
       
   109 CCustomTextCursor* CCustomTextCursor::CreateCustomTextCursorL(TInt aScreenNumber,TInt aBmpIndex,CTestBase* aTest)
       
   110 	{
       
   111 	CCustomTextCursor* customTextCursor = new (ELeave) CCustomTextCursor(aTest);
       
   112 	CleanupStack::PushL(customTextCursor);
       
   113 	customTextCursor->ConstructL(aScreenNumber,aBmpIndex);
       
   114 	CleanupStack::Pop(customTextCursor);
       
   115 	return customTextCursor;
       
   116 	}
       
   117 
       
   118 /*
       
   119  * Wrapper class for a list of custom text cursor.
       
   120  */
       
   121 class CCustomTextCursorsWrapper : public CBase
       
   122 	{
       
   123 public:
       
   124 	static CCustomTextCursorsWrapper* NewLC(TInt aScreenNumber,CTestBase* aTest);
       
   125 	~CCustomTextCursorsWrapper();
       
   126 	inline RPointerArray<CCustomTextCursor>& CustomTextCursorsArray();
       
   127 	inline CCustomTextCursor& CustomTextCursor(TInt aIndex);
       
   128 private:
       
   129 	void ConstructL(TInt aScreenNumber,CTestBase* aTest);
       
   130 private:
       
   131 	RPointerArray<CCustomTextCursor> iCustomTextCursors;
       
   132 	};
       
   133 
       
   134 inline RPointerArray<CCustomTextCursor>& CCustomTextCursorsWrapper::CustomTextCursorsArray()
       
   135 		{
       
   136 		return iCustomTextCursors;
       
   137 		}
       
   138 
       
   139 inline CCustomTextCursor& CCustomTextCursorsWrapper::CustomTextCursor(TInt aIndex)
       
   140 		{
       
   141 		return *(iCustomTextCursors[aIndex]);
       
   142 		}
       
   143 
       
   144 CCustomTextCursorsWrapper* CCustomTextCursorsWrapper::NewLC(TInt aScreenNumber,CTestBase* aTest)
       
   145 	{
       
   146 	CCustomTextCursorsWrapper* self = new(ELeave) CCustomTextCursorsWrapper();
       
   147 	CleanupStack::PushL(self);
       
   148 	self->ConstructL(aScreenNumber,aTest);
       
   149 	return self;
       
   150 	}
       
   151 
       
   152 CCustomTextCursorsWrapper::~CCustomTextCursorsWrapper()
       
   153 	{
       
   154 	iCustomTextCursors.ResetAndDestroy();
       
   155 	iCustomTextCursors.Close();
       
   156 	}
       
   157 
       
   158 void CCustomTextCursorsWrapper::ConstructL(TInt aScreenNumber, CTestBase* aTest)
       
   159 	{
       
   160 	for (TInt index=0; index<KNumberOfCustoTextCursors; ++index)
       
   161 		{
       
   162 		CCustomTextCursor* customTextCursor=CCustomTextCursor::CreateCustomTextCursorL(aScreenNumber,index, aTest);
       
   163 		CleanupStack::PushL(customTextCursor);
       
   164 		User::LeaveIfError(iCustomTextCursors.Append(customTextCursor));
       
   165 		CleanupStack::Pop(customTextCursor);
       
   166 		}
       
   167 	}
       
   168 
       
   169 CTCursorTest::CTCursorTest(CTestStep* aStep) :
       
   170 	CTWsGraphicsBase(aStep)
       
   171 	{
       
   172 	iCursorType = TTextCursor::ETypeFirst;
       
   173 	iStaticTest=iTest;
       
   174 	}
       
   175 	
       
   176 CTCursorTest::~CTCursorTest()
       
   177 	{
       
   178 	delete iWorkInProgress;
       
   179 	delete iComparisonWindow;
       
   180 	}
       
   181 
       
   182 TInt CTCursorTest::DoPanicTest(TInt aInt, TAny *aScreenNumber)
       
   183 	{
       
   184 	RWsSession ws;
       
   185 	if (ws.Connect()==KErrNone)
       
   186 		{
       
   187 		// use correct screen
       
   188 		CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
       
   189 		User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
       
   190 		RWindowGroup group(ws);
       
   191 		if (group.Construct(444)==KErrNone)
       
   192 			{
       
   193 			group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
       
   194 			RWindow wnd(ws);
       
   195 			if (wnd.Construct(group, TInt32(&ws))==KErrNone)
       
   196 				{
       
   197 				TTextCursor tc;
       
   198 				tc.iHeight=10;
       
   199 				tc.iAscent=5;
       
   200 				tc.iWidth=10;
       
   201 				tc.iFlags=0;
       
   202 				tc.iColor=TRgb(0,0,0);
       
   203 				switch(aInt)
       
   204 					{
       
   205 					case 0:
       
   206 						{
       
   207 						/* TESTCASE:	6.1
       
   208 						* TITLE:		Invalid use of a custom text cursor ID (basic text cursor).
       
   209 						* IMPORTANCE:	1
       
   210 						* REQUIREMENT:	Unknown.
       
   211 						* 
       
   212 						* ACTION:		This test tries to set a text cursor using an ID which is invalid.
       
   213 						* 
       
   214 						* CHECK:		The thread should panic with the exit reason EWservPanicInvalidTextCursor
       
   215 						*/ 
       
   216 						tc.iType=(TTextCursor::EType)KTextCursorPanicUid1;
       
   217 						group.SetTextCursor(wnd,TPoint(10,10),tc);
       
   218 						}
       
   219 						break;
       
   220 					case 1:
       
   221 						{
       
   222 						/* TESTCASE:	6.2
       
   223 						* TITLE:		Invalid use of a window for a text cursor.
       
   224 						* IMPORTANCE:	1
       
   225 						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
       
   226 						* 
       
   227 						* ACTION:		This test tries to set a text cursor using a window which is not part
       
   228 						*				of the window group calling the setting API.
       
   229 						* 
       
   230 						* CHECK:		The thread should panic with the exit reason EWservPanicWindow
       
   231 						*/ 
       
   232 						tc.iType=(TTextCursor::EType)KTextCursorPanicUid2;
       
   233 						group.SetTextCursor(*TestWin->Win(),TPoint(10,10),tc);
       
   234 						}
       
   235 						break;
       
   236 					case 2:
       
   237 						{
       
   238 						/* TESTCASE:	6.3
       
   239 						* TITLE:		Invalid use of a custom text cursor ID.
       
   240 						* IMPORTANCE:	1
       
   241 						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
       
   242 						* 
       
   243 						* ACTION:		This test tries to set a text cursor using an ID which is associated to
       
   244 						*				an non-existing custom text cursor.
       
   245 						* 
       
   246 						* CHECK:		The thread should panic with the exit reason EWservPanicNoCustomTextCursor
       
   247 						*/ 
       
   248 						tc.iType=(TTextCursor::EType)KTextCursorPanicUid3;
       
   249 						group.SetTextCursor(wnd,TPoint(10,10),tc);
       
   250 						}
       
   251 						break;
       
   252 					case 3:
       
   253 						{
       
   254 						/* TESTCASE:	6.4
       
   255 						* TITLE:		Invalid use of a custom text cursor ID.
       
   256 						* IMPORTANCE:	1
       
   257 						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
       
   258 						* 
       
   259 						* ACTION:		This test tries to set a custom text cursor which has been set to use
       
   260 						*				an invalid alignment.
       
   261 						* 
       
   262 						* CHECK:		The thread should panic with the exit reason EWservPanicCustomTextCursorAlign
       
   263 						*/ 
       
   264 						CCustomTextCursor* customTextCursor=NULL;
       
   265 						TRAPD(error, customTextCursor=CCustomTextCursor::CreateCustomTextCursorL((TInt)aScreenNumber,0,iStaticTest));
       
   266 						if (error==KErrNone)
       
   267 							{
       
   268 							error = ws.SetCustomTextCursor(KTextCursorPanicUid4, customTextCursor->iSpriteMemberArray.Array(), 0, (RWsSession::TCustomTextCursorAlignment)(RWsSession::ECustomTextCursorAlignBottom+1));
       
   269 							if (error==KErrNone || error==KErrAlreadyExists)
       
   270 								{
       
   271 								tc.iType=(TTextCursor::EType)KTextCursorPanicUid4;
       
   272 								group.SetTextCursor(wnd,TPoint(10,10),tc);
       
   273 								}
       
   274 							}
       
   275 						delete customTextCursor;
       
   276 						}
       
   277 						break;
       
   278 					case 4:
       
   279 						{
       
   280 						/* TESTCASE:	6.5
       
   281 						* TITLE:		Use of an invalid custom text cursor
       
   282 						* IMPORTANCE:	1
       
   283 						* REQUIREMENT:	REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
       
   284 						* 
       
   285 						* ACTION:		This test tries to set a custom text cursor which does not have
       
   286 						*				any sprite member set.
       
   287 						* 
       
   288 						* CHECK:		The thread should panic with the exit reason EWservPanicNoSpriteMember
       
   289 						*/ 
       
   290 						RArray<TSpriteMember> spriteMemberArray;
       
   291 						const TInt error = ws.SetCustomTextCursor(KTextCursorPanicUid5, spriteMemberArray.Array(), 0, (RWsSession::TCustomTextCursorAlignment)(RWsSession::ECustomTextCursorAlignBottom));
       
   292 						if (error==KErrNone || error==KErrAlreadyExists)
       
   293 							{
       
   294 							tc.iType=(TTextCursor::EType)KTextCursorPanicUid5;
       
   295 							group.SetTextCursor(wnd,TPoint(10,10),tc);
       
   296 							}
       
   297 						}
       
   298 						break;
       
   299 					case 5:
       
   300 						{
       
   301 						// Uncover set.cursor.iType < TTextCursor::ETypeFirst code path
       
   302 						tc.iType=(TTextCursor::EType)TTextCursor::ETypeFirst - 1;
       
   303 						group.SetTextCursor(wnd,TPoint(10,10),tc);
       
   304 						}
       
   305 						break;
       
   306 					case 6:
       
   307 						{
       
   308 						// Uncover (set.cursor.iFlags&static_cast<TUint>(TTextCursor::EPrivateFlags) code path
       
   309 						tc.iFlags=ETextCursorPrivateFlags;
       
   310 						group.SetTextCursor(wnd,TPoint(10,10),tc);
       
   311 						}
       
   312 						break;
       
   313 					case 7:
       
   314 						{
       
   315 						// Uncover (iGroupWin != searchWin) i.e. bogus group window
       
   316 						tc.iType=(TTextCursor::EType)TTextCursor::ETypeRectangle;
       
   317 						RWindow windowNotAssociatedWithAGroup(ws);
       
   318 						group.SetTextCursor(windowNotAssociatedWithAGroup, TPoint(10,10),tc);
       
   319 						}
       
   320 						break;
       
   321 					}
       
   322 				}
       
   323 			ws.Flush();
       
   324 			}
       
   325 		}
       
   326 	return(EWsExitReasonBad);
       
   327 	}
       
   328 
       
   329 void CTCursorTest::TestPanicsL()
       
   330 	{	
       
   331 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicInvalidTextCursor, 0, (TAny*)iTest->iScreenNumber));
       
   332 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicWindow, 1, (TAny*)iTest->iScreenNumber));
       
   333 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicNoCustomTextCursor, 2, (TAny*)iTest->iScreenNumber));
       
   334 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicCustomTextCursorAlign, 3, (TAny*)iTest->iScreenNumber));
       
   335 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicNoSpriteMember, 4, (TAny*)iTest->iScreenNumber));
       
   336 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicInvalidTextCursor, 5, (TAny*)iTest->iScreenNumber));
       
   337 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicInvalidTextCursor, 6, (TAny*)iTest->iScreenNumber));
       
   338 		TEST(iTest->TestWsPanicL(DoPanicTest, EWservPanicWindow, 7, (TAny*)iTest->iScreenNumber));
       
   339 		iTest->CloseAllPanicWindows();
       
   340 	}
       
   341 
       
   342 void CTCursorTest::TextCursorSetLCoverageTests()
       
   343 	{
       
   344 	ValidateWin(BaseWin,TRgb::Gray256(255));
       
   345 	ValidateWin(TestWin,TRgb::Gray256(255));	
       
   346 	TTextCursor textCursor;
       
   347 	textCursor.iHeight = 10;
       
   348 	textCursor.iAscent = 0;
       
   349 	textCursor.iWidth = 10;
       
   350 	textCursor.iFlags = 0;
       
   351 	textCursor.iColor = KRgbBlack;
       
   352 	textCursor.iType = (TTextCursor::EType)TTextCursor::ETypeRectangle;
       
   353 	TPoint position(10, 10);
       
   354 	TRect clipRect0(10, 10, 10, 10);
       
   355 	TRect clipRect1(10, 10, 5, 5);
       
   356 	RWindowGroup *group = TheClient->iGroup->GroupWin(); 
       
   357 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   358 	/*
       
   359 	 * Duplicate the previous SetTextCursor command to uncover the code which checks for any delta in SetL
       
   360 	 * compared to the current settings.
       
   361 	 */
       
   362 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   363 	/*
       
   364 	 * Change the type only to pick up that difference in SetL.
       
   365 	 */
       
   366 	textCursor.iType++;
       
   367 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   368 	textCursor.iType--;
       
   369 	/*
       
   370 	 * Vary the clipping rectangle.
       
   371 	 */
       
   372 	group->SetTextCursor(*TestWin->Win(), position, textCursor, clipRect0);
       
   373 	group->SetTextCursor(*TestWin->Win(), position, textCursor, clipRect1);
       
   374 	/*
       
   375 	 * Vary the color.
       
   376 	 */
       
   377 	textCursor.iColor = KRgbGreen;
       
   378 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   379 	textCursor.iColor = KRgbBlack;
       
   380 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   381 	/*
       
   382 	 * Vary the target Window.
       
   383 	 */
       
   384 	group->SetTextCursor(*BaseWin->Win(), position, textCursor);
       
   385 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   386 	/*
       
   387 	 * Vary the size of the cursor.
       
   388 	 */
       
   389 	textCursor.iWidth++;
       
   390 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   391 	textCursor.iWidth--;
       
   392 	/*
       
   393 	 * Set different custom cursors.
       
   394 	 */
       
   395 	CCustomTextCursorsWrapper* customTextCursorsWrapper = CCustomTextCursorsWrapper::NewLC(iTest->iScreenNumber, iTest);
       
   396 	const TInt count = customTextCursorsWrapper->CustomTextCursorsArray().Count();
       
   397 	for (TInt index=0; index<count; ++index)
       
   398 		{
       
   399 		CCustomTextCursor& customTextCursor = customTextCursorsWrapper->CustomTextCursor(index);
       
   400 		textCursor.iType = customTextCursor.iIdentifier;
       
   401 		group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   402 		}			
       
   403 	CleanupStack::PopAndDestroy(customTextCursorsWrapper);
       
   404 	/*
       
   405 	 * Set the last custom cursor from the above loop again so the
       
   406 	 * product code sees the same Custom Text Cursor settings come
       
   407 	 * in a second time.
       
   408 	 */
       
   409 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   410 	textCursor.iType = (TTextCursor::EType)TTextCursor::ETypeRectangle;
       
   411 	/*
       
   412 	 * Vary the horizontal clipping.
       
   413 	 */
       
   414 	textCursor.iFlags = TTextCursor::EFlagClipHorizontal;
       
   415 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   416 	/*
       
   417 	 * Vary the horizontal clipping.
       
   418 	 */
       
   419 	textCursor.iFlags = TTextCursor::EFlagClipVertical;
       
   420 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   421 	/*
       
   422 	 * Try both horizontal and vertical clipping.
       
   423 	 */
       
   424 	textCursor.iFlags = TTextCursor::EFlagClipVertical|TTextCursor::EFlagClipHorizontal;
       
   425 	group->SetTextCursor(*TestWin->Win(), position, textCursor);
       
   426 	textCursor.iFlags = 0;
       
   427 	
       
   428 	TheClient->iWs.Flush();
       
   429 	CancelTextCursor();
       
   430 	}
       
   431 
       
   432 void CTCursorTest::SetCursor(const TPoint &aPos,const TSize &aSize,TRgb aColor, const TRect &aRect, TUint aFlags)
       
   433 	{
       
   434 	TTextCursor tc;
       
   435 	tc.iType=iCursorType;
       
   436     tc.iHeight=aSize.iHeight;
       
   437     tc.iAscent=aSize.iHeight*4/5;
       
   438     tc.iWidth=aSize.iWidth;
       
   439     tc.iFlags=aFlags;
       
   440 	tc.iColor=aColor;
       
   441 	TheClient->iGroup->GroupWin()->SetTextCursor(*TestWin->Win(),TPoint(aPos.iX,aPos.iY+tc.iAscent),tc,aRect);
       
   442 	}
       
   443 
       
   444 void CTCursorTest::SetCursor(const TPoint &aPos,const TSize &aSize,TRgb aColor, TUint aFlags)
       
   445 	{
       
   446 	TTextCursor tc;
       
   447 	tc.iType=iCursorType;
       
   448     tc.iHeight=aSize.iHeight;
       
   449     tc.iAscent=aSize.iHeight*4/5;
       
   450     tc.iWidth=aSize.iWidth;
       
   451     tc.iFlags=aFlags;
       
   452 	tc.iColor=aColor;
       
   453 	TheClient->iGroup->GroupWin()->SetTextCursor(*TestWin->Win(),TPoint(aPos.iX,aPos.iY+tc.iAscent),tc);
       
   454 	}
       
   455 
       
   456 void CTCursorTest::SetCursorPlusBox(const TPoint &aPos,const TSize &aSize,TRgb aColor, const TRect *aClipRect, TUint aFlags)
       
   457 	{
       
   458 	if (aClipRect)
       
   459 		SetCursor(aPos,aSize,aColor,*aClipRect,aFlags);
       
   460 	else
       
   461 		SetCursor(aPos,aSize,aColor,aFlags);
       
   462 	TRect rect(aPos,aSize);
       
   463 	if (aClipRect)
       
   464 		rect.Intersection(*aClipRect);
       
   465 	rect.Grow(2,2);
       
   466 	
       
   467 	TheClient->iGc->Activate(*(TestWin->Win()));
       
   468 	TestWin->Invalidate(rect);
       
   469 	TestWin->Win()->BeginRedraw(rect);
       
   470 	TheClient->iGc->SetPenColor(aColor);
       
   471 	TheClient->iGc->SetDrawMode(CGraphicsContext::EDrawModeXOR);
       
   472 
       
   473 	TheClient->iGc->DrawRect(rect);
       
   474 	TheClient->iGc->Deactivate();
       
   475 	TestWin->Win()->EndRedraw();
       
   476 	
       
   477 	}
       
   478 
       
   479 void CTCursorTest::CancelTextCursor()
       
   480 	{
       
   481 	TheClient->iGroup->GroupWin()->CancelTextCursor();
       
   482 	}
       
   483 
       
   484 void CTCursorTest::ConstructL()
       
   485 	{
       
   486 	// for allocating some cached memory
       
   487 	CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
       
   488 	CleanupStack::PushL(bitmap);
       
   489 	User::LeaveIfError(bitmap->Load(TEST_BITMAP_NAME, 0));
       
   490 	CleanupStack::PopAndDestroy(bitmap);
       
   491 
       
   492 	CCustomTextCursorsWrapper* customTextCursorsWrapper = CCustomTextCursorsWrapper::NewLC(iTest->iScreenNumber, iTest);
       
   493 	const TInt count = customTextCursorsWrapper->CustomTextCursorsArray().Count();
       
   494 	for (TInt index=0; index<count; ++index)
       
   495 		{
       
   496 		CCustomTextCursor& customTextCursor = customTextCursorsWrapper->CustomTextCursor(index);
       
   497 		TInt err = TheClient->iWs.SetCustomTextCursor(customTextCursor.iIdentifier, customTextCursor.iSpriteMemberArray.Array(), customTextCursor.iSpriteFlags, customTextCursor.iAlignment);
       
   498 		TEST(err == KErrNone || err == KErrAlreadyExists);
       
   499 		if (err!=KErrNone && err != KErrAlreadyExists)
       
   500 			INFO_PRINTF4(_L("TheClient->iWs.SetCustomTextCursor return value  - Expected: %d or %d, Actual: %d"), KErrNone, KErrAlreadyExists, err);
       
   501 
       
   502 		__UHEAP_MARK;
       
   503 		err = TheClient->iWs.SetCustomTextCursor(customTextCursor.iIdentifier, customTextCursor.iSpriteMemberArray.Array(), customTextCursor.iSpriteFlags, customTextCursor.iAlignment);
       
   504 		__UHEAP_MARKEND;
       
   505 		TEST(err == KErrAlreadyExists);
       
   506 		if (err != KErrAlreadyExists)
       
   507 			INFO_PRINTF3(_L("TheClient->iWs.SetCustomTextCursor return value  - Expected: %d, Actual: %d"), KErrAlreadyExists, err);
       
   508 
       
   509 		}
       
   510 	_LIT(KLog,"Text Cursor: Loaded %d Custom Cursors");
       
   511 	TLogMessageText buf;
       
   512 	buf.Format(KLog,count);
       
   513 	TheClient->LogMessage(buf);
       
   514 	CleanupStack::PopAndDestroy(customTextCursorsWrapper);
       
   515 //
       
   516 	ValidateWin(BaseWin,TRgb::Gray256(204));
       
   517 	ValidateWin(TestWin,TRgb::Gray256(204));
       
   518 //
       
   519 	SetCursor(TPoint(10,90),TSize(80,100),TRgb(255,255,255));
       
   520 //
       
   521 	iWinState=0;
       
   522 	iWinPos=TPoint(2*TheClient->iGroup->Size().iWidth/3,0);
       
   523 //
       
   524 	iMoveWin=new(ELeave) CBlankWindow(TRgb::Gray256(220));
       
   525 	TDisplayMode mode=EGray16;
       
   526 	TInt testWinWidth = TestWin->Size().iWidth;
       
   527 	TInt halfTestWinWidth = testWinWidth/2;
       
   528 	TInt halfTestWinHeight = TestWin->Size().iHeight/2;
       
   529 	
       
   530 	iMoveWin->SetUpL(iWinPos,TSize(halfTestWinHeight,halfTestWinHeight),
       
   531 			TheClient->iGroup,*TheClient->iGc,&mode);
       
   532 
       
   533 	iCheckWin=new(ELeave) CBlankWindow(TRgb::Gray256(220));
       
   534 	iCheckWin->SetUpL(TPoint(testWinWidth+halfTestWinWidth,halfTestWinHeight),
       
   535 			TSize(halfTestWinWidth,halfTestWinHeight),
       
   536 			TheClient->iGroup,*TheClient->iGc,&mode);
       
   537 	}
       
   538 
       
   539 void CTCursorTest::DeleteMoveWindows()
       
   540 	{
       
   541 	delete iMoveWin;
       
   542 	delete iCheckWin;
       
   543 	CancelTextCursor();
       
   544 	}
       
   545 
       
   546 void CTCursorTest::ResetMoveWindowsL()
       
   547 	{
       
   548 	SetCursor(TPoint(10,90),TSize(80,100),TRgb(255,255,255));
       
   549 	iWinState=0;
       
   550 	iWinPos=TPoint(2*TheClient->iGroup->Size().iWidth/3,0);
       
   551 	iMoveWin->SetExtL(iWinPos,TSize(TestWin->Size().iWidth/2,TestWin->Size().iHeight/2));
       
   552 	iCheckWin->SetExtL(TPoint(TestWin->Size().iWidth+(TestWin->Size().iWidth>>1),TestWin->Size().iHeight>>1),
       
   553 														TSize(TestWin->Size().iWidth/2,TestWin->Size().iHeight/2));
       
   554 	}
       
   555 
       
   556 TBool CTCursorTest::MoveWindow()
       
   557 	{
       
   558 	TSize scrSize(TheClient->iScreen->SizeInPixels());
       
   559 	iWinState++;
       
   560 	if (iWinState<20)
       
   561 		iWinPos+=TPoint((4*scrSize.iWidth)/640,(4*scrSize.iHeight)/240);
       
   562 	else if (iWinState<40)
       
   563 		iWinPos+=TPoint((1*scrSize.iWidth)/640,(-3*scrSize.iHeight)/240);
       
   564 	else if (iWinState<60)
       
   565 		iWinPos+=TPoint((-6*scrSize.iWidth)/640,(3*scrSize.iHeight)/240);
       
   566 	else
       
   567 		iWinPos+=TPoint((1*scrSize.iWidth)/640,(-2*scrSize.iHeight)/240);
       
   568 	iMoveWin->SetPos(iWinPos);
       
   569 	return (iWinState==80);
       
   570 	}
       
   571 
       
   572 void CTCursorTest::ValidateWin(TestWindow *aWin, TRgb aColor)
       
   573 	{
       
   574 	aWin->Win()->Invalidate();
       
   575 	RedrawWin(*aWin->Win(),aColor);
       
   576 	}
       
   577 
       
   578 void CTCursorTest::RedrawWin(RWindow &aWin, TRgb aColor)
       
   579 	{
       
   580 	aWin.BeginRedraw();
       
   581 	TheClient->iGc->Activate(aWin);
       
   582 	TheClient->iGc->SetBrushColor(aColor);
       
   583 	TheClient->iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   584 	TheClient->iGc->SetPenStyle(CGraphicsContext::ENullPen);
       
   585 	TheClient->iGc->Clear();
       
   586 	TheClient->iGc->Deactivate();
       
   587 	aWin.EndRedraw();
       
   588 	}
       
   589 
       
   590 void CTCursorTest::ScrollTest()
       
   591 	{
       
   592 	const TSize size(20,40);
       
   593 	ValidateWin(TestWin,TRgb::Gray256(255));
       
   594 
       
   595 	SetCursor(TPoint(10,20),size,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
       
   596 	TheClient->iWs.Flush();
       
   597 	TheClient->WaitForRedrawsToFinish();
       
   598 	TheClient->iWs.Finish();
       
   599 
       
   600 	for(TInt ii=0;ii<20;ii++)
       
   601 		{
       
   602 		TInt dist=(ii&3)*2;
       
   603 		TInt nx=ii&0x1?1:-1;
       
   604 		TInt ny=ii&0x2?1:-1;
       
   605 		TestWin->Win()->Scroll(TPoint(dist*nx,dist*ny),TRect(10,20,30,40));
       
   606 		TheClient->iWs.Flush();
       
   607 		}
       
   608 	TheClient->WaitForRedrawsToFinish();
       
   609 	TheClient->iWs.Finish();
       
   610 
       
   611 	BaseWin->Win()->Invalidate();
       
   612 	BaseWin->Win()->BeginRedraw();
       
   613 	TheClient->iGc->Activate(*(BaseWin->Win()));
       
   614 	TheClient->iGc->Clear();
       
   615 	TheClient->iGc->SetBrushColor(TRgb::Gray256(255));
       
   616 	TheClient->iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   617 	TheClient->iGc->SetPenStyle(CGraphicsContext::ENullPen);
       
   618 	TheClient->iGc->Clear(TRect(TPoint(10,20),size));
       
   619 	TheClient->iGc->Deactivate();
       
   620 	BaseWin->Win()->EndRedraw();
       
   621 
       
   622 	TheClient->iWs.Flush();
       
   623 	TheClient->WaitForRedrawsToFinish();
       
   624 	TheClient->iWs.Finish();
       
   625 
       
   626 	/*
       
   627 	 * NOTE: Reason for removal of COMPARE_WINDOWS_SOFTFAIL_WINSCW
       
   628 	 * Due to the new implementation of sprites in wserv2, the sprites no longer keep a 
       
   629 	 * backup bitmap of what the screen looks like beneath them. As it is not possible to 
       
   630 	 * move the sprites associated with the custom text cursors that were created in second 
       
   631 	 * phase construction of the CTCursorTest object, the COMPARE_WINDOWS_SOFTFAIL_WINSCW; 
       
   632 	 * macro function has been removed. Otherwise the test case is going to subject to the
       
   633 	 * timing of the flashing sprite. An alternative solution would be to assign NULL values
       
   634 	 * to the sprite bitmaps in second phase construction, but this is avoided as it would
       
   635 	 * trigger failures in some test cases later on (that are depended on these "embedded"
       
   636 	 * sprite images).
       
   637 	 */	
       
   638 	CancelTextCursor();
       
   639 	}
       
   640 
       
   641 void DrawTestSprite(CBitmapContext *aGc,TInt , const TSize &aSize, TBool aDoMask, TAny *)
       
   642 	{
       
   643 	aGc->SetBrushColor(TRgb::Gray4(aDoMask ? 0 : 2));
       
   644 	aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   645 	aGc->SetPenStyle(CGraphicsContext::ENullPen);
       
   646 	aGc->DrawRect(TRect(aSize));
       
   647 	aGc->SetPenStyle(CGraphicsContext::ESolidPen);
       
   648 	aGc->SetPenColor(TRgb::Gray4(aDoMask ? 3 : 0));
       
   649 	aGc->SetBrushColor(TRgb::Gray4(aDoMask ? 3 : 1));
       
   650 	aGc->DrawEllipse(TRect(aSize));
       
   651 	}
       
   652 
       
   653 CTSprite *CTCursorTest::CreateTestSpriteLC(RWindowTreeNode &aWindow, const TPoint &aPos, TInt aCount)
       
   654 //
       
   655 // At the moment aCount must be 1 or 2
       
   656 //
       
   657 	{
       
   658 	TSpriteCreateParams params(TSize(30,70),TPoint(0,0),DrawTestSprite);
       
   659 	TSpriteCreateParams paramarray[2];
       
   660 	params.iInterval=TTimeIntervalMicroSeconds32(200000);
       
   661 
       
   662 	paramarray[0]=params;
       
   663 	paramarray[1]=params;
       
   664 	paramarray[1].iSize=TSize(100,10);
       
   665 	CTSprite *sprite=new(ELeave) CTSprite(TheClient->iWs);
       
   666 	CleanupStack::PushL(sprite);
       
   667 	sprite->ConstructL(aWindow,aPos,aCount,&paramarray[0],0);
       
   668 	return(sprite);
       
   669 	}
       
   670 
       
   671 void CTCursorTest::doMoveWindowTestL()
       
   672 	{
       
   673 	RBlankWindow blankwin(TheClient->iWs);
       
   674 	User::LeaveIfError(blankwin.Construct(*TestWin->Win(),1));
       
   675 	CleanupStack::PushL(TCleanupItem(CleanUpWindow,&blankwin));
       
   676 //
       
   677 	blankwin.SetExtent(TPoint(35,165),TSize(40,40));
       
   678 	blankwin.SetColor(TRgb::Gray256(220));
       
   679 	blankwin.Activate();
       
   680 	TheClient->iWs.SetAutoFlush(ETrue);
       
   681 	User::After(500000);
       
   682 	blankwin.SetPosition(TPoint(25,55));
       
   683 	User::After(500000);
       
   684 	blankwin.SetPosition(TPoint(30,160));
       
   685 	User::After(500000);
       
   686 	blankwin.SetPosition(TPoint(12,22));	// Almost totally covering sprite
       
   687 	User::After(500000);
       
   688 	blankwin.SetPosition(TPoint(-100,-100));	// Totally off the sprite
       
   689 	User::After(500000);
       
   690 	blankwin.SetPosition(TPoint(10,20));	// Write on top of sprite
       
   691 	User::After(500000);
       
   692 	blankwin.SetPosition(TPoint(24,24));	// moving off...
       
   693 	User::After(500000);
       
   694 	blankwin.SetPosition(TPoint(38,28));	// ...
       
   695 	User::After(500000);
       
   696 	blankwin.SetPosition(TPoint(58,48));	// ...
       
   697 	User::After(500000);
       
   698 	blankwin.SetPosition(TPoint(92,62));	// ... off
       
   699 	User::After(500000);
       
   700 	CleanupStack::PopAndDestroy();	// blank window
       
   701 	TheClient->iWs.Flush();
       
   702 	TheClient->WaitForRedrawsToFinish();
       
   703 	TheClient->iWs.Finish();
       
   704 
       
   705 	TheClient->iWs.SetAutoFlush(EFalse);
       
   706 	}
       
   707 
       
   708 void CTCursorTest::MoveWindowTest1L()
       
   709 	{
       
   710 	ValidateWin(TestWin,TRgb::Gray256(255));
       
   711 // Check it with a static sprite
       
   712 	CTSprite * sprite_static = CreateTestSpriteLC(*TestWin->Win(), TPoint(10,20), 1);
       
   713 	doMoveWindowTestL();
       
   714 	(sprite_static->Sprite()).SetPosition(TPoint(500,500)); //move the sprite out of the viewing area before the window comparison 
       
   715 	CleanupStack::PopAndDestroy(1);	// sprite
       
   716 // Check it an animated sprite
       
   717 	CTSprite * sprite_anim = CreateTestSpriteLC(*TestWin->Win(), TPoint(10,20), 2);
       
   718 	doMoveWindowTestL();
       
   719 	(sprite_anim->Sprite()).SetPosition(TPoint(500,500)); //move the sprite out of the viewing area before the window comparison
       
   720 	CleanupStack::PopAndDestroy(1);	// sprite
       
   721 	}
       
   722 
       
   723 void CTCursorTest::MoveWindowTest2L()
       
   724 	{
       
   725 	const TSize size(20,40);
       
   726 // Check it with a text cursor
       
   727 	ValidateWin(TestWin,TRgb::Gray256(255));
       
   728 	SetCursor(TPoint(10,25),size,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
       
   729 	doMoveWindowTestL();
       
   730 	CancelTextCursor();
       
   731 // Check it with an anaimated sprite and a text cursor
       
   732 	ValidateWin(TestWin,TRgb::Gray256(255));
       
   733 	CTSprite * sprite_anim = CreateTestSpriteLC(*TestWin->Win(), TPoint(10,20), 2);
       
   734 	SetCursor(TPoint(10,45),size,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
       
   735 	doMoveWindowTestL();
       
   736 	(sprite_anim->Sprite()).SetPosition(TPoint(500,500));
       
   737 	CancelTextCursor();
       
   738 	CleanupStack::PopAndDestroy(1);	// sprite
       
   739 	}
       
   740 
       
   741 TBool CTCursorTest::IncrementCursorType()
       
   742 	{
       
   743 	// each screen has it own set of cursor
       
   744 	//
       
   745 	// the values would be ETypeLast=2 ETypeLastBasic=1009
       
   746 	//
       
   747 	if (iCursorType == TTextCursor::ETypeFirst)
       
   748 		{
       
   749 		iCursorType = (TTextCursor::EType)(TTextCursor::ETypeLastBasic + 1 + iTest->iScreenNumber*KNumberOfCustoTextCursors);
       
   750 		return ETrue;
       
   751 		}
       
   752 	else if (iCursorType >= TTextCursor::ETypeLastBasic + (iTest->iScreenNumber+1)*KNumberOfCustoTextCursors)
       
   753 		{
       
   754 		iCursorType = TTextCursor::ETypeFirst;
       
   755 		return EFalse;
       
   756 		}
       
   757 	else
       
   758 		{
       
   759 		iCursorType = (TTextCursor::EType)(iCursorType + 1);
       
   760 		return ETrue;
       
   761 		}
       
   762 	}
       
   763 
       
   764 void CTCursorTest::GeneralTestsL()
       
   765 	{
       
   766 	const TInt winColor=255;		//Best to use Light Grey that is 170, but this code is bugged and doing so shows them up.
       
   767 	ValidateWin(BaseWin,TRgb::Gray256(255));
       
   768 	ValidateWin(TestWin,TRgb::Gray256(255));
       
   769 	SetCursor(TPoint(-1000,10),TSize(10,30),TRgb::Gray256(255));
       
   770 	TheClient->iWs.Flush();
       
   771 	SetCursor(TPoint(10,10),TSize(10,30),TRgb::Gray256(255));
       
   772 	TheClient->iWs.Flush();
       
   773 	TRect rect(15,15,18,25);
       
   774 	SetCursorPlusBox(TPoint(10,10),TSize(10,30),TRgb::Gray256(255), &rect);
       
   775 	CancelTextCursor();
       
   776 //
       
   777 	ValidateWin(BaseWin,TRgb::Gray256(255));
       
   778 	ValidateWin(TestWin,TRgb::Gray256(255));
       
   779 	TheClient->iWs.Flush();
       
   780 	for(TInt winType=0;winType<3;winType++)
       
   781 		{
       
   782 		RWindowBase *cursorwin=NULL;
       
   783 		RBackedUpWindow backcursorwin(TheClient->iWs);
       
   784 		RWindow backwindow(TheClient->iWs);
       
   785 		RBlankWindow backblankwin(TheClient->iWs);
       
   786 		switch(winType)
       
   787 			{
       
   788 			case 0:
       
   789 				cursorwin=&backcursorwin;
       
   790 				User::LeaveIfError(backcursorwin.Construct(*TestWin->BaseWin(),EGray4,1));
       
   791 				break;
       
   792 			case 1:
       
   793 				cursorwin=&backwindow;
       
   794 				User::LeaveIfError(backwindow.Construct(*TestWin->BaseWin(),1));
       
   795 				break;
       
   796 			case 2:
       
   797 				cursorwin=&backblankwin;
       
   798 				User::LeaveIfError(backblankwin.Construct(*TestWin->BaseWin(),1));
       
   799 				break;
       
   800 			}
       
   801 		CleanupStack::PushL(TCleanupItem(CleanUpWindow,cursorwin));
       
   802 		User::LeaveIfError(cursorwin->SetSizeErr(TestWin->BaseWin()->Size()));
       
   803 		cursorwin->Activate();
       
   804 //
       
   805 		TTextCursor tc;
       
   806 		tc.iType=iCursorType;
       
   807 		tc.iHeight=30;
       
   808 		tc.iAscent=0;
       
   809 		tc.iWidth=50;
       
   810 		tc.iFlags=0;
       
   811 		tc.iColor=TRgb::Gray256(255);
       
   812 		TheClient->iGroup->GroupWin()->SetTextCursor(*cursorwin,TPoint(10,10),tc);
       
   813 //
       
   814 		CreateTestSpriteLC(*cursorwin, TPoint(10,20), 2);
       
   815 //
       
   816 		if (cursorwin==&backwindow)
       
   817 			RedrawWin(backwindow,TRgb::Gray256(255));
       
   818 		for(TInt count=0;count<9;count++)
       
   819 			{
       
   820 			RWindowBase *pwin=NULL;
       
   821 			RBackedUpWindow backedup(TheClient->iWs);
       
   822 			RWindow window(TheClient->iWs);
       
   823 			RBlankWindow blankwin(TheClient->iWs);
       
   824 			switch(count%3)
       
   825 				{
       
   826 				case 0:
       
   827 					pwin=&window;
       
   828 					window.Construct(*cursorwin,2);
       
   829 					window.SetBackgroundColor(TRgb(winColor,winColor,winColor));
       
   830 					break;
       
   831 				case 1:
       
   832 					pwin=&backedup;
       
   833 					backedup.Construct(*cursorwin,EGray4,2);
       
   834 					break;
       
   835 				case 2:
       
   836 					pwin=&blankwin;
       
   837 					blankwin.Construct(*cursorwin,2);
       
   838 					blankwin.SetColor(TRgb(winColor,winColor,winColor));
       
   839 					break;
       
   840 				}
       
   841 			CleanupStack::PushL(TCleanupItem(CleanUpWindow,pwin));
       
   842 			pwin->SetExtentErr(TPoint(30,30),TSize(50,80));
       
   843 			pwin->Activate();
       
   844 			TheClient->iWs.Flush();
       
   845 			CleanupStack::PopAndDestroy();	// window
       
   846 			if (cursorwin==&backwindow)
       
   847 				RedrawWin(backwindow,TRgb::Gray256(255));
       
   848 			TheClient->iWs.Flush();
       
   849 			TheClient->WaitForRedrawsToFinish();
       
   850 			COMPARE_WINDOWS_SOFTFAIL_WINSCW;
       
   851 			User::After(200000);	// Wait a fifth of a second to make sure the test is run during different states of flashing
       
   852 			}
       
   853 		for(TInt count2=0;count2<4;count2++)
       
   854 			{
       
   855 			cursorwin->SetPosition(TPoint(10,5));
       
   856 			TheClient->iWs.Flush();
       
   857 			User::After(100000);
       
   858 			cursorwin->SetPosition(TPoint(5,10));
       
   859 			TheClient->iWs.Flush();
       
   860 			User::After(100000);
       
   861 			cursorwin->SetPosition(TPoint(0,0));
       
   862 			TheClient->iWs.Flush();
       
   863 			User::After(100000);
       
   864 			TheClient->WaitForRedrawsToFinish();
       
   865 			COMPARE_WINDOWS_SOFTFAIL_WINSCW;
       
   866 			}
       
   867 		CleanupStack::PopAndDestroy(2);	// sprite & window containing sprite and cursor
       
   868 		}
       
   869 	CancelTextCursor();
       
   870 	}
       
   871 
       
   872 void CTCursorTest::INC040489L()
       
   873 	{
       
   874 	INFO_PRINTF1(_L("AUTO_TCur INC040489 "));
       
   875 	RWindowGroup group1(TheClient->iWs);
       
   876 	PushWindowL(&group1);
       
   877 	User::LeaveIfError(group1.Construct(ENullWsHandle));
       
   878 	RBlankWindow blank1(TheClient->iWs);
       
   879 	PushWindowL(&blank1);
       
   880 	User::LeaveIfError(blank1.Construct(group1,ENullWsHandle));
       
   881 	blank1.SetRequiredDisplayMode(EColor4K);
       
   882 	blank1.SetColor(TRgb(250,150,0));
       
   883 	blank1.Activate();
       
   884 	RWindowGroup group2(TheClient->iWs);
       
   885 	PushWindowL(&group2);
       
   886 	User::LeaveIfError(group2.Construct(ENullWsHandle));
       
   887 	RBlankWindow blank2(TheClient->iWs);
       
   888 	PushWindowL(&blank2);
       
   889 	User::LeaveIfError(blank2.Construct(group2,ENullWsHandle));
       
   890 	blank2.SetRequiredDisplayMode(EColor4K);
       
   891 	blank2.SetColor(TRgb(75,200,125));
       
   892 	blank2.Activate();
       
   893 	TheClient->Flush();
       
   894 	INFO_PRINTF1(_L(" Created Windows "));
       
   895 	TTextCursor tc;
       
   896 	tc.iType=KTextCursorInitialIdValue + iTest->iScreenNumber*KNumberOfCustoTextCursors;
       
   897 	tc.iHeight=80;
       
   898 	tc.iAscent=10;
       
   899 	tc.iWidth=30;
       
   900 	tc.iFlags=0;
       
   901 	tc.iColor=TRgb::Gray256(255);
       
   902 	INFO_PRINTF1(_L(" About to Set Text Cursor 1 "));
       
   903 	group2.SetTextCursor(blank2,TPoint(20,20),tc);
       
   904 	TheClient->Flush();
       
   905 	INFO_PRINTF1(_L(" Set Text Cursor 1 "));
       
   906 	User::After(2000000);		//2sec
       
   907 	TheClient->iWs.PrepareForSwitchOff();
       
   908 	TheClient->Flush();
       
   909 	User::After(2000000);		//2sec
       
   910 	group1.SetOrdinalPosition(0);
       
   911 	group2.CancelTextCursor();
       
   912 	TheClient->Flush();
       
   913 	INFO_PRINTF1(_L(" Canceled Text Cursor "));
       
   914 	User::After(2000000);		//2sec
       
   915 	//
       
   916 	// Before applying the fix, the following operations makes the Custom Text 
       
   917 	// Cursor Sprite invisible (happens even without wserv heartbeat suppression)
       
   918 	INFO_PRINTF1(_L(" About to Set Text Cursor 2 "));
       
   919 	group1.SetOrdinalPosition(2);
       
   920 	group2.SetTextCursor(blank2,TPoint(20,20),tc);
       
   921 	TheClient->Flush();
       
   922 	INFO_PRINTF1(_L(" Set Text Cursor 2 "));
       
   923 	User::After(2000000);		//2sec
       
   924 	TRawEvent event;
       
   925 	event.Set(TRawEvent::EActive);
       
   926 	TheClient->iWs.SimulateRawEvent(event);
       
   927 	TheClient->Flush();
       
   928 	INFO_PRINTF1(_L(" Simulated Active Event "));
       
   929 	User::After(2000000);		//2sec
       
   930 	CleanupStack::PopAndDestroy(4, &group1);
       
   931 	INFO_PRINTF1(_L(" End of test "));
       
   932 	}
       
   933 
       
   934 void CTCursorTest::CursorUpdatedBeforeWindowRenderedL()
       
   935 	{
       
   936 	INFO_PRINTF1(_L("CursorUpdatedBeforeWindowRenderedL"));
       
   937 	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0);
       
   938 	// We use some unique looking colors otherwise its harder
       
   939 	// to spot which test is which
       
   940 	TRgb kAqua(134, 242, 251);
       
   941 	
       
   942 	iWorkInProgress = new(ELeave) CBlankWindow(kAqua);
       
   943 	iComparisonWindow = new(ELeave) CBlankWindow(kAqua);
       
   944 	CancelTextCursor();
       
   945 	
       
   946 	const TSize screenSize=TheClient->iGroup->Size();
       
   947 	const TInt kPad = 5;
       
   948 	const TInt kThirdOfScreenWidth = screenSize.iWidth/3;
       
   949 	const TInt kWinWidth = kThirdOfScreenWidth - 2*kPad;
       
   950 	const TInt kWinHeight = screenSize.iHeight - 2*kPad;
       
   951 	const TSize kWinSize(kWinWidth, kWinHeight);
       
   952 	const TPoint kCursorPos(30, 30);
       
   953 	iComparisonWindow->SetUpL(TPoint(2*kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
       
   954 	iWorkInProgress->SetUpL(  TPoint(  kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
       
   955 	
       
   956 	TTextCursor nonFlashingCursor;
       
   957 	nonFlashingCursor.iType = TTextCursor::ETypeRectangle;
       
   958 	nonFlashingCursor.iHeight=kCursorHeight;
       
   959 	nonFlashingCursor.iAscent=0;
       
   960 	nonFlashingCursor.iWidth=kCursorWidth;
       
   961 	nonFlashingCursor.iFlags=TTextCursor::EFlagNoFlash;
       
   962 	nonFlashingCursor.iColor = KRgbBlack; 
       
   963 	TheClient->iGroup->GroupWin()->SetTextCursor(*iWorkInProgress->BaseWin(), kCursorPos, nonFlashingCursor);
       
   964 	
       
   965 	// Up till this point, there has not been a CWsWindow::Render() for iWorkInProgress
       
   966 	// because the window has not been invalid
       
   967 	
       
   968 	/*
       
   969 	 * Here is the crux of the test.  We want to create the following condition in a window group:
       
   970 	 * 1) None of its windows have yet been Rendered using CWsWindow::Render()
       
   971 	 * 2) A text cursor is present
       
   972 	 * 3) Focus is lost then received
       
   973 	 * 
       
   974 	 * It used to be the case that Wserv picked up the handle to the Render Stage Text Cursor
       
   975 	 * drawer upon a Refresh caused by Rendering the window.  But drawing the Text Cursor could
       
   976 	 * come either from a Window Render or a change to the state of the Text Cursor, such as
       
   977 	 * receiving focus in the window.  A bug was experienced when the Text Cursor was drawn in
       
   978 	 * a window which never had been rendered.  This meant that the handle was not set up causing
       
   979 	 * an assert.
       
   980 	 * 
       
   981 	 * The code has been modified since then, to setup the handle to the Render Stage Text
       
   982 	 * Cursor during Wserv initialisation.  However, to guard against future changes, its
       
   983 	 * worthwhile to have this corner case test to ensure it is possible to receive focus
       
   984 	 * in a window which has never been rendered.  That is because the text cursor state
       
   985 	 * is updated in such circumstances, and that might trigger a draw of the cursor in a
       
   986 	 * future version of the text cursor code.
       
   987 	 */
       
   988 	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(1);  // lose focus
       
   989 	TheClient->iWs.Finish();
       
   990 	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0); // gain focus
       
   991 	TheClient->iWs.Finish();
       
   992 	
       
   993 	// If we get this far without a panic or assert, we have passed this test.
       
   994 	
       
   995 	// Now allow CWsWindow::Render() to occur in iWorkInProgress
       
   996 	// The reason for doing this is so that when you watch the test
       
   997 	// progress you can see visual confirmation via the progress message and
       
   998 	// the coloured windows appear on the screen.  Otherwise you would think
       
   999 	// that the test had either been skipped or had broken.
       
  1000 	iWorkInProgress->Invalidate();
       
  1001 	iWorkInProgress->Redraw();
       
  1002 	iComparisonWindow->Invalidate();
       
  1003 	iComparisonWindow->Redraw();
       
  1004 	TheClient->iWs.Finish();
       
  1005 	delete iWorkInProgress;
       
  1006 	iWorkInProgress = NULL;
       
  1007 	delete iComparisonWindow;
       
  1008 	iComparisonWindow = NULL;
       
  1009 	INFO_PRINTF1(_L("End of test"));
       
  1010 	}
       
  1011 
       
  1012 void CTCursorTest::INC097774()
       
  1013 	{
       
  1014 	TTimeIntervalMicroSeconds32 initialRepeatRate;
       
  1015 	TTimeIntervalMicroSeconds32 repeatRate;
       
  1016 	TheClient->iWs.GetKeyboardRepeatRate(initialRepeatRate,repeatRate);
       
  1017 	
       
  1018 	//simulates a text cursor moving across the screen as if a user was holding down
       
  1019 	//a key to scroll the cursor through a section of text.
       
  1020 	//before applying the fix the cursor only shows up intermittently instead of smoothly
       
  1021 	//scrolling across the screen.
       
  1022 	const TSize cursorSize(3,20);
       
  1023 	const TInt moveInterval=10;
       
  1024 	SetCursor(TPoint(0,20),cursorSize,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
       
  1025 	TheClient->Flush();
       
  1026 	User::After(initialRepeatRate);
       
  1027 	for(TInt offset=10;offset<=100;offset+=moveInterval)
       
  1028 		{
       
  1029 		SetCursor(TPoint(offset,20),cursorSize,TRgb::Gray256(255),TTextCursor::EFlagNoFlash);
       
  1030 		TheClient->Flush();
       
  1031 		User::After(repeatRate);
       
  1032 		}
       
  1033 		
       
  1034 	//simulate clipped text cursor moving accross the screen
       
  1035 	TRect rect(0,20,3,40);
       
  1036 	SetCursor(TPoint(0,20),cursorSize,TRgb::Gray256(255),rect,TTextCursor::EFlagNoFlash);
       
  1037 	TheClient->Flush();
       
  1038 	User::After(initialRepeatRate);
       
  1039 	for(TInt offset=10;offset<=100;offset+=moveInterval)
       
  1040 		{
       
  1041 		rect.Move(moveInterval,0);
       
  1042 		SetCursor(TPoint(offset,20),cursorSize,TRgb::Gray256(255),rect,TTextCursor::EFlagNoFlash);
       
  1043 		TheClient->Flush();
       
  1044 		User::After(repeatRate);
       
  1045 		}	
       
  1046 	}
       
  1047 /** What happens when a cursor becomes off-screen when the screen is resized/rotated? 
       
  1048  * 
       
  1049  * 
       
  1050  **/
       
  1051 void CTCursorTest::INC117232()
       
  1052 	{
       
  1053 	const TInt initialRepeatRate=300000;	// 3/10 seconds should be long enough to update everything!
       
  1054 	TInt currMode=TheClient->iScreen->CurrentScreenMode();
       
  1055 	TInt testMode=currMode;
       
  1056 	TPixelsTwipsAndRotation currModeSize;
       
  1057 	TheClient->iScreen->GetScreenModeSizeAndRotation(currMode, currModeSize);
       
  1058 	//find a (rotated) mode where the dimensions of the screen shrank
       
  1059 	for (TInt mode=0;mode<TheClient->iScreenModes.Count();mode++)
       
  1060 		{
       
  1061 		TPixelsTwipsAndRotation testModeSize;
       
  1062 		TheClient->iScreen->GetScreenModeSizeAndRotation(mode,testModeSize);
       
  1063 		if (	testModeSize.iPixelSize.iWidth<currModeSize.iPixelSize.iWidth-10
       
  1064 			||	testModeSize.iPixelSize.iHeight<currModeSize.iPixelSize.iHeight-10
       
  1065 			)
       
  1066 			{
       
  1067 			testMode=mode;
       
  1068 			break;
       
  1069 			}
       
  1070 		}
       
  1071 	if (testMode==currMode)
       
  1072 		{
       
  1073 		_LIT(KLog,"No smaller screen-size modes available - INC117232 test skipped");
       
  1074 		LOG_MESSAGE(KLog);
       
  1075 		//iStep->SetTestStepResult(EInconclusive);		//With this line the whole test fails which is too drastic
       
  1076 		return;
       
  1077 		}
       
  1078 	//enable a cursor on the bottom right corner of the screen
       
  1079 	TestWin->SetFullScreenExtL();
       
  1080 	TheClient->Flush();
       
  1081 	iCursorType=TTextCursor::ETypeRectangle;
       
  1082 	SetCursor(TPoint(-20,-20)+TestWin->Size(),TSize(40,40),KRgbDarkMagenta,TTextCursor::EFlagNoFlash);
       
  1083 	TheClient->Flush();
       
  1084 	User::After(initialRepeatRate);
       
  1085 	//shrink the screen
       
  1086 	TheClient->iScreen->SetScreenMode(testMode);
       
  1087 	TheClient->iScreen->SetAppScreenMode(testMode);
       
  1088 	//The defect was that WServ would now crash! 
       
  1089 	TheClient->Flush();
       
  1090 	User::After(initialRepeatRate);
       
  1091 	//Set everything back
       
  1092 	TheClient->iScreen->SetScreenMode(currMode);
       
  1093 	TheClient->iScreen->SetAppScreenMode(currMode);
       
  1094 	TheClient->Flush();
       
  1095 	User::After(initialRepeatRate);
       
  1096 	}
       
  1097 
       
  1098 #ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
       
  1099 /**
       
  1100  * Sets up a text cursor whose attributes indicate it should not be flashing
       
  1101  * and then checks to ensure this is the actual behaviour.
       
  1102  */
       
  1103 void CTCursorTest::TextCursorNoFlashTestL()
       
  1104 	{
       
  1105 	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0);
       
  1106 	// We use some unique looking colors otherwise its harder
       
  1107 	// to spot which test is which
       
  1108 	TRgb kGentleYellow(251, 249, 198);
       
  1109 	TRgb kGentlePink(253, 196, 221);
       
  1110 	
       
  1111 	iWorkInProgress = new(ELeave) CBlankWindow(kGentleYellow);
       
  1112 	iComparisonWindow = new(ELeave) CBlankWindow(kGentleYellow);
       
  1113 	CancelTextCursor();
       
  1114 	TheClient->Flush();
       
  1115 	
       
  1116 	const TSize screenSize=TheClient->iGroup->Size();
       
  1117 	const TInt kPad = 5;
       
  1118 	const TInt kThirdOfScreenWidth = screenSize.iWidth/3;
       
  1119 	const TInt kWinWidth = kThirdOfScreenWidth - 2*kPad;
       
  1120 	const TInt kWinHeight = screenSize.iHeight - 2*kPad;
       
  1121 	const TSize kWinSize(kWinWidth, kWinHeight);
       
  1122 	const TPoint kCursorPos(30, 30);
       
  1123 	iWorkInProgress->SetUpL(  TPoint(  kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
       
  1124 	iComparisonWindow->SetUpL(TPoint(2*kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
       
  1125 	
       
  1126 	TTextCursor nonFlashingCursor;
       
  1127 	
       
  1128 	nonFlashingCursor.iType = TTextCursor::ETypeRectangle;
       
  1129 	nonFlashingCursor.iHeight=kCursorHeight;
       
  1130 	nonFlashingCursor.iAscent=0;
       
  1131 	nonFlashingCursor.iWidth=kCursorWidth;
       
  1132 	nonFlashingCursor.iFlags=TTextCursor::EFlagNoFlash;
       
  1133 	nonFlashingCursor.iColor = kGentlePink; // We expect a Flicker Buffer Render Stage to ignore this color
       
  1134 	
       
  1135 	iWorkInProgress->Invalidate();
       
  1136 	iWorkInProgress->Redraw();
       
  1137 	iComparisonWindow->Invalidate();
       
  1138 	iComparisonWindow->Redraw();
       
  1139 	
       
  1140 	DrawTextCursorSimilarToRenderStage(*TheClient->iGc, *iComparisonWindow->Win(), kCursorPos, nonFlashingCursor);
       
  1141 	TheClient->iGroup->GroupWin()->SetTextCursor(*iWorkInProgress->BaseWin(), kCursorPos, nonFlashingCursor);
       
  1142 	TheClient->Flush();
       
  1143 		
       
  1144 	CheckCursorDoesNotFlash(iWorkInProgress->BaseWin()->Size());
       
  1145 	
       
  1146 	delete iWorkInProgress;
       
  1147 	iWorkInProgress = NULL;
       
  1148 	delete iComparisonWindow;
       
  1149 	iComparisonWindow = NULL;
       
  1150 	}
       
  1151 
       
  1152 void CTCursorTest::TextCursorFlashTestL()
       
  1153 	{
       
  1154 	TheClient->iGroup->WinTreeNode()->SetOrdinalPosition(0);
       
  1155 	// We use some unique looking colors otherwise its harder
       
  1156 	// to spot which test is which
       
  1157 	TRgb kMildPurple(218, 155, 244);
       
  1158 	TRgb kPaleGreen(146, 190, 12);
       
  1159 	
       
  1160 	iWorkInProgress = new(ELeave) CBlankWindow(kMildPurple);
       
  1161 	iComparisonWindow = new(ELeave) CBlankWindow(kMildPurple);
       
  1162 	CancelTextCursor();
       
  1163 	TheClient->Flush();
       
  1164 	
       
  1165 	const TSize screenSize=TheClient->iGroup->Size();
       
  1166 	const TInt kPad = 5;
       
  1167 	const TInt kThirdOfScreenWidth = screenSize.iWidth/3;
       
  1168 	const TInt kWinWidth = kThirdOfScreenWidth - 2*kPad;
       
  1169 	const TInt kWinHeight = screenSize.iHeight - 2*kPad;
       
  1170 	const TSize kWinSize(kWinWidth, kWinHeight);
       
  1171 	const TPoint kCursorPos(30, 30);
       
  1172 	iWorkInProgress->SetUpL(  TPoint(  kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
       
  1173 	iComparisonWindow->SetUpL(TPoint(2*kThirdOfScreenWidth + kPad, kPad), kWinSize, TheClient->iGroup, *TheClient->iGc);
       
  1174 	
       
  1175 	TTextCursor flashingCursor;
       
  1176 	
       
  1177 	flashingCursor.iType = TTextCursor::ETypeRectangle;
       
  1178 	flashingCursor.iHeight=kCursorHeight;
       
  1179 	flashingCursor.iAscent=0;
       
  1180 	flashingCursor.iWidth=kCursorWidth;
       
  1181 	flashingCursor.iFlags=0; // implies that cursor SHOULD flash
       
  1182 	flashingCursor.iColor = kPaleGreen; // We expect a Flicker Buffer Render Stage to ignore this color
       
  1183 
       
  1184 	iWorkInProgress->Invalidate();
       
  1185 	iWorkInProgress->Redraw();
       
  1186 	iComparisonWindow->Invalidate();
       
  1187 	iComparisonWindow->Redraw();
       
  1188 	
       
  1189 	DrawTextCursorSimilarToRenderStage(*TheClient->iGc, *iComparisonWindow->Win(), kCursorPos, flashingCursor);
       
  1190 	TheClient->iGroup->GroupWin()->SetTextCursor(*iWorkInProgress->BaseWin(), kCursorPos, flashingCursor);
       
  1191 	TheClient->Flush();
       
  1192 	
       
  1193 	CheckCursorDoesFlash(kCursorPos, flashingCursor, kMildPurple);
       
  1194 	CancelTextCursor();
       
  1195 	TheClient->Flush();
       
  1196 	
       
  1197 	delete iWorkInProgress;
       
  1198 	iWorkInProgress = NULL;
       
  1199 	delete iComparisonWindow;
       
  1200 	iComparisonWindow = NULL;
       
  1201 	}
       
  1202 
       
  1203 void CTCursorTest::DrawTextCursorSimilarToRenderStage(CWindowGc& aGc, RWindow& aWin, const TPoint& aPos, const TTextCursor& aTextCursor)
       
  1204 	{
       
  1205 	// This method duplicates the way in which the default FlickerBuffer Render
       
  1206 	// Stage draws a Text Cursor of ETypeRectangle.  @see CFbRenderStage::DrawTextCursor
       
  1207 	// This code must be kept in sync with the FlickerBuffer Render Stage
       
  1208 	
       
  1209 	ASSERT(aTextCursor.iType == TTextCursor::ETypeRectangle);
       
  1210 	const TRect updatedRegion(aPos,TSize(aTextCursor.iWidth,aTextCursor.iHeight));
       
  1211 	aWin.Invalidate();
       
  1212 	aWin.BeginRedraw();
       
  1213 	aGc.Activate(aWin);
       
  1214 	aGc.Clear();
       
  1215 	aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1216 	aGc.SetBrushColor(KRgbBlack);
       
  1217 	aGc.SetPenStyle(CGraphicsContext::ENullPen);
       
  1218 	aGc.Clear(updatedRegion);
       
  1219 	aGc.Deactivate();
       
  1220 	aWin.EndRedraw();
       
  1221 	}
       
  1222 
       
  1223 void CTCursorTest::CheckCursorDoesNotFlash(const TSize& aSize)
       
  1224 	{
       
  1225 	const TInt kSampleTime = 100000; // one tenth of a second
       
  1226 	const TInt kSampleLimit = 100;
       
  1227 	TInt sampleIteration = 0;
       
  1228 	TBool comparisonOkay = EFalse;
       
  1229 	
       
  1230 	while (sampleIteration < kSampleLimit)
       
  1231 		{	
       
  1232 		comparisonOkay = DoCheckRect(iWorkInProgress, iComparisonWindow, TRect(TPoint(), aSize), CWsScreenDevice::EIncludeTextCursor);
       
  1233 		if (!comparisonOkay)
       
  1234 			{
       
  1235 			INFO_PRINTF2(_L("CheckCursorDoesNotFlash difference found after %d milliseconds"), sampleIteration*100);
       
  1236 			break;
       
  1237 			}
       
  1238 		sampleIteration++;
       
  1239 		User::After(kSampleTime);
       
  1240 		}
       
  1241 	TEST(comparisonOkay);
       
  1242 	}
       
  1243 
       
  1244 void CTCursorTest::UpdateCountersOnCursorTransition(
       
  1245 		const TBool	aTransitionedToOn,
       
  1246 		TTime& 		aNow,
       
  1247 		TInt64&		aDeltaTime,
       
  1248 		TTime&		aLastDeltaTime,
       
  1249 		TInt&		aWarmUpIterations,
       
  1250 		const TInt&	aFlashChangeTime,
       
  1251 		const TInt&	aToleranceMargin,
       
  1252 		TInt&		aSampleNumber,
       
  1253 		TInt&		aToleranceViolations
       
  1254 		)
       
  1255 	{
       
  1256 	_LIT(KTxtOn,	" On");
       
  1257 	_LIT(KTxtOff,	"Off");
       
  1258 	TBufC<3> transitionType;	
       
  1259 	transitionType = aTransitionedToOn ? KTxtOn : KTxtOff;
       
  1260 	
       
  1261 	aNow.UniversalTime();
       
  1262 	aDeltaTime = aNow.MicroSecondsFrom(aLastDeltaTime).Int64();
       
  1263 	aLastDeltaTime = aNow;
       
  1264 	
       
  1265 	if (aWarmUpIterations > 0)
       
  1266 		{
       
  1267 		aWarmUpIterations--;
       
  1268 		}
       
  1269 	else
       
  1270 		{
       
  1271 		if (aDeltaTime > aFlashChangeTime + aToleranceMargin ||
       
  1272 				aDeltaTime < aFlashChangeTime - aToleranceMargin)
       
  1273 			{
       
  1274 			INFO_PRINTF5(_L(" Iteration %d, Cursor %S after %d, errorDelta %d microseconds"),
       
  1275 					aSampleNumber, &transitionType, I64INT(aDeltaTime), I64INT(aDeltaTime - aFlashChangeTime));
       
  1276 			aToleranceViolations++;
       
  1277 			}
       
  1278 		}
       
  1279 	}
       
  1280 void CTCursorTest::CheckCursorDoesFlash(const TPoint& aPos, const TTextCursor& aTextCursor, TRgb /* aBackgroundColor */)
       
  1281 	{	
       
  1282 	
       
  1283 	/**
       
  1284 	 * Quality of Service based thresholding
       
  1285 	 * 
       
  1286 	 * The idea behind this test is to identify tolerances which would either
       
  1287 	 * cause the test to fail when the user would perceive the text cursor as
       
  1288 	 * not flashing uniformly, or would point to an unexpected delay outside
       
  1289 	 * the way the flashing (and scheduling of animations) is supposed to work.
       
  1290 	 * 
       
  1291 	 * Potentially the cursor can be late if we miss a V-SYNC from hardware.  In
       
  1292 	 * such cases we expect to see the cursor on the next frame.  Since the V-SYNC
       
  1293 	 * is typically 1/50 second, a tolerance of two frames, or 1/25 second is reasonable.
       
  1294 	 * 
       
  1295 	 * If the cursor is delayed longer than this, say a long time of 1 second, but this
       
  1296 	 * does not happen too often, then the user is likely to still be happy.  So we
       
  1297 	 * set the period of testing to 60 seconds, and set the violations limit to 2.
       
  1298 	 */
       
  1299 	const TInt kOneSecond = 1000000;
       
  1300 	const TInt kFlashPeriod = kOneSecond; 		// comprises one "ON" and one "OFF"
       
  1301 	const TInt kToleranceFactor = 25; 			// meaning 1/25 of a Flash Period
       
  1302 	const TInt kNumberTestFlashPeriods = 60;	// meaning 60 Flash Periods worth of testing
       
  1303 	const TInt kMaximumToleranceViolations = 2;	// number of times an occassional flash may be late or early
       
  1304 	
       
  1305 	const TInt kToleranceMargin = kFlashPeriod / kToleranceFactor;
       
  1306 	const TInt kNumberSamples = kNumberTestFlashPeriods * kToleranceFactor;
       
  1307 	const TInt kFlashChangeTime = kFlashPeriod / 2;
       
  1308 	
       
  1309 	// The first couple of changes to the cursor should be ignored because
       
  1310 	// when the test is started, the cursor may have been on for a while.
       
  1311 	// Then when the cursor goes off, it appears to have switched to the
       
  1312 	// off state too early.  We therefore ignore the first two changes
       
  1313 	// so we start cleanly.
       
  1314 	TInt warmUpIterations = 2;
       
  1315 	
       
  1316 	// Empirically we see that cursors mostly flash with good timeliness apart from
       
  1317 	// occasional events causing them to be either early or late.  In order to keep
       
  1318 	// a tight tolerance (1/50 second is around the screen refresh time) but still
       
  1319 	// allow for the occasional variance (seen to be 1/23 second) we use a counter
       
  1320 	// toleranceViolations < kMaximumToleranceViolations
       
  1321 	TInt toleranceViolations = 0;
       
  1322 	TBool cursorShownLastTime = EFalse;
       
  1323 	TBool cursorShown = EFalse;
       
  1324 	TTime lastDeltaTime;
       
  1325 	TTime now;
       
  1326 	TInt64 deltaTime = 0;
       
  1327 	lastDeltaTime.UniversalTime();
       
  1328 	now.UniversalTime();
       
  1329 
       
  1330 	TRect textCursorRect(TRect(aPos, TSize(aTextCursor.iWidth, aTextCursor.iHeight)));
       
  1331 
       
  1332 	for (TInt sampleNumber = 0; sampleNumber < kNumberSamples; sampleNumber++)
       
  1333 		{
       
  1334 		cursorShown = DoCheckRect(iWorkInProgress, iComparisonWindow, textCursorRect, CWsScreenDevice::EIncludeTextCursor);
       
  1335 
       
  1336 		if (cursorShown && !cursorShownLastTime)
       
  1337 			{
       
  1338 			cursorShownLastTime = ETrue;
       
  1339 			UpdateCountersOnCursorTransition(
       
  1340 					cursorShownLastTime, now, deltaTime, lastDeltaTime, warmUpIterations, kFlashChangeTime,
       
  1341 					kToleranceMargin, sampleNumber, toleranceViolations);
       
  1342 			}
       
  1343 		else if (!cursorShown && cursorShownLastTime)
       
  1344 			{
       
  1345 			cursorShownLastTime = EFalse;
       
  1346 			UpdateCountersOnCursorTransition(
       
  1347 					cursorShownLastTime, now, deltaTime, lastDeltaTime, warmUpIterations, kFlashChangeTime,
       
  1348 					kToleranceMargin, sampleNumber, toleranceViolations);
       
  1349 			}
       
  1350 
       
  1351 		if (toleranceViolations > kMaximumToleranceViolations)
       
  1352 			break;
       
  1353 
       
  1354 		User::After(kToleranceMargin);
       
  1355 		}
       
  1356 	// Check was some flashing
       
  1357 	TEST_SOFTFAIL_WINSCW(warmUpIterations == 0);
       
  1358 	// Check cursor flashed on and off, regularly and on-time
       
  1359 	TEST_SOFTFAIL_WINSCW(toleranceViolations <= kMaximumToleranceViolations);
       
  1360 	}
       
  1361 #endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
       
  1362 
       
  1363 void CTCursorTest::MakeCursors(TTextCursor& aTextCursor, TTextCursor& aCustomCursor)
       
  1364 	{
       
  1365 	aCustomCursor.iType = KTextCursorInitialIdValue + iTest->iScreenNumber*KNumberOfCustoTextCursors; // custom text cursor
       
  1366 	aCustomCursor.iAscent=0;
       
  1367 	aCustomCursor.iHeight=kCursorHeight;
       
  1368 	aCustomCursor.iWidth=kCursorWidth;
       
  1369 	aCustomCursor.iFlags=TTextCursor::EFlagNoFlash; 
       
  1370 	aCustomCursor.iColor=TRgb::Color256(217);	
       
  1371 		
       
  1372 	// Create a standard cursor for the tests
       
  1373 	aTextCursor.iType = TTextCursor::ETypeRectangle; // Normal rectangular text cursor
       
  1374 	aTextCursor.iHeight=kCursorHeight;
       
  1375 	aTextCursor.iAscent=0;
       
  1376 	aTextCursor.iWidth=kCursorWidth;
       
  1377 	aTextCursor.iFlags=TTextCursor::EFlagNoFlash;
       
  1378 	}
       
  1379 
       
  1380 void CTCursorTest::StartDoubleCursorTestL(TInt aTestNumber)
       
  1381 	{
       
  1382 	// general setup
       
  1383 	CBlankWindow* win1=new(ELeave) CBlankWindow(KRgbWhite);
       
  1384 	CleanupStack::PushL(win1);
       
  1385 
       
  1386 	win1->SetUpL(kWin1TopLeft,kWinSize,TheClient->iGroup,*TheClient->iGc,EColor64K);
       
  1387 	
       
  1388 	win1->Redraw();
       
  1389 	
       
  1390 	// Create the second window
       
  1391 	CBlankWindow* win2=new(ELeave) CBlankWindow(KRgbWhite);
       
  1392 	CleanupStack::PushL(win2);
       
  1393 
       
  1394 	win2->SetUpL(kWin2TopLeft,kWinSize,TheClient->iGroup,*TheClient->iGc,EColor64K);
       
  1395 	win2->Redraw();
       
  1396 
       
  1397 	// Create normal and custom cursor for the tests
       
  1398 	TTextCursor textCursor;
       
  1399 	TTextCursor customCursor;
       
  1400 	MakeCursors(textCursor, customCursor);
       
  1401 
       
  1402 	TheClient->Flush();
       
  1403 	CWindowGc* winGc = TheClient->iGc;	
       
  1404 
       
  1405 	switch(aTestNumber)
       
  1406 		{
       
  1407 		case 1:
       
  1408 		CheckNoDoubleCursorTest1L(win1, win2, textCursor, customCursor, winGc);
       
  1409 		break;
       
  1410 		
       
  1411 		case 2:
       
  1412 		CheckNoDoubleCursorTest2L(win1, win2, textCursor, customCursor, winGc);
       
  1413 		break;
       
  1414 		
       
  1415 		case 3:
       
  1416 		CheckNoDoubleCursorTest3L(win1, win2, textCursor, customCursor, winGc);
       
  1417 		break;
       
  1418 		
       
  1419 		default:
       
  1420 		TEST(EFalse);
       
  1421 		break;
       
  1422 		}
       
  1423 	CleanupStack::PopAndDestroy(2); 	
       
  1424 	}
       
  1425 
       
  1426 // DEF098704
       
  1427 void CTCursorTest::CheckNoDoubleCursorTest1L(CBlankWindow* aWin1, CBlankWindow* aWin2, TTextCursor& /*aTextCursor*/, TTextCursor& aCustomCursor, CWindowGc* aWinGc)
       
  1428 	{
       
  1429 	// Test that changing the focus of a custom text cursor does not leave that cursor drawn where it was (INC093898)
       
  1430 
       
  1431 	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),TPoint(),aCustomCursor);
       
  1432 		
       
  1433 	// Bit blit the TEST_BITMAP_NAME image to the second window to use as a comparison
       
  1434 	// this is the same image that the custom cursor is using
       
  1435 	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
       
  1436 	CleanupStack::PushL(bitmap);
       
  1437 	TEST(KErrNone == bitmap->Load(TEST_BITMAP_NAME,0,ETrue)); 
       
  1438 
       
  1439 	aWinGc->Activate(*aWin2->Win());
       
  1440 	TRect updateArea(TPoint(0,0), bitmap->SizeInPixels());
       
  1441 	aWin2->Win()->Invalidate(updateArea);
       
  1442 	aWin2->Win()->BeginRedraw(updateArea);
       
  1443 	aWinGc->BitBlt(TPoint(0,0),bitmap); 
       
  1444 	aWinGc->Deactivate();
       
  1445 	aWin2->Win()->EndRedraw();
       
  1446 	TheClient->Flush();
       
  1447 	doCheckNoDoubleCursor(aWin1,aWin2,kWin1TopLeft,kWin2TopLeft,aCustomCursor,bitmap->SizeInPixels(),CWsScreenDevice::EIncludeSprite);
       
  1448 	CleanupStack::PopAndDestroy(1); // bitmap
       
  1449 	}
       
  1450 
       
  1451 // DEF098704
       
  1452 void CTCursorTest::CheckNoDoubleCursorTest2L(CBlankWindow* aWin1, CBlankWindow* aWin2, TTextCursor& /*aTextCursor*/, TTextCursor& aCustomCursor, CWindowGc* aWinGc)
       
  1453 	{
       
  1454 	//TEST 2: Checks that no artifacts are left behind when a text cursor is moved from under a transparent sprite
       
  1455 	
       
  1456 	// Construct the window win1 with a transparent sprite
       
  1457 	
       
  1458 	// Clear the top and bottom windows
       
  1459 	ResetWindows(aWinGc,aWin1,aWin2);	
       
  1460 	
       
  1461 	// Create a bitmap and a corresponding bitmap mask
       
  1462 	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
       
  1463 	CleanupStack::PushL(bitmap);
       
  1464 	TEST(KErrNone == bitmap->Load(TEST_BITMAP_NAME,0,ETrue)); 
       
  1465 	CBitmap* spriteBitmap=CBitmap::NewL(kWinSize,EColor256);
       
  1466 	CleanupStack::PushL(spriteBitmap);
       
  1467 	spriteBitmap->Gc().SetBrushColor(KRgbBlack);
       
  1468 	spriteBitmap->Gc().SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1469 	spriteBitmap->Gc().SetPenStyle(CGraphicsContext::ESolidPen); 
       
  1470 	spriteBitmap->Gc().DrawRect(TRect(kWinSize));
       
  1471 	CBitmap* mask=CBitmap::NewL(kWinSize,EColor256);
       
  1472 	CleanupStack::PushL(mask);
       
  1473 	mask->Gc().SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1474 	mask->Gc().SetBrushColor(KRgbBlack);
       
  1475 	mask->Gc().DrawRect(TRect(kWinSize));	
       
  1476 	
       
  1477 	// Create a sprite
       
  1478 	RWsSprite sprite = RWsSprite(TheClient->iWs);
       
  1479 	CleanupClosePushL(sprite);
       
  1480 	TEST(KErrNone == sprite.Construct(*aWin1->BaseWin(),TPoint(),0));
       
  1481 	
       
  1482 	// Add the bitmap to the sprite
       
  1483 	TSpriteMember member;
       
  1484 	member.iInvertMask=EFalse;
       
  1485 	member.iDrawMode=CGraphicsContext::EDrawModePEN;
       
  1486 	member.iOffset=TPoint();
       
  1487 	member.iInterval=TTimeIntervalMicroSeconds32(0);
       
  1488 	member.iBitmap = &spriteBitmap->Bitmap();
       
  1489 	member.iMaskBitmap = &mask->Bitmap(); 
       
  1490 	TEST(KErrNone == sprite.AppendMember(member));
       
  1491 	
       
  1492 	// Activate the sprite in win1
       
  1493 	TEST(KErrNone == sprite.Activate());
       
  1494 	
       
  1495 	// Put a cursor in win1
       
  1496 	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),TPoint(),aCustomCursor);
       
  1497 	
       
  1498 	// Bit blit the matching bitmap to the bottom window
       
  1499 	TRect bitmapArea(TPoint(0,0), bitmap->SizeInPixels());
       
  1500 	aWin2->Win()->Invalidate(bitmapArea);
       
  1501 	aWin2->Win()->BeginRedraw(bitmapArea);
       
  1502 	aWinGc->Activate(*aWin2->Win());
       
  1503 	aWinGc->BitBlt(TPoint(),bitmap); 
       
  1504 	aWinGc->Deactivate();
       
  1505 	aWin2->Win()->EndRedraw();
       
  1506 		
       
  1507 	TheClient->Flush();
       
  1508 	doCheckNoDoubleCursor(aWin1,aWin2,kWin1TopLeft,kWin2TopLeft,aCustomCursor,bitmap->SizeInPixels(),CWsScreenDevice::EIncludeSprite);
       
  1509 	CleanupStack::PopAndDestroy(4); // sprite, mask, spriteBitmap, bitmap
       
  1510 	}
       
  1511 
       
  1512 // DEF098704		
       
  1513 void CTCursorTest::CheckNoDoubleCursorTest3L(CBlankWindow* aWin1, CBlankWindow* aWin2, TTextCursor& aTextCursor,TTextCursor& aCustomCursor, CWindowGc* aWinGc)
       
  1514 	{
       
  1515 	//
       
  1516 	// TEST 3: Test a flashing text cursor does not leave artifacts when a redraw + change position happens during
       
  1517 	// the time the cursor flashing 'off'
       
  1518 	// 
       
  1519 	// This test moves a flashing cursor a number of times over a two second period to a seconds position.
       
  1520 	// it does it a number of times so some of the redraws will occur during the 'flash off' period
       
  1521 	// We then compare the 'after' position to what we expect
       
  1522 	// 
       
  1523 	// There are four possible outcomes when we look at the bitmap after the redraw + move
       
  1524 	// Position 1 is the original position, position 2 is the new position after the redraw
       
  1525 	// 
       
  1526 	// cursor artifact @ pos1 and flashed on cursor @ pos2
       
  1527 	// cursor artifact at pos1 and flashed off cursor @ pos2
       
  1528 	// no artifact at pos1 and flashed off cursor @ pos2
       
  1529 	// no artifact at pos1 and flashed on cursor @ pos2
       
  1530 	// 
       
  1531 	// any artifacts left over will cause the complete test to fail.
       
  1532 	//
       
  1533 	
       
  1534 	//
       
  1535 	// PART A: 
       
  1536 	aTextCursor.iFlags=0; 	// flashing
       
  1537 
       
  1538 	ResetWindows(aWinGc,aWin1,aWin2);	
       
  1539 	TestForArtifacts(aWin1, aTextCursor);
       
  1540 	
       
  1541 	//
       
  1542 	// PART B - For a non-custom text cursor
       
  1543 	aCustomCursor.iFlags=0; // flashing
       
  1544 
       
  1545 	ResetWindows(aWinGc,aWin1,aWin2);	
       
  1546 	TestForArtifacts(aWin1, aCustomCursor);	
       
  1547 	}
       
  1548 	
       
  1549 // moves the cursor between two positions while flashing and tests no artifacts are left at the position it moved from
       
  1550 // The moves take place in a loop so it is tested happening when the cursor is flashed on and also off
       
  1551 void CTCursorTest::TestForArtifacts(CBlankWindow* aWin1, TTextCursor& aCursor)
       
  1552 	{
       
  1553 	const TInt KIterations = 30;
       
  1554 	const TPoint kStartPos(0,0);
       
  1555 	const TPoint kMoveToPos(200,0);
       
  1556 	TRect r1(kWin1TopLeft,kCursorSize);
       
  1557 	TRect r2(kWin2TopLeft,kCursorSize);
       
  1558 	const TPoint kWin1TopLeft; 
       
  1559 	const TPoint kWin2TopLeft; 
       
  1560 	const TSize aCursorSize;
       
  1561 
       
  1562 	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),kStartPos,aCursor);
       
  1563 	TheClient->Flush();
       
  1564 
       
  1565 	TInt initialRepeatRate = 1000000; 
       
  1566 	const TInt KIncrement = 30000;
       
  1567 	TInt i=0;
       
  1568 
       
  1569 	for(i=0; i<KIterations; i++)		
       
  1570 		{
       
  1571 		// move the cursor to its new position
       
  1572 		TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),kMoveToPos,aCursor);
       
  1573 		TheClient->Flush();
       
  1574 
       
  1575 		User::After(initialRepeatRate);
       
  1576 		
       
  1577 		// check no artifact was left in position 1 by comparing against (blank) win2
       
  1578 		if(!TheClient->iScreen->RectCompare( r1,r2, CWsScreenDevice::EIncludeTextCursor))
       
  1579 			{
       
  1580 			break; // detected an artifact remaining, test failed
       
  1581 			}
       
  1582 
       
  1583 		// move the cursor back to its start position, this resets the flash timer which is why we increment initialRepeatRate 
       
  1584 		TheClient->iGroup->GroupWin()->SetTextCursor(*aWin1->BaseWin(),kStartPos,aCursor);
       
  1585 		TheClient->Flush();
       
  1586 		initialRepeatRate += KIncrement;
       
  1587 		}
       
  1588 		
       
  1589 		// if all went well i should equal KIterations, if it doesnt its because we detected 
       
  1590 		// an artifact and quit the test early
       
  1591 	TEST_SOFTFAIL_WINSCW(i==KIterations);
       
  1592 	}
       
  1593 	
       
  1594 
       
  1595 // Tests the two windows match, moves the cursor off win 1 then tests they no longer match 		
       
  1596 void CTCursorTest::doCheckNoDoubleCursor(CBlankWindow* aWin1,
       
  1597 											CBlankWindow* aWin2,
       
  1598 											const TPoint& aWin1Tl,
       
  1599 											const TPoint& aWin2Tl,
       
  1600 											const TTextCursor& aCursor,
       
  1601 											const TSize& aCursorSize,
       
  1602 											CWsScreenDevice::TSpriteInCompare aFlags)
       
  1603 	{
       
  1604 	TRect r1(aWin1Tl,aCursorSize);
       
  1605 	TRect r2(aWin2Tl,aCursorSize);
       
  1606 	
       
  1607 	TInt compareTries = 0;
       
  1608 	const TInt compareLimit = 5;
       
  1609 	
       
  1610 	TBool correctComparison = EFalse;
       
  1611 	while (!correctComparison && compareTries < compareLimit)
       
  1612 		{
       
  1613 		compareTries++;
       
  1614 		User::After(500000);
       
  1615 		correctComparison = TheClient->iScreen->RectCompare(r1,r2, aFlags);
       
  1616 		}
       
  1617 
       
  1618 	INFO_PRINTF3(_L("Result Before %d (attempts %d)"), correctComparison, compareTries);
       
  1619 	TEST_SOFTFAIL_WINSCW(correctComparison);
       
  1620 
       
  1621 	
       
  1622 	// Change the focus off win1, by drawing the text cursor on the second window
       
  1623 	TheClient->iGroup->GroupWin()->SetTextCursor(*aWin2->BaseWin(),aWin2Tl,aCursor);
       
  1624 	TheClient->Flush();
       
  1625 
       
  1626 	// Cause a redraw
       
  1627 	aWin1->CTWin::DrawNow();
       
  1628 	TheClient->WaitForRedrawsToFinish();
       
  1629 
       
  1630 	// make sure any cursor has actually moved	
       
  1631 	User::After(1000000); // 1 sec
       
  1632 	
       
  1633 	TBool resultAfter;
       
  1634 	resultAfter = !TheClient->iScreen->RectCompare(r1,r2, aFlags);
       
  1635 	INFO_PRINTF2(_L("Result After %d"), resultAfter);
       
  1636 	TEST_SOFTFAIL_WINSCW(resultAfter);
       
  1637 	}	
       
  1638 
       
  1639 // resets the windows to their initial state
       
  1640 void CTCursorTest::ResetWindows(CWindowGc* aWinGc,CBlankWindow* aWin1,CBlankWindow* aWin2)
       
  1641 	{
       
  1642 	TheClient->iGroup->GroupWin()->CancelTextCursor();
       
  1643 	aWinGc->Activate(*aWin1->Win());
       
  1644 	aWinGc->Reset();
       
  1645 	aWinGc->Clear();
       
  1646 	aWinGc->Deactivate();
       
  1647 
       
  1648 	aWin1->Invalidate();
       
  1649 	aWin1->Redraw();
       
  1650 	aWin2->Invalidate();
       
  1651 	aWin2->Redraw();
       
  1652 	TheClient->Flush();
       
  1653 	}
       
  1654 	
       
  1655 void CTCursorTest::RunTestCaseL(TInt /*aCurTestCase*/)
       
  1656 	{
       
  1657 	TBool deleteMove=EFalse;
       
  1658 	((CTCursorTestStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
       
  1659 
       
  1660 	switch(++iTest->iState)
       
  1661 		{
       
  1662 /**
       
  1663 @SYMTestCaseID		GRAPHICS-WSERV-0241
       
  1664 
       
  1665 @SYMDEF				DEF081259
       
  1666 
       
  1667 @SYMTestCaseDesc    Test the text cursor functions properly as a window is moved
       
  1668 
       
  1669 @SYMTestPriority    High
       
  1670 
       
  1671 @SYMTestStatus      Implemented
       
  1672 
       
  1673 @SYMTestActions     Move a window about the screen and meanwhile check the text
       
  1674 					cursor functions correctly
       
  1675 
       
  1676 @SYMTestExpectedResults The text cursor functions correctly as the window is moved
       
  1677 */
       
  1678 	case 1:
       
  1679 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0241"));
       
  1680 		while (!deleteMove)
       
  1681 			{
       
  1682 			if (iCursorType==TTextCursor::ETypeFirst)
       
  1683 				iTest->LogSubTest(_L("Cursor 1"));
       
  1684 			if (MoveWindow())
       
  1685 				{
       
  1686 				if (IncrementCursorType())
       
  1687 					{
       
  1688 					ResetMoveWindowsL();
       
  1689 					}
       
  1690 				else
       
  1691 					{
       
  1692 					DeleteMoveWindows();
       
  1693 					deleteMove =true;
       
  1694 					}
       
  1695 				}
       
  1696 			}
       
  1697 		break;
       
  1698 
       
  1699 /**
       
  1700 @SYMTestCaseID		GRAPHICS-WSERV-0242
       
  1701 
       
  1702 @SYMDEF				DEF081259
       
  1703 
       
  1704 @SYMTestCaseDesc    Test the text cursor functions properly as the window is scrolled
       
  1705 
       
  1706 @SYMTestPriority    High
       
  1707 
       
  1708 @SYMTestStatus      Implemented
       
  1709 
       
  1710 @SYMTestActions     Scroll the window and meanwhile check the text cursor functions correctly
       
  1711 
       
  1712 @SYMTestExpectedResults The text cursor functions correctly as the window is scrolled
       
  1713 */
       
  1714 		case 2:
       
  1715 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0242"));
       
  1716 			iTest->LogSubTest(_L("Cursor 2"));
       
  1717 			iCursorType=TTextCursor::ETypeRectangle;
       
  1718 			ScrollTest();
       
  1719 			iCursorType=TTextCursor::ETypeFirst;
       
  1720 			break;
       
  1721 /**
       
  1722 @SYMTestCaseID		GRAPHICS-WSERV-0244
       
  1723 
       
  1724 @SYMDEF				DEF081259
       
  1725 
       
  1726 @SYMTestCaseDesc    Test the text cursor functions properly as a blank window is moved
       
  1727 
       
  1728 @SYMTestPriority    High
       
  1729 
       
  1730 @SYMTestStatus      Implemented
       
  1731 
       
  1732 @SYMTestActions     Move a blank window about the screen and meanwhile check the text
       
  1733 					cursor functions correctly
       
  1734 
       
  1735 @SYMTestExpectedResults The text cursor functions correctly as the blank window is moved
       
  1736 */
       
  1737 		case 3:
       
  1738 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0244"));
       
  1739 			iTest->LogSubTest(_L("Move window1"));
       
  1740 			MoveWindowTest1L();
       
  1741 			break;
       
  1742 /**
       
  1743 @SYMTestCaseID		GRAPHICS-WSERV-0245
       
  1744 
       
  1745 @SYMDEF				DEF081259
       
  1746 
       
  1747 @SYMTestCaseDesc    Test that a non flashing text cursor functions properly as a 
       
  1748 					blank window is moved
       
  1749 
       
  1750 @SYMTestPriority    High
       
  1751 
       
  1752 @SYMTestStatus      Implemented
       
  1753 
       
  1754 @SYMTestActions     Move a blank window about the screen and meanwhile check that a non
       
  1755 					flashing text cursor functions correctly
       
  1756 
       
  1757 @SYMTestExpectedResults The text cursor functions correctly as the blank window is moved
       
  1758 */
       
  1759 		case 4:
       
  1760 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0245"));
       
  1761 			while (IncrementCursorType())
       
  1762 				{
       
  1763 				iTest->LogSubTest(_L("Move window2"));
       
  1764 				MoveWindowTest2L();
       
  1765 				}
       
  1766 			break;		
       
  1767 /**
       
  1768 @SYMTestCaseID		GRAPHICS-WSERV-0247
       
  1769 
       
  1770 @SYMDEF				DEF081259
       
  1771 
       
  1772 @SYMTestCaseDesc    Tests a Custom Text Cursor Sprite visibility after wserv hearbeat suppression
       
  1773 					REQUIREMENT:	INC040489.
       
  1774 
       
  1775 @SYMTestPriority    High
       
  1776 
       
  1777 @SYMTestStatus      Implemented
       
  1778 
       
  1779 @SYMTestActions     Create a window group with an associated window for it, then activate it.
       
  1780 					Create another window group with an associated window along with a custom cursor, 
       
  1781 					then active it. Make a call to suppress the wserv hearbeat, which will stop 
       
  1782 					the custom cursor from flashing with flash ON state. Bring the first window 
       
  1783 					group to the foreground and cancel the custom test cursor in the second window group.
       
  1784 					After that, put the first window group to the background and set the custom test 
       
  1785 					cursor in the second window group. Simulate a raw key event to start 
       
  1786 					the wserv heartbeat, which will make the custom cursor flashing.
       
  1787 
       
  1788 @SYMTestExpectedResults The Custom text cursor in the second window group should be visible and flashing, 
       
  1789 						when it comes to the foreground after the first window group sent to the background.
       
  1790 */
       
  1791 		case 5:
       
  1792 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0247"));
       
  1793 			iTest->LogSubTest(_L("Custom Text Cursor Sprite visibility"));
       
  1794 			INC040489L();
       
  1795 			break;
       
  1796 /**
       
  1797 @SYMTestCaseID		GRAPHICS-WSERV-2095-0015
       
  1798 
       
  1799 @SYMTestCaseDesc    Text Cursor allows Update before Rendering the owning window
       
  1800 
       
  1801 @SYMTestPriority    Normal
       
  1802 
       
  1803 @SYMTestStatus      Implemented
       
  1804 
       
  1805 @SYMTestActions     Create a window group and two windows, one with a Text Cursor.
       
  1806 					Stimulate a state change in the Text Cursor by receiving
       
  1807 					window focus, but before the Window has ever been Rendered.
       
  1808 					This shakes out logic in RWsTextCursor which depends on
       
  1809 					side effects arising from having executed CWsWindow::Render()
       
  1810 					
       
  1811 @SYMTestExpectedResults 
       
  1812 					There should be no panic or assertion.
       
  1813 */
       
  1814 		case 6:
       
  1815 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0015"));
       
  1816 			iTest->LogSubTest(_L("Update before Render"));
       
  1817 			CursorUpdatedBeforeWindowRenderedL();
       
  1818 			break;
       
  1819 
       
  1820 /**
       
  1821 @SYMTestCaseID		GRAPHICS-WSERV-0248
       
  1822 
       
  1823 @SYMDEF  			DEF081259
       
  1824 
       
  1825 @SYMTestCaseDesc    Tests a bad use of text cursor functionality from a client.
       
  1826 					REQ 1079, CR RDEF-5F7Q24 (10/04/2003).
       
  1827 
       
  1828 @SYMTestPriority    High
       
  1829 
       
  1830 @SYMTestStatus      Implemented
       
  1831 
       
  1832 @SYMTestActions     This test case checks whether the window server is able to detect a bad
       
  1833 					use of the text cursor functionality (including the custom text cursor)
       
  1834 					by a client.
       
  1835 					This test case launches several threads and each of them will try
       
  1836 					to use the text cursor functionality in a non-proper way.
       
  1837 
       
  1838 @SYMTestExpectedResults Each new thread has panic code associated to it. This is the expected panic when
       
  1839 						the thread dies.
       
  1840 						The thread once launched is expected to panic and the returning panic code should
       
  1841 						match the expected one.
       
  1842 */
       
  1843 		case 7:
       
  1844 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0248"));
       
  1845 			iTest->LogSubTest(_L("Panic"));
       
  1846 			TestPanicsL();
       
  1847 			break;
       
  1848 /**
       
  1849 @SYMTestCaseID		GRAPHICS-WSERV-0400
       
  1850 
       
  1851 @SYMDEF				PDEF099013
       
  1852 
       
  1853 @SYMTestCaseDesc    Cursor moves slowly in text editors. 
       
  1854 
       
  1855 @SYMTestPriority    High
       
  1856 
       
  1857 @SYMTestStatus      Implemented
       
  1858 
       
  1859 @SYMTestActions     This test case is a VISUAL TEST only on whether a scrolling text cursor is drawn to the
       
  1860 					screen correctly. 2 types of cursor are checked both clipped and non clipped cursors.
       
  1861 					In each case the test simulates a text cursor moving across the screen as if a user were
       
  1862 					holding down a key to scroll the cursor through a section of text.
       
  1863 
       
  1864 @SYMTestExpectedResults The text cursor in both cases should scroll smoothly to the centre of the screen.
       
  1865 						In versions prior to this fix the cursor was not correctly drawn and appeared to move 	
       
  1866 						slowly.
       
  1867 */
       
  1868 		case 8:
       
  1869 			((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0400"));
       
  1870 			iTest->LogSubTest(_L("Text Cursor Update Tests"));
       
  1871 			INC097774();
       
  1872 			break;	
       
  1873 		
       
  1874 /**
       
  1875 @SYMTestCaseID		GRAPHICS-WSERV-0401
       
  1876 
       
  1877 @SYMDEF  			DEF098704
       
  1878 
       
  1879 @SYMTestCaseDesc    Test code for implemented fix to remove double cursors 
       
  1880 					
       
  1881 @SYMTestPriority    Normal
       
  1882 
       
  1883 @SYMTestStatus      Implemented
       
  1884 
       
  1885 @SYMTestActions     This test case tests for artifacts left over when normal/custon flashing/non-flashing cursors are drawn.
       
  1886 					Test that changing the focus of a custom text cursor does not leave that cursor drawn where it was (INC093898)
       
  1887 
       
  1888 @SYMTestExpectedResults 
       
  1889 */			
       
  1890 	case 9:
       
  1891 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0401"));
       
  1892 		iTest->LogSubTest(_L("Double cursors test 1"));
       
  1893 		StartDoubleCursorTestL(1);
       
  1894 		break;
       
  1895 
       
  1896 	/**
       
  1897 	@SYMTestCaseID		GRAPHICS-WSERV-0402
       
  1898 
       
  1899 	@SYMDEF				DEF098704
       
  1900 
       
  1901 	@SYMTestCaseDesc    Test code for implemented fix to remove double cursors 
       
  1902 
       
  1903 	@SYMTestPriority    Normal
       
  1904 
       
  1905 	@SYMTestStatus      Implemented
       
  1906 
       
  1907 	@SYMTestActions     Checks that no artifacts are left behind when a text cursor is moved from under a transparent sprite
       
  1908 
       
  1909 	@SYMTestExpectedResults 
       
  1910 	*/
       
  1911 	case 10:
       
  1912 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0402"));
       
  1913 		iTest->LogSubTest(_L("Double cursors test 2"));
       
  1914 		StartDoubleCursorTestL(2);
       
  1915 		break;
       
  1916 
       
  1917 	/**
       
  1918 	@SYMTestCaseID		GRAPHICS-WSERV-0403
       
  1919 
       
  1920 	@SYMDEF				DEF098704
       
  1921 
       
  1922 	@SYMTestCaseDesc    Test code for implemented fix to remove double cursors 
       
  1923 						
       
  1924 	@SYMTestPriority    Normal
       
  1925 
       
  1926 	@SYMTestStatus      Implemented
       
  1927 
       
  1928 	@SYMTestActions     This test moves a flashing cursor a number of times over a two second period to a seconds position.
       
  1929 						it does it a number of times so some of the redraws will occur during the 'flash off' period
       
  1930 						We then compare the 'after' position to what we expect
       
  1931 
       
  1932 	@SYMTestExpectedResults 
       
  1933 	*/
       
  1934 	case 11:
       
  1935 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0403"));
       
  1936 		iTest->LogSubTest(_L("Double cursors test 3"));
       
  1937 		StartDoubleCursorTestL(3);
       
  1938 		break;
       
  1939 
       
  1940 	/**
       
  1941 	@SYMTestCaseID		GRAPHICS-WSERV-0483
       
  1942 
       
  1943 	@SYMDEF				INC117232
       
  1944 
       
  1945 	@SYMTestCaseDesc    Test code: Refreshing cursors becoming offscreen due to screen size change should not panic 
       
  1946 
       
  1947 	@SYMTestPriority    Normal
       
  1948 
       
  1949 	@SYMTestStatus      Implemented
       
  1950 
       
  1951 	@SYMTestActions     Create a cursor on bottom right of screen, change to a screen mode that excludes that coordinate
       
  1952 
       
  1953 	@SYMTestExpectedResults 
       
  1954 						The server should not panic.
       
  1955 	*/
       
  1956 	case 12:
       
  1957 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0483"));
       
  1958 		iTest->LogSubTest(_L("Screen resize invalidate cursor off-screen"));
       
  1959 		INC117232();
       
  1960 		break;
       
  1961 
       
  1962 	/**
       
  1963 	@SYMTestCaseID		GRAPHICS-WSERV-2095-0016
       
  1964 
       
  1965 	@SYMTestCaseDesc    Text Cursor flag TTextCursor::EFlagNoFlash honored 
       
  1966 
       
  1967 	@SYMTestPriority    Normal
       
  1968 
       
  1969 	@SYMTestStatus      Implemented
       
  1970 
       
  1971 	@SYMTestActions     Create a text cursor with the TTextCursor::EFlagNoFlash setting.  Observe the screen over
       
  1972 						a short period of time to verify that it remains continuously in the Flash ON state.
       
  1973 
       
  1974 	@SYMTestExpectedResults 
       
  1975 						The text cursor should be always shown.
       
  1976 	*/
       
  1977 	case 13:
       
  1978 	#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
       
  1979 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0016"));
       
  1980 		iTest->LogSubTest(_L("Text cursor EFlagNoFlash test"));
       
  1981 		TextCursorNoFlashTestL();
       
  1982 	#endif
       
  1983 		break;
       
  1984 
       
  1985 	/**
       
  1986 	@SYMTestCaseID		GRAPHICS-WSERV-2095-0009
       
  1987 
       
  1988 	@SYMTestCaseDesc    Text Cursor flashes when flag value is 0
       
  1989 
       
  1990 	@SYMTestPriority    Normal
       
  1991 
       
  1992 	@SYMTestStatus      Implemented
       
  1993 
       
  1994 	@SYMTestActions     Create a text cursor with the 0 flag setting.  Observe the screen over
       
  1995 						a short period of time to verify that the cursor flashes ON and OFF at
       
  1996 						the correct period of one second.
       
  1997 
       
  1998 	@SYMTestExpectedResults 
       
  1999 						The text cursor should flash.
       
  2000 	*/
       
  2001 	case 14:
       
  2002 	#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
       
  2003 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0009"));
       
  2004 		iTest->LogSubTest(_L("Text cursor will Flash test"));
       
  2005 		TextCursorFlashTestL();
       
  2006 	#endif
       
  2007 		break;
       
  2008 
       
  2009 	/**
       
  2010 	@SYMTestCaseID		GRAPHICS-WSERV-2095-0017
       
  2011 
       
  2012 	@SYMTestCaseDesc    Text Cursor handles different valid Cursor Setttings
       
  2013 
       
  2014 	@SYMTestPriority    Normal
       
  2015 
       
  2016 	@SYMTestStatus      Implemented
       
  2017 
       
  2018 	@SYMTestActions     Create a text cursor and then issue a SetTextCursor.  Then repeatedly
       
  2019 						call SetTextCursor, varying the arguments relating to the Text Cursor
       
  2020 						as well as keeping the arguments the same on one occassion.
       
  2021 
       
  2022 	@SYMTestExpectedResults 
       
  2023 						The system should not panic as the arguments supplied are never invalid.
       
  2024 	*/
       
  2025 	case 15:
       
  2026 		((CTCursorTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2095-0017"));
       
  2027 		iTest->LogSubTest(_L("SetTextCursor test"));
       
  2028 		TextCursorSetLCoverageTests();
       
  2029 		break;
       
  2030 
       
  2031 		default:
       
  2032 			((CTCursorTestStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
       
  2033 			((CTCursorTestStep*)iStep)->CloseTMSGraphicsStep();
       
  2034 			TestComplete();
       
  2035 			break;
       
  2036 		}
       
  2037 	((CTCursorTestStep*)iStep)->RecordTestResultL();
       
  2038 	}
       
  2039 
       
  2040 __WS_CONSTRUCT_STEP__(CursorTest)