windowing/windowserver/tdynamicres/src/t_wsdynamicreswinbase.cpp
changeset 0 5d03bc08d59c
child 45 36b2e23a8629
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2008-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 //
       
    15 
       
    16 /**
       
    17  @file
       
    18 */
       
    19 
       
    20 
       
    21 #include <e32std.h>
       
    22 #include <e32math.h>
       
    23 #include <w32std.h>
       
    24 #include <w32debug.h>
       
    25 #include "teflogextensions.h"
       
    26 #include "t_wsdynamicreswinbase.h"
       
    27 #include "globalsettings.h"
       
    28 #include <bitdraw.h>
       
    29 #include <bitdrawinterfaceid.h>
       
    30 #include <u32hal.h>
       
    31 #include <dispchannel.h>
       
    32 #include <graphics/displaycontrol.h>
       
    33 
       
    34 #if (!defined(K_DISPLAY_CH_MAJOR_VERSION_NUMBER) && !defined(K_DISPLAY_CH_MINOR_VERSION_NUMBER))
       
    35 #define MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER
       
    36 #endif
       
    37 
       
    38 _LIT(KMonospaceTestFontTypefaceName,"Arial");
       
    39 const TInt KMaxFontSize = 150;
       
    40 TBool	CWsDynamicResWinBase::iTransparencyEnabled=EFalse;
       
    41 
       
    42 CWsDynamicResWinBase::CWsDynamicResWinBase():
       
    43 	iDoTearDown(EFalse),
       
    44 	iSession(TGlobalSettings::Instance().iScreen)
       
    45 {
       
    46 }
       
    47 
       
    48 void CWsDynamicResWinBase::SetupL()
       
    49 	{
       
    50 	SetupL(EFalse);
       
    51 	}
       
    52 CActiveScheduler	CWsDynamicResWinBase::iScheduler;
       
    53 
       
    54 void CWsDynamicResWinBase::SetupL(TBool aUseOtherScreenForInfo)
       
    55 	{	
       
    56 	if (CActiveScheduler::Current()!=&iScheduler)
       
    57 		{
       
    58 		new (&iScheduler) CActiveScheduler;
       
    59 		CActiveScheduler::Install(&iScheduler);
       
    60 		}
       
    61 	iDoTearDown=ETrue;
       
    62 	iRed.SetInternal(0xFFFF0000);
       
    63 	iGreen.SetInternal(0xFF00FF00);
       
    64 	iBlue.SetInternal(0xFF0000FF);
       
    65 	iCyan.SetInternal(0xFF00FFFF);
       
    66 	iMagenta.SetInternal(0xFFFF00FF);
       
    67 	iYellow.SetInternal(0xFFFFFF00);
       
    68 	iWhite.SetInternal(0xFFFFFFFF);
       
    69 	iLastGceHoleColor.SetInternal(0);
       
    70 	TITLE_BACKGROUND=iCyan;
       
    71 	COMPARE_BACKGROUND=iBlue;
       
    72 
       
    73 	ASSERT_EQUALS_X(iSession.Connect(), KErrNone);
       
    74 
       
    75 		{//Stolen from TAuto CloseAllPanicWindows()
       
    76 		TInt idFocus = iSession.GetFocusWindowGroup();
       
    77 		TWsEvent event;
       
    78 		event.SetType(EEventKey); //EEventKeyDown
       
    79 		TKeyEvent *keyEvent = event.Key();
       
    80 		keyEvent->iCode = EKeyEscape;
       
    81 		keyEvent->iScanCode = EStdKeyEscape;
       
    82 		keyEvent->iModifiers = 0;
       
    83 		TInt theLimit = 50;
       
    84 		while(idFocus != NULL && (theLimit-- > 0))
       
    85 			{
       
    86 			iSession.SendEventToAllWindowGroups(event);
       
    87 			TInt idNewFocus = iSession.GetFocusWindowGroup();
       
    88 			if (idNewFocus!=idFocus)
       
    89 				{
       
    90 				INFO_PRINTF1(_L("A window was closed [probably a panic box from the previous test]."));
       
    91 				}
       
    92 			idFocus=idNewFocus;
       
    93 			}
       
    94 		}
       
    95 	TInt err = KErrNone;
       
    96 
       
    97 	TRAP(err, iScreenDevice = new (ELeave) CWsScreenDevice(iSession));
       
    98 	PRINT_ON_ERROR2_L(err, _L("Failed to create screen device: %d"), err);
       
    99 	ASSERT_EQUALS_X(iScreenDevice->Construct(TGlobalSettings::Instance().iScreen), KErrNone);
       
   100 	iDisplayMode = iScreenDevice->DisplayMode();	// Get default display mode
       
   101 
       
   102 	CheckAndConnectScreen();
       
   103 
       
   104 	TRAP(err, iGc = new (ELeave) CWindowGc(iScreenDevice));
       
   105 	PRINT_ON_ERROR2_L(err, _L("Failed to create graphics context: %d"), err);
       
   106 	ASSERT_EQUALS_X(iGc->Construct(), KErrNone);
       
   107 	
       
   108 	iGroup = RWindowGroup(iSession);
       
   109 	ASSERT_EQUALS_X(iGroup.Construct(++iWindowHandle,iScreenDevice), KErrNone);
       
   110 	iGroup.SetOrdinalPositionErr(0, KPasswordWindowGroupPriority - 1); // Added code ---- Fastpath
       
   111 	iSession.Flush();
       
   112 	
       
   113 	if (aUseOtherScreenForInfo)
       
   114 		{
       
   115 		if (iSession.NumberOfScreens()>1)
       
   116 			{	//Create server objects for info windows to appear on alternate screen
       
   117 			TInt alternateScreenNum=iSession.NumberOfScreens()-1;
       
   118 			if (TGlobalSettings::Instance().iScreen==alternateScreenNum)
       
   119 				{	//Alternate screen is last screen, or first screen if that is being tested. 
       
   120 				alternateScreenNum=0;
       
   121 				}
       
   122 			
       
   123 			TRAP(err, iInfoScreenDevice = new (ELeave) CWsScreenDevice(iSession));
       
   124 			PRINT_ON_ERROR2_L(err, _L("Failed to create second screen device: %d"), err);
       
   125 			ASSERT_EQUALS_X(iInfoScreenDevice->Construct(alternateScreenNum), KErrNone);
       
   126 	
       
   127 			TRAP(err, iInfoGc = new (ELeave) CWindowGc(iInfoScreenDevice));
       
   128 			PRINT_ON_ERROR2_L(err, _L("Failed to create second graphics context: %d"), err);
       
   129 			ASSERT_EQUALS_X(iInfoGc->Construct(), KErrNone);
       
   130 
       
   131 			iInfoGroupInstance = RWindowGroup(iSession);
       
   132 			ASSERT_EQUALS_X(iInfoGroupInstance.Construct(++iWindowHandle,iInfoScreenDevice), KErrNone);
       
   133 			iInfoGroup=&iInfoGroupInstance;
       
   134 			}
       
   135 		else
       
   136 			{	//If alternate screen is not available then no text or compare windows should be created!
       
   137 			iInfoScreenDevice=iScreenDevice;	//it is "convenient" for the device to still be good.
       
   138 			iInfoGc=NULL;
       
   139 			iInfoGroup=NULL;
       
   140 			}
       
   141 		}
       
   142 	else
       
   143 		{	//
       
   144 		iInfoScreenDevice=iScreenDevice;
       
   145 		iInfoGc=iGc;
       
   146 		iInfoGroup=&iGroup;
       
   147 		}
       
   148 	
       
   149 	if (iInfoGroup && iInfoGc)
       
   150 		{
       
   151 		// Add a plain background window to obscure anything else that
       
   152 		// happens to be behind the test. Setting this window's display mode is also
       
   153 		// used to set the screen device display mode, and hence the composition
       
   154 		// mode: alpha or chroma key.
       
   155 		iBackground = RBlankWindow(iSession);
       
   156 		ASSERT_EQUALS_X(iBackground.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
       
   157 	
       
   158 		iBackground.SetOrdinalPosition(100);	// Behind anything else in this group.
       
   159 		iBackground.SetColor(TRgb(iWhite));
       
   160 		//iBackground.SetExtent(TPoint(-1000,-1000),TSize(3000,3000));
       
   161 		iBackground.Activate();
       
   162 		iBackground.SetVisible(ETrue);
       
   163 		}
       
   164 	iSession.Flush();
       
   165 	
       
   166 	RWindow testTrans(iSession);
       
   167 	ASSERT_EQUALS_X(testTrans.Construct(iGroup, ++iWindowHandle), KErrNone);
       
   168 	iTransparencyEnabled=(testTrans.SetTransparencyFactor(iWhite)==KErrNone);
       
   169 	if (iTransparencyEnabled)
       
   170 		{
       
   171 		TTestName testName;
       
   172 		testName.Format(_L("Screen %i, depth %i: Found Trans Man"),
       
   173 				TGlobalSettings::Instance().iScreen
       
   174 			);
       
   175 		UpdateTitleWindowL(testName,KMaxInfoLines-1);
       
   176 		}
       
   177 	else
       
   178 		{
       
   179 		TTestName testName;
       
   180 		testName.Format(_L("Screen %i, depth %i: No Trans Man"),
       
   181 				TGlobalSettings::Instance().iScreen
       
   182 			);
       
   183 		UpdateTitleWindowL(testName,KMaxInfoLines-1);
       
   184 		}
       
   185 	testTrans.Close();
       
   186 	}
       
   187 
       
   188 
       
   189 void CWsDynamicResWinBase::CheckAndConnectScreen()
       
   190 	{
       
   191 	if (TGlobalSettings::Instance().iDisconnected) //set from script file to match wsini keyword SIMULATE_STARTUP_DISCONNECTED
       
   192 		{
       
   193 		//Verify that the display really is disconnected
       
   194 		ASSERT_TRUE_X(iScreenDevice != NULL);
       
   195 		MDisplayControl* interface = static_cast<MDisplayControl*>(iScreenDevice->GetInterface(MDisplayControl::ETypeId));
       
   196 		ASSERT_TRUE_X(interface != NULL);
       
   197 		RArray<MDisplayControl::TResolution> resolutions;
       
   198 		const TInt err = interface->GetResolutions(resolutions);
       
   199 		ASSERT_EQUALS_X(err, KErrDisconnected);
       
   200 		resolutions.Close();
       
   201 		}
       
   202 	
       
   203 #ifndef MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER
       
   204 	//make sure display is attached to screen (only if I/F is available at compile time...)
       
   205 	TInt displayState = ENormalResolution;
       
   206 	UserSvr::HalFunction(EHalGroupDisplay | (TGlobalSettings::Instance().iScreen<<16), EDisplayHalSetDisplayState, &displayState, NULL);
       
   207 	Pause(200);
       
   208 #endif	
       
   209 	
       
   210 	if (TGlobalSettings::Instance().iDisconnected)
       
   211 		{
       
   212 		//Verify that the display now is connected
       
   213 		MDisplayControl* interface = static_cast<MDisplayControl*>(iScreenDevice->GetInterface(MDisplayControl::ETypeId));
       
   214 		RArray<MDisplayControl::TResolution> resolutions;
       
   215 		const TInt err = interface->GetResolutions(resolutions);
       
   216 		ASSERT_EQUALS_X(err, KErrNone);
       
   217 		const_cast<TGlobalSettings&>(TGlobalSettings::Instance()).iDisconnected = EFalse;
       
   218 		resolutions.Close();
       
   219 		}
       
   220 	}
       
   221 
       
   222 /**
       
   223 Common tear down code for all tests.
       
   224 
       
   225 Windows, group and session created are closed. Screen device is destroyed.
       
   226 Surfaces, manager and update session are closed.
       
   227 */
       
   228 void CWsDynamicResWinBase::TearDownL()
       
   229 	{
       
   230 	iDoTearDown=EFalse;
       
   231 	if (iInfoGc!=iGc)
       
   232 		delete iInfoGc;
       
   233 	delete iGc;
       
   234 	if (iInfoScreenDevice!=iScreenDevice)
       
   235 		delete iInfoScreenDevice;
       
   236 	delete iScreenDevice;
       
   237 
       
   238 	iGroup.Close();
       
   239 	if (iInfoGroupInstance.WsHandle())
       
   240 		iInfoGroupInstance.Close();
       
   241 	iSession.Flush();
       
   242 	iSession.Close();
       
   243 	}
       
   244 /**
       
   245  * Note that this is not the ideal mechanism.
       
   246  * A derived class may thinks its TearDown is safe to do from delete, but in the class it is derived from it may not be safe
       
   247  **/
       
   248 void CWsDynamicResWinBase::TearDownFromDeleteL()	
       
   249 	{
       
   250 	CWsDynamicResWinBase::TearDownL();	//Explicitly call the non-derived implementation.
       
   251 	}
       
   252 
       
   253 CWsDynamicResWinBase::~CWsDynamicResWinBase()
       
   254 {
       
   255 	if (iDoTearDown)
       
   256 		TearDownFromDeleteL();	//This mechanism is not entirely clean to use.
       
   257 }
       
   258 /**
       
   259 Pause for the given number of milliseconds.
       
   260 
       
   261 @param aMilliseconds	Time to wait in milliseconds.
       
   262 */
       
   263 void CWsDynamicResWinBase::Pause(TInt aMilliseconds)
       
   264 	{
       
   265 	User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000));
       
   266 	}
       
   267 // This handles any non-member uses of the extended ASSERT_XXX macros
       
   268 void TefUnitFailLeaveL()
       
   269 	{
       
   270 	
       
   271 	User::Leave(KErrTEFUnitFail);
       
   272 	}
       
   273 /**
       
   274  * side-effect: log the state info just before I leave!
       
   275  * Note that this only logs intentional assertion failures.
       
   276  * Fails due to panics or throws won't log this info.
       
   277  **/
       
   278 void CWsDynamicResWinBase::TefUnitFailLeaveL()
       
   279 	{
       
   280 	for (TInt line=0;line<KMaxInfoLines;line++)
       
   281 		if (iTestInfo[line].Length())
       
   282 			Logger().LogExtra((TText8*)"Test state at fail - line",line, ESevrAll, iTestInfo[line]);
       
   283 	
       
   284 	User::Leave(KErrTEFUnitFail);
       
   285 	}
       
   286 
       
   287 /**	Creates the LHS info window, annd a middle window to display a representation of the expected result.
       
   288  *  Also sets up a rectangle representing the space on the right to be used for the test
       
   289  * 	@param	aTitle	The title to display on the info window
       
   290  *  @param	aDetail	Optional text to display on the first line under the title
       
   291 **/
       
   292 void CWsDynamicResWinBase::MakeTitleAndCompareWindowsL(TRefByValue<const TDesC16> aTitle,TRefByValue<const TDesC16> aDetail)
       
   293 	{	
       
   294 	iTestName=aTitle;
       
   295 	iTestInfo[0]=aDetail;
       
   296 	
       
   297 	TRect screenSize(iInfoScreenDevice->SizeInPixels());
       
   298 	TPoint oneThird(screenSize.iBr.iX/3,screenSize.iBr.iY/3);
       
   299 	TRect winSize(0,0,oneThird.iX,oneThird.iY);
       
   300 	
       
   301 	if (oneThird.iX>oneThird.iY)
       
   302 		{
       
   303 		oneThird.iY=0;
       
   304 		winSize.iBr.iY=screenSize.iBr.iY;
       
   305 		}
       
   306 	else
       
   307 		{
       
   308 		oneThird.iX=0;
       
   309 		winSize.iBr.iX=screenSize.iBr.iX;
       
   310 		}
       
   311 	winSize.Shrink(5,5);
       
   312 
       
   313 	if (iInfoGc)
       
   314 		{
       
   315 		iTitle=RWindow(iSession);
       
   316 		ASSERT_EQUALS_X(iTitle.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
       
   317 		iTitle.SetBackgroundColor(iCyan);
       
   318 		iTitle.SetExtent(winSize.iTl,winSize.Size());
       
   319 		iTitle.Activate();
       
   320 		
       
   321 		RepaintTitleWindowL();
       
   322 		iTitle.SetVisible(ETrue);
       
   323 	
       
   324 		winSize.Move(oneThird);
       
   325 		iCompare=RWindow(iSession);
       
   326 		ASSERT_EQUALS_X(iCompare.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
       
   327 		iCompare.SetBackgroundColor(COMPARE_BACKGROUND);
       
   328 		iCompare.SetExtent(winSize.iTl,winSize.Size());
       
   329 		iCompare.Activate();
       
   330 		iCompare.BeginRedraw();
       
   331 		ActivateWithWipe(iInfoGc,iCompare,COMPARE_BACKGROUND);
       
   332 	
       
   333 		TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize);
       
   334 		CFont *font=NULL;
       
   335 		ASSERT_EQUALS(iScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone);
       
   336 		iInfoGc->UseFont(font);
       
   337 		iInfoGc->DrawText(_L("Simulation"),winSize.Size(),winSize.Size().iHeight-5,iGc->ECenter);
       
   338 	
       
   339 		iInfoGc->Deactivate();
       
   340 		iCompare.EndRedraw();
       
   341 		iCompare.SetVisible(ETrue);
       
   342 		if (iScreenDevice!=iInfoScreenDevice)
       
   343 			{
       
   344 			winSize.Move(-oneThird);
       
   345 			}
       
   346 		else
       
   347 			{
       
   348 			winSize.Move(oneThird);
       
   349 			}
       
   350 		}
       
   351 	else
       
   352 		{
       
   353 		winSize=iScreenDevice->SizeInPixels();
       
   354 		}
       
   355 	
       
   356 	iTestPos=winSize;
       
   357 	iTestPointCentre=winSize.Center();
       
   358 	iCenteredFrontWinRect=winSize;
       
   359 	iCenteredFrontWinRect.Shrink(winSize.Size().iWidth/3,winSize.Size().iHeight/3);
       
   360 
       
   361 	}
       
   362 /**	Makes the compare window larger by covering the test window area as well.
       
   363  * 	Copes with vertically aligned screens, but will be naughty if called multiple times!!!
       
   364  *  @param aGoLarger	If set false, resets the size back.
       
   365  **/
       
   366 void CWsDynamicResWinBase::LargerCompareWindow(TBool aGoLarger)
       
   367 	{
       
   368 	TPoint currPos=iCompare.AbsPosition();
       
   369 	TSize currSize=iCompare.Size();
       
   370 	if (currPos.iX<currPos.iY)
       
   371 		{
       
   372 		if (aGoLarger)
       
   373 			currSize.iHeight<<=1;
       
   374 		else
       
   375 			currSize.iHeight>>=1;
       
   376 		}
       
   377 	else
       
   378 		{
       
   379 		if (aGoLarger)
       
   380 			currSize.iWidth<<=1;
       
   381 		else
       
   382 			currSize.iWidth>>=1;
       
   383 		}
       
   384 	iCompare.SetSize(currSize);
       
   385 	}
       
   386 	
       
   387 
       
   388 /**	Puts a line of text on the LHS window.
       
   389  *  Repaints the window. The line of text will also be shown in the log if the test fails.
       
   390  *	@param	aDetail	The text to display
       
   391  * 	@param	aIndex	The row number to display at
       
   392  **/
       
   393 void CWsDynamicResWinBase::UpdateTitleWindowL(TRefByValue<const TDesC16> aDetail,TInt aIndex)
       
   394 	{
       
   395 	ASSERT(aIndex>=0 && aIndex<KMaxInfoLines);
       
   396 	iTestInfo[aIndex]=aDetail;
       
   397 
       
   398 	RepaintTitleWindowL();
       
   399 	
       
   400 	}
       
   401 /**	Activate the GC onto the Window.
       
   402  *  In non-transparent mode it also performs a wipe background as the WServ system does not necessarily do this.
       
   403  * 	@param	aGc		The GC to associate
       
   404  * 	@param	aWin	The window to associate
       
   405  * 	@param	aColor	The color to use as the wipe. Default is transparent, which means no wipe.
       
   406  **/
       
   407 TBool	CWsDynamicResWinBase::ActivateWithWipe(CWindowGc* aGc,RWindow& aWin,TRgb aColor)
       
   408 	{
       
   409 	aGc->Activate(aWin);
       
   410 	aGc->SetBrushColor(aColor);
       
   411 	aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   412 	if (aColor!=TRgb(0,0) && !iTransparencyEnabled)	//presume that all redraw-stored windows will draw background
       
   413 		{
       
   414 		aGc->Clear();
       
   415 		return ETrue;	//window was cleared
       
   416 		}
       
   417 	return EFalse;	
       
   418 	}
       
   419 
       
   420 CWindowGc*	CWsDynamicResWinBase::GcForWindow(RWindow& aWin)
       
   421 	{
       
   422 	if (aWin.WsHandle()==NULL)
       
   423 		return NULL;	//can't activate uninitialised window.
       
   424 	CWindowGc* gc=iGc;
       
   425 	if (iGc!=iInfoGc)
       
   426 		if (&aWin==&iCompare || &aWin==&iTitle)
       
   427 			gc=iInfoGc;
       
   428 		else if (iInfoGroup && aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
       
   429 			gc=iInfoGc;
       
   430 	return gc;
       
   431 	}
       
   432 /** Activates an appropriate predefined GC on the specified window and wipes the background if necessary. 
       
   433  *  @param	aWin	The window to wipe
       
   434  * 	@param	aColor	The colour to wipe with (if necessary)
       
   435  * 	@return	the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live"
       
   436  **/
       
   437 CWindowGc*	CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,RWindow& aWin,TRgb aColor)
       
   438 	{
       
   439 	CWindowGc* gc=GcForWindow(aWin);
       
   440 	iSession.Flush();
       
   441 	if (gc==NULL)
       
   442 		return gc;	//can't activate uninitialised window.
       
   443 	if (aInvalidate)
       
   444 		aWin.Invalidate();
       
   445 	iSession.Flush();
       
   446 	aWin.BeginRedraw();
       
   447 	iSession.Flush();
       
   448 	ActivateWithWipe(gc,aWin,aColor);
       
   449 	return gc;	
       
   450 	}
       
   451 
       
   452 /** Activates an appropriate predefined GC on the specified window and wipes the background if necessary. 
       
   453  *  @param	aWin	The window to wipe
       
   454  * 	@param	aColor	The colour to wipe with (if necessary)
       
   455  * 	@return	the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live"
       
   456  **/
       
   457 CWindowGc*	CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,TRect aRect,RWindow& aWin,TRgb aColor)
       
   458 	{
       
   459 	if (aWin.WsHandle()==NULL)
       
   460 		return NULL;	//can't activate uninitialised window.
       
   461 	if (aInvalidate)
       
   462 		aWin.Invalidate(aRect);
       
   463 	aWin.BeginRedraw(aRect);
       
   464 	CWindowGc* gc=iGc;
       
   465 	if (iGc!=iInfoGc)
       
   466 		if (&aWin==&iCompare || &aWin==&iTitle)
       
   467 			gc=iInfoGc;
       
   468 		else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
       
   469 			gc=iInfoGc;
       
   470 	ActivateWithWipe(gc,aWin,aColor);
       
   471 	return gc;	
       
   472 	}
       
   473 
       
   474 TBool		CWsDynamicResWinBase::InvalidateRegion(const TRegion& aRegion,RWindow& aWin)
       
   475 	{
       
   476 	if (aWin.WsHandle()==NULL)
       
   477 		return false;	//can't activate uninitialised window.
       
   478 	for (TInt ii = 0; ii < aRegion.Count(); ii++)
       
   479 		{
       
   480 		aWin.Invalidate(aRegion[ii]);
       
   481 		}
       
   482 	return true;
       
   483 	}
       
   484 
       
   485 CWindowGc*	CWsDynamicResWinBase::BeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor)
       
   486 	{
       
   487 	if (!InvalidateRegion(aRegion,aWin))
       
   488 		return NULL;	//can't activate uninitialised window.
       
   489 
       
   490 	aWin.BeginRedraw();
       
   491 	CWindowGc* gc=iGc;
       
   492 	if (iGc!=iInfoGc)
       
   493 		if (&aWin==&iCompare || &aWin==&iTitle)
       
   494 			gc=iInfoGc;
       
   495 		else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
       
   496 			gc=iInfoGc;
       
   497 	ActivateWithWipe(gc,aWin,aColor);
       
   498 	return gc;	
       
   499 	}
       
   500 
       
   501 
       
   502 /**	Paints the LHS window with rows of text.
       
   503  * 
       
   504  **/
       
   505 void CWsDynamicResWinBase::RepaintTitleWindowL()
       
   506 	{
       
   507 	if (iTitle.WsHandle())
       
   508 		{
       
   509 		iTitle.Invalidate();
       
   510 	
       
   511 		iTitle.BeginRedraw();
       
   512 		ActivateWithWipe(iInfoGc,iTitle,TITLE_BACKGROUND);
       
   513 		iInfoGc->SetUnderlineStyle(EUnderlineOn);
       
   514 		TSize winSize=iTitle.Size();
       
   515 		TRect textRect(winSize);
       
   516 		textRect.iBr.iY/=4;
       
   517 		TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize);
       
   518 		CFont *font=NULL;
       
   519 		ASSERT_EQUALS(iInfoScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone);
       
   520 		iInfoGc->UseFont(font);
       
   521 		iInfoGc->DrawText(iTestName,textRect,textRect.iBr.iY/2,iGc->ECenter);
       
   522 		iInfoGc->SetUnderlineStyle(EUnderlineOff);
       
   523 		textRect.iTl.iY=textRect.iBr.iY;
       
   524 		TInt rowHeight=winSize.iHeight*3/(4*(KMaxInfoLines+1));
       
   525 		textRect.iBr.iY+=rowHeight;
       
   526 		for (TInt index=0;index<KMaxInfoLines;index++)
       
   527 			{
       
   528 			if (iTestInfo[index].Length())
       
   529 				iInfoGc->DrawText(iTestInfo[index],textRect,textRect.Size().iHeight*3/4,iInfoGc->ECenter);
       
   530 			textRect.Move(0,rowHeight);
       
   531 			}
       
   532 		iInfoGc->DiscardFont();
       
   533 		iInfoGc->Deactivate();
       
   534 		iTitle.EndRedraw();
       
   535 		iInfoScreenDevice->ReleaseFont(font);
       
   536 	
       
   537 		iSession.Flush();
       
   538 		iSession.Finish();
       
   539 		}
       
   540 	}
       
   541 
       
   542 /** Useful test culled from other GCE test classes.
       
   543  * 	
       
   544  * 
       
   545  * 
       
   546  **/
       
   547 TBool CWsDynamicResWinBase::DisplayHasAlpha() const
       
   548 	{
       
   549 	return (iDisplayMode == EColor16MA || iDisplayMode == EColor16MAP);
       
   550 	}
       
   551 /**	Test using an indipendent method that GCE version of WServ is running
       
   552  *  This method can only be called after the testcase is started
       
   553  * 
       
   554  * 	@return	true if WServ version is GCE technology, false if legacy technology
       
   555  **/
       
   556 TBool CWsDynamicResWinBase::GCEIsSupported() const
       
   557 	{
       
   558 	CFbsDrawDevice* screenDevice=NULL;
       
   559 	TDisplayMode displayMode=iScreenDevice->DisplayMode();
       
   560 	TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
       
   561 	TBool rv=EFalse;
       
   562 	if(err == KErrNone)
       
   563 		{
       
   564 		TAny* p=NULL;
       
   565 		rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
       
   566 		delete screenDevice;
       
   567 		}
       
   568 	return rv;
       
   569 	}
       
   570 /**	Test using an indipendent method that GCE version of WServ is running
       
   571  *  This method can be called at any time, even by external code, but creates temporary window session objects
       
   572  * 
       
   573  * 	@return	true if WServ version is GCE technology, false if legacy technology
       
   574  **/
       
   575 TBool CWsDynamicResWinBase::GCEIsSupportedStatic()
       
   576 	{
       
   577 	CFbsDrawDevice* screenDevice=NULL;
       
   578 	RWsSession session;
       
   579 	if (session.Connect()!=KErrNone)
       
   580 		{
       
   581 		return EFalse;
       
   582 		}
       
   583 	TDisplayMode displayMode=ENone;
       
   584 		{CWsScreenDevice screen(session);
       
   585 		if (screen.Construct(TGlobalSettings::Instance().iScreen)!=KErrNone)
       
   586 			{
       
   587 			return EFalse;
       
   588 			}
       
   589 			displayMode=screen.DisplayMode();
       
   590 		}//screen destroyed
       
   591 		TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
       
   592 		TBool rv=EFalse;
       
   593 		if(err == KErrNone)
       
   594 			{
       
   595 			TAny* p=NULL;
       
   596 			rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
       
   597 			delete screenDevice;
       
   598 			}
       
   599 	return rv;
       
   600 	}//session destroyed
       
   601 /**
       
   602 Use the full-screen background window to select a display mode that doesn't use
       
   603 alpha (anything other than EColor16MA or EColor16MAP). Record the mode for use
       
   604 in setting all other windows.
       
   605 @return ETrue if an appropriate mode was selected, EFalse otherwise.
       
   606 */
       
   607 TBool CWsDynamicResWinBase::SelectChromaCompositionMode()
       
   608 	{
       
   609 	// Request EColor64K, but as long as the actual mode doesn't use alpha, it
       
   610 	// doesn't matter too much which one is used.
       
   611 	if (iInfoGc==iGc)
       
   612 		{
       
   613 		iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(EColor64K);
       
   614 		iSession.Flush();		// Force switching to the display mode.
       
   615 		}
       
   616 	return !DisplayHasAlpha();
       
   617 	}
       
   618 /**	Returns the colour used by WServ to paint holes in UI layer to reveal the GCE behind.
       
   619  * 	The window should have a surface attached.
       
   620  * 	If the method is called after the surface has been detached or the window was removed then 
       
   621  * 	the previous recorded hole color is returned.
       
   622  **/
       
   623 TRgb  CWsDynamicResWinBase::GceHoleColor( RWindowBase& aWin)const
       
   624 	{
       
   625 	if (aWin.WsHandle()==NULL)
       
   626 		{
       
   627 		return iLastGceHoleColor;
       
   628 		}
       
   629 	TRgb retVal=aWin.KeyColor();
       
   630 	if (retVal==TRgb(0,0))
       
   631 		{
       
   632 		return iLastGceHoleColor;
       
   633 		}
       
   634 	else
       
   635 		{
       
   636 		iLastGceHoleColor=retVal;
       
   637 		return retVal;
       
   638 		}
       
   639 	}
       
   640 
       
   641 
       
   642 /**
       
   643 Use the full-screen background window to select a display mode that can use
       
   644 alpha (either EColor16MA or EColor16MAP). Record the mode for use in setting all
       
   645 other windows.
       
   646 @return ETrue if an appropriate mode was selected, EFalse otherwise.
       
   647 */
       
   648 TBool CWsDynamicResWinBase::SelectAlphaCompositionMode(TDisplayMode aMode)
       
   649 	{
       
   650 	// Request EColor16MA, but as long as the actual mode can use alpha, it
       
   651 	// doesn't matter too much which one is used.
       
   652 	if (iInfoGc==iGc)
       
   653 		{
       
   654 		iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(aMode);
       
   655 		iSession.Flush();		// Force switching to the display mode.
       
   656 		}
       
   657 	return DisplayHasAlpha();
       
   658 	}
       
   659 
       
   660 /**
       
   661  * 	Interesting UI pattern used by other GCE tests.
       
   662  * 
       
   663  * 
       
   664  **/
       
   665 void CWsDynamicResWinBase::DrawUIContent(RWindow& aWindow)
       
   666 	{
       
   667 	aWindow.BeginRedraw();
       
   668 	CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
       
   669 	
       
   670 	gc->Activate(aWindow);
       
   671 
       
   672 	TBool hasAlpha = DisplayHasAlpha();
       
   673 
       
   674 	// Draw a red-green graduated box in the central portion of the window,
       
   675 	// with alpha if available.
       
   676 	TPoint start;
       
   677 	TPoint end;
       
   678 	TInt halfW = KSurfaceWidth / 2;
       
   679 	TInt quarterW = halfW / 2;
       
   680 	TInt halfH = KSurfaceHeight / 2;
       
   681 	TInt quarterH = halfH / 2;
       
   682 
       
   683 	// Set constant ordinals for non-alpha case.
       
   684 	start.iX = quarterW;
       
   685 	end.iX = quarterW + halfW;
       
   686 
       
   687 	for (TInt yy = 0; yy < halfH; yy++)
       
   688 		{
       
   689 		TInt yval = yy * 255 / (halfH - 1);
       
   690 		start.iY = yy + quarterH;
       
   691 		end.iY = start.iY;
       
   692 
       
   693 		if (hasAlpha)
       
   694 			{
       
   695 			for (TInt xx = 0; xx < halfW; xx++)
       
   696 				{
       
   697 				TInt xval = xx * 255 / (halfW - 1);
       
   698 				start.iX = xx + quarterW;
       
   699 				end.iX = start.iX + 1;
       
   700 				gc->SetPenColor(TRgb(yval, 255 - yval, 0, xval));
       
   701 				gc->DrawLine(start, end);
       
   702 				}
       
   703 			}
       
   704 		else
       
   705 			{
       
   706 			gc->SetPenColor(TRgb(yval, 255 - yval, 0));
       
   707 			gc->DrawLine(start, end);
       
   708 			}
       
   709 		}
       
   710 
       
   711 	gc->Deactivate();
       
   712 	aWindow.EndRedraw();
       
   713 	}
       
   714 
       
   715 /**
       
   716  * 	Causes the given window to be redrawn.
       
   717  * 	Doesn't draw anything except the background wipe, when the transparency manager hasn't
       
   718  * 
       
   719  **/
       
   720 void CWsDynamicResWinBase::DrawPlainUI(RWindow& aWindow,TBool aInvalidate,TRgb aWipeColor)
       
   721 	{
       
   722 	if (CWindowGc* gc=BeginActivateWithWipe(aInvalidate,aWindow,aWipeColor))
       
   723 		{
       
   724 		//actually does nothing!
       
   725 		gc->Deactivate();
       
   726 		aWindow.EndRedraw();
       
   727 		}
       
   728 	}
       
   729 /**
       
   730  *  	Interesting UI pattern used by other GCE tests.
       
   731  * 
       
   732  * 
       
   733  **/
       
   734 void CWsDynamicResWinBase::DrawCross(RWindow& aWindow, TRgb aColor, TInt aThickness)
       
   735 	{
       
   736 	aWindow.BeginRedraw();
       
   737 	CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
       
   738 	gc->Activate(aWindow);
       
   739 
       
   740 	// Draw a red diagonal cross in the window.
       
   741 	gc->SetPenColor(aColor);
       
   742 	gc->SetPenSize(TSize(aThickness, aThickness));
       
   743 	gc->DrawLine(TPoint(0, 0), TPoint(KSurfaceWidth, KSurfaceHeight));
       
   744 	gc->DrawLine(TPoint(KSurfaceWidth, 0), TPoint(0, KSurfaceHeight));
       
   745 
       
   746 	gc->Deactivate();
       
   747 	aWindow.EndRedraw();
       
   748 	}
       
   749 
       
   750 /**
       
   751  * 	Checks the RGB value
       
   752  * 
       
   753  * 
       
   754  **/
       
   755 void CWsDynamicResWinBase::TestPixelL(TPoint aPt, TRgb aColor, TBool aMatch)
       
   756 	{
       
   757 	TRect screenArea(iScreenDevice->SizeInPixels());
       
   758 	if (aPt.iX < screenArea.iTl.iX)
       
   759 		{
       
   760 		aPt.iX = screenArea.iTl.iX;
       
   761 		}
       
   762 	else if (aPt.iX >= screenArea.iBr.iX)
       
   763 		{
       
   764 		aPt.iX = screenArea.iBr.iX - 1;
       
   765 		}
       
   766 	if (aPt.iY < screenArea.iTl.iY)
       
   767 		{
       
   768 		aPt.iY = screenArea.iTl.iY;
       
   769 		}
       
   770 	else if (aPt.iY >= screenArea.iBr.iY)
       
   771 		{
       
   772 		aPt.iY = screenArea.iBr.iY - 1;
       
   773 		}
       
   774 
       
   775 	TRgb pixel;
       
   776 	iScreenDevice->GetPixel(pixel, aPt);
       
   777 	if (aMatch)
       
   778 		{
       
   779 		ASSERT_EQUALS_X(pixel.Internal(), aColor.Internal());
       
   780 		}
       
   781 	else
       
   782 		{
       
   783 		ASSERT_NOT_EQUALS_X(pixel.Internal(), aColor.Internal());
       
   784 		}
       
   785 	}
       
   786 
       
   787 struct CountColour
       
   788 	{
       
   789 	TRgb	iColor;
       
   790 	TInt	iCount;
       
   791 	TBool operator  < (const CountColour& aRhs)const	
       
   792 		{	return iColor.Value()<aRhs.iColor.Value();	}
       
   793 	
       
   794 	CountColour(TRgb	aColor,TInt	aCount=0): 
       
   795 			iColor(aColor),iCount(aCount) {}
       
   796 	
       
   797 	CountColour(const CountColour& aRhs): 
       
   798 			iColor(aRhs.iColor),iCount(aRhs.iCount) {}
       
   799 	};
       
   800 
       
   801 void LogColorL(TRgb aPixel,RArray<CountColour>& aColors)
       
   802 	{
       
   803 	//I am sure one of the find methods would do this, but life is too short!
       
   804 	TInt existingIndex;
       
   805 	for (existingIndex=0;existingIndex<aColors.Count();existingIndex++)
       
   806 		if (aColors[existingIndex].iColor==aPixel)
       
   807 			break;
       
   808 	if (existingIndex==aColors.Count())
       
   809 		aColors.AppendL(CountColour(aPixel,1));
       
   810 	else
       
   811 		aColors[existingIndex].iCount++;
       
   812 	}
       
   813 
       
   814 /**
       
   815  * Tests the outline of the given rectangle to verify that it has the expected inner and outer colors
       
   816  * There may be a limited number of other colors present.
       
   817  * If the given count of other colors is exceeded then false is returned
       
   818  * If the majority of inner and outer edge pixels are not the given colors then returns false
       
   819  * If the  colors are repeated on inside and outside then returns false
       
   820  * If there are corners then the insides of the corners are also check for outside color
       
   821  * Note that the right and bottom edge coordinates are outside the rectangle.
       
   822  * Note that I am not performing any safety clipping at present. The rectangle must be on-screen!
       
   823  * A negative value for corner size indicates that the window may or may not have corners that size.
       
   824  * Only leaves if fatal memory condition!
       
   825 **/
       
   826 TBool CWsDynamicResWinBase::TestRectL(TRect aRect,TRgb aInnerColor,TInt aOtherInnerColors,TRgb aOuterColor,TInt aOtherOuterColors,TInt aExpectedCornerSize)
       
   827 	{
       
   828 	if (aRect.iTl.iX<=0 || aRect.iTl.iY<=0)
       
   829 		return ETrue;	//can't perform the test against the outside of the screen
       
   830 	//quantise the expectation based on the current mode.
       
   831 	switch (iScreenDevice->DisplayMode())
       
   832 	{
       
   833 	case EColor4K:
       
   834 		aInnerColor=aInnerColor.Color4K(aInnerColor.Color4K());
       
   835 		aOuterColor=aOuterColor.Color4K(aOuterColor.Color4K());
       
   836 	break;
       
   837 	case EColor64K:
       
   838 		aInnerColor=aInnerColor.Color64K(aInnerColor.Color64K());
       
   839 		aOuterColor=aOuterColor.Color64K(aOuterColor.Color64K());
       
   840 	break;
       
   841 	case EColor16M:
       
   842 	case EColor16MU:
       
   843 	case EColor16MA:
       
   844 	case EColor16MAP:
       
   845 		break;
       
   846 	default:
       
   847 		ASSERT_TRUE(!"Can't quantise color for this display mode!");
       
   848 	
       
   849 	}
       
   850 	RArray<CountColour> innerColors;
       
   851 	innerColors.AppendL(aInnerColor);
       
   852 	RArray<CountColour> outerColors;
       
   853 	outerColors.AppendL(aOuterColor);
       
   854 	TInt cornerSize=aExpectedCornerSize>=0?aExpectedCornerSize:-aExpectedCornerSize;
       
   855 	//Check outside first!
       
   856 	TRgb pixelVal;
       
   857 	for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY-1);pixelPos.iX<aRect.iBr.iX;pixelPos.iX++)
       
   858 		{
       
   859 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   860 		LogColorL(pixelVal,outerColors);
       
   861 		}
       
   862 	for(TPoint pixelPos(aRect.iTl.iX,aRect.iBr.iY);pixelPos.iX<=aRect.iBr.iX;pixelPos.iX++)
       
   863 		{
       
   864 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   865 		LogColorL(pixelVal,outerColors);
       
   866 		}
       
   867 	for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY);pixelPos.iY<=aRect.iBr.iY;pixelPos.iY++)
       
   868 		{
       
   869 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   870 		LogColorL(pixelVal,outerColors);
       
   871 		}
       
   872 	for(TPoint pixelPos(aRect.iBr.iX,aRect.iTl.iY-1);pixelPos.iY<aRect.iBr.iY;pixelPos.iY++)
       
   873 		{
       
   874 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   875 		LogColorL(pixelVal,outerColors);
       
   876 		}
       
   877 	TInt cornerStart=1;
       
   878 	if (cornerSize)
       
   879 		{
       
   880 		cornerStart=cornerSize;
       
   881 		if (aExpectedCornerSize>0)
       
   882 			{
       
   883 			iScreenDevice->GetPixel(pixelVal, aRect.iTl);
       
   884 			LogColorL(pixelVal,outerColors);
       
   885 			iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX,aRect.iBr.iY-1));
       
   886 			LogColorL(pixelVal,outerColors);
       
   887 			iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iTl.iY));
       
   888 			LogColorL(pixelVal,outerColors);
       
   889 			iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1));
       
   890 			LogColorL(pixelVal,outerColors);
       
   891 			}
       
   892 		}
       
   893 	
       
   894 	//test inside edges (excluding 4 corner pixels - do them seperately)
       
   895 	for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iTl.iY);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
       
   896 		{
       
   897 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   898 		LogColorL(pixelVal,innerColors);
       
   899 		}
       
   900 	for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iBr.iY-1);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
       
   901 		{
       
   902 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   903 		LogColorL(pixelVal,innerColors);
       
   904 		}
       
   905 	for(TPoint pixelPos(aRect.iTl.iX,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
       
   906 		{
       
   907 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   908 		LogColorL(pixelVal,innerColors);
       
   909 		}
       
   910 	for(TPoint pixelPos(aRect.iBr.iX-1,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
       
   911 		{
       
   912 		iScreenDevice->GetPixel(pixelVal, pixelPos);
       
   913 		LogColorL(pixelVal,innerColors);
       
   914 		}
       
   915 	//the 4 corner cells - not checking the whole corner area...
       
   916 	if (aExpectedCornerSize>=0)
       
   917 		{
       
   918 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iTl.iY+cornerSize));
       
   919 		LogColorL(pixelVal,innerColors);
       
   920 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iBr.iY-1-cornerSize));
       
   921 		LogColorL(pixelVal,innerColors);
       
   922 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iBr.iY-1-cornerSize));
       
   923 		LogColorL(pixelVal,innerColors);
       
   924 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iTl.iY+cornerSize));
       
   925 		LogColorL(pixelVal,innerColors);
       
   926 		}
       
   927 	//OK... that has tested all the pixels, now check the result
       
   928 	if (innerColors.Count()>aOtherInnerColors+1)
       
   929 		return EFalse;
       
   930 	if (outerColors.Count()>aOtherOuterColors+1)
       
   931 		return EFalse;
       
   932 	for (TInt index=1;index<innerColors.Count();index++)
       
   933 		if (innerColors[0].iCount<innerColors[index].iCount)
       
   934 			{
       
   935 			return EFalse;
       
   936 			}
       
   937 	for (TInt index=1;index<outerColors.Count();index++)
       
   938 		if (outerColors[0].iCount<outerColors[index].iCount)
       
   939 			{
       
   940 			return EFalse;
       
   941 			}
       
   942 	for (TInt indexIn=1;indexIn<innerColors.Count();indexIn++)
       
   943 		for (TInt indexOut=0;indexOut<outerColors.Count();indexOut++)
       
   944 			if (innerColors[indexIn].iColor.Value()==outerColors[indexOut].iColor.Value())
       
   945 				{
       
   946 				return EFalse;
       
   947 				}
       
   948 	return ETrue;
       
   949 	}
       
   950 
       
   951 TRect CWsDynamicResWinBase::PentCellRect(const TRect& aFullRect,char aStartLetter,char aEndLetter)
       
   952 	{
       
   953 	if (aEndLetter==0)
       
   954 		aEndLetter=aStartLetter;
       
   955 	aStartLetter&=0x1f;
       
   956 	aEndLetter&=0x1f;
       
   957 	TInt startx=(aStartLetter-1)%5;
       
   958 	TInt starty=(aStartLetter-1)/5;
       
   959 	TInt endx=(aEndLetter-1)%5;
       
   960 	TInt endy=(aEndLetter-1)/5;
       
   961 	if (starty>endy)
       
   962 		{	//swap			//	s		e
       
   963 		starty-=endy;		//	s-e
       
   964 		endy+=starty;		//			s					
       
   965 		starty=endy-starty;	//	e
       
   966 		}
       
   967 	if (startx>endx)
       
   968 		{	//swap			//	s		e
       
   969 		startx-=endx;		//	s-e
       
   970 		endx+=startx;		//			s					
       
   971 		startx=endx-startx;	//	e
       
   972 		}
       
   973 	TSize fullSize=aFullRect.Size();
       
   974 	return TRect(	aFullRect.iTl.iX+fullSize.iWidth*startx/5,
       
   975 					aFullRect.iTl.iY+fullSize.iHeight*starty/5,
       
   976 					aFullRect.iTl.iX+fullSize.iWidth*(endx+1)/5,
       
   977 					aFullRect.iTl.iY+fullSize.iHeight*(endy+1)/5
       
   978 				);
       
   979 	}