os/graphics/windowing/windowserver/test/tdynamicres/src/t_wsdynamicreswinbase.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2008-2010 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 			    {
   530 				iInfoGc->DrawText(iTestInfo[index],textRect,textRect.Size().iHeight*3/4,iInfoGc->ECenter);
   531 			    }
   532 			textRect.Move(0,rowHeight);
   533 			}
   534 		iInfoGc->DiscardFont();
   535 		iInfoGc->Deactivate();
   536 		iTitle.EndRedraw();
   537 		iInfoScreenDevice->ReleaseFont(font);
   538 	
   539 		iSession.Flush();
   540 		iSession.Finish();
   541 		}
   542 	}
   543 
   544 /** Useful test culled from other GCE test classes.
   545  * 	
   546  * 
   547  * 
   548  **/
   549 TBool CWsDynamicResWinBase::DisplayHasAlpha() const
   550 	{
   551 	return (iDisplayMode == EColor16MA || iDisplayMode == EColor16MAP);
   552 	}
   553 /**	Test using an indipendent method that GCE version of WServ is running
   554  *  This method can only be called after the testcase is started
   555  * 
   556  * 	@return	true if WServ version is GCE technology, false if legacy technology
   557  **/
   558 TBool CWsDynamicResWinBase::GCEIsSupported() const
   559 	{
   560 	CFbsDrawDevice* screenDevice=NULL;
   561 	TDisplayMode displayMode=iScreenDevice->DisplayMode();
   562 	TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
   563 	TBool rv=EFalse;
   564 	if(err == KErrNone)
   565 		{
   566 		TAny* p=NULL;
   567 		rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
   568 		delete screenDevice;
   569 		}
   570 	return rv;
   571 	}
   572 /**	Test using an indipendent method that GCE version of WServ is running
   573  *  This method can be called at any time, even by external code, but creates temporary window session objects
   574  * 
   575  * 	@return	true if WServ version is GCE technology, false if legacy technology
   576  **/
   577 TBool CWsDynamicResWinBase::GCEIsSupportedStatic()
   578 	{
   579 	CFbsDrawDevice* screenDevice=NULL;
   580 	RWsSession session;
   581 	if (session.Connect()!=KErrNone)
   582 		{
   583 		return EFalse;
   584 		}
   585 	TDisplayMode displayMode=ENone;
   586 		{CWsScreenDevice screen(session);
   587 		if (screen.Construct(TGlobalSettings::Instance().iScreen)!=KErrNone)
   588 			{
   589 			return EFalse;
   590 			}
   591 			displayMode=screen.DisplayMode();
   592 		}//screen destroyed
   593 		TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
   594 		TBool rv=EFalse;
   595 		if(err == KErrNone)
   596 			{
   597 			TAny* p=NULL;
   598 			rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
   599 			delete screenDevice;
   600 			}
   601 	return rv;
   602 	}//session destroyed
   603 /**
   604 Use the full-screen background window to select a display mode that doesn't use
   605 alpha (anything other than EColor16MA or EColor16MAP). Record the mode for use
   606 in setting all other windows.
   607 @return ETrue if an appropriate mode was selected, EFalse otherwise.
   608 */
   609 TBool CWsDynamicResWinBase::SelectChromaCompositionMode()
   610 	{
   611 	// Request EColor64K, but as long as the actual mode doesn't use alpha, it
   612 	// doesn't matter too much which one is used.
   613 	if (iInfoGc==iGc)
   614 		{
   615 		iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(EColor64K);
   616 		iSession.Flush();		// Force switching to the display mode.
   617 		}
   618 	return !DisplayHasAlpha();
   619 	}
   620 /**	Returns the colour used by WServ to paint holes in UI layer to reveal the GCE behind.
   621  * 	The window should have a surface attached.
   622  * 	If the method is called after the surface has been detached or the window was removed then 
   623  * 	the previous recorded hole color is returned.
   624  **/
   625 TRgb  CWsDynamicResWinBase::GceHoleColor( RWindowBase& aWin)const
   626 	{
   627 	if (aWin.WsHandle()==NULL)
   628 		{
   629 		return iLastGceHoleColor;
   630 		}
   631 	TRgb retVal=aWin.KeyColor();
   632 	if (retVal==TRgb(0,0))
   633 		{
   634 		return iLastGceHoleColor;
   635 		}
   636 	else
   637 		{
   638 		iLastGceHoleColor=retVal;
   639 		return retVal;
   640 		}
   641 	}
   642 
   643 
   644 /**
   645 Use the full-screen background window to select a display mode that can use
   646 alpha (either EColor16MA or EColor16MAP). Record the mode for use in setting all
   647 other windows.
   648 @return ETrue if an appropriate mode was selected, EFalse otherwise.
   649 */
   650 TBool CWsDynamicResWinBase::SelectAlphaCompositionMode(TDisplayMode aMode)
   651 	{
   652 	// Request EColor16MA, but as long as the actual mode can use alpha, it
   653 	// doesn't matter too much which one is used.
   654 	if (iInfoGc==iGc)
   655 		{
   656 		iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(aMode);
   657 		iSession.Flush();		// Force switching to the display mode.
   658 		}
   659 	return DisplayHasAlpha();
   660 	}
   661 
   662 /**
   663  * 	Interesting UI pattern used by other GCE tests.
   664  * 
   665  * 
   666  **/
   667 void CWsDynamicResWinBase::DrawUIContent(RWindow& aWindow)
   668 	{
   669 	aWindow.BeginRedraw();
   670 	CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
   671 	
   672 	gc->Activate(aWindow);
   673 
   674 	TBool hasAlpha = DisplayHasAlpha();
   675 
   676 	// Draw a red-green graduated box in the central portion of the window,
   677 	// with alpha if available.
   678 	TPoint start;
   679 	TPoint end;
   680 	TInt halfW = KSurfaceWidth / 2;
   681 	TInt quarterW = halfW / 2;
   682 	TInt halfH = KSurfaceHeight / 2;
   683 	TInt quarterH = halfH / 2;
   684 
   685 	// Set constant ordinals for non-alpha case.
   686 	start.iX = quarterW;
   687 	end.iX = quarterW + halfW;
   688 
   689 	for (TInt yy = 0; yy < halfH; yy++)
   690 		{
   691 		TInt yval = yy * 255 / (halfH - 1);
   692 		start.iY = yy + quarterH;
   693 		end.iY = start.iY;
   694 
   695 		if (hasAlpha)
   696 			{
   697 			for (TInt xx = 0; xx < halfW; xx++)
   698 				{
   699 				TInt xval = xx * 255 / (halfW - 1);
   700 				start.iX = xx + quarterW;
   701 				end.iX = start.iX + 1;
   702 				gc->SetPenColor(TRgb(yval, 255 - yval, 0, xval));
   703 				gc->DrawLine(start, end);
   704 				}
   705 			}
   706 		else
   707 			{
   708 			gc->SetPenColor(TRgb(yval, 255 - yval, 0));
   709 			gc->DrawLine(start, end);
   710 			}
   711 		}
   712 
   713 	gc->Deactivate();
   714 	aWindow.EndRedraw();
   715 	}
   716 
   717 /**
   718  * 	Causes the given window to be redrawn.
   719  * 	Doesn't draw anything except the background wipe, when the transparency manager hasn't
   720  * 
   721  **/
   722 void CWsDynamicResWinBase::DrawPlainUI(RWindow& aWindow,TBool aInvalidate,TRgb aWipeColor)
   723 	{
   724 	if (CWindowGc* gc=BeginActivateWithWipe(aInvalidate,aWindow,aWipeColor))
   725 		{
   726 		//actually does nothing!
   727 		gc->Deactivate();
   728 		aWindow.EndRedraw();
   729 		}
   730 	}
   731 /**
   732  *  	Interesting UI pattern used by other GCE tests.
   733  * 
   734  * 
   735  **/
   736 void CWsDynamicResWinBase::DrawCross(RWindow& aWindow, TRgb aColor, TInt aThickness)
   737 	{
   738 	aWindow.BeginRedraw();
   739 	CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
   740 	gc->Activate(aWindow);
   741 
   742 	// Draw a red diagonal cross in the window.
   743 	gc->SetPenColor(aColor);
   744 	gc->SetPenSize(TSize(aThickness, aThickness));
   745 	gc->DrawLine(TPoint(0, 0), TPoint(KSurfaceWidth, KSurfaceHeight));
   746 	gc->DrawLine(TPoint(KSurfaceWidth, 0), TPoint(0, KSurfaceHeight));
   747 
   748 	gc->Deactivate();
   749 	aWindow.EndRedraw();
   750 	}
   751 
   752 /**
   753  * 	Checks the RGB value
   754  * 
   755  * 
   756  **/
   757 void CWsDynamicResWinBase::TestPixelL(TPoint aPt, TRgb aColor, TBool aMatch)
   758 	{
   759 	TRect screenArea(iScreenDevice->SizeInPixels());
   760 	if (aPt.iX < screenArea.iTl.iX)
   761 		{
   762 		aPt.iX = screenArea.iTl.iX;
   763 		}
   764 	else if (aPt.iX >= screenArea.iBr.iX)
   765 		{
   766 		aPt.iX = screenArea.iBr.iX - 1;
   767 		}
   768 	if (aPt.iY < screenArea.iTl.iY)
   769 		{
   770 		aPt.iY = screenArea.iTl.iY;
   771 		}
   772 	else if (aPt.iY >= screenArea.iBr.iY)
   773 		{
   774 		aPt.iY = screenArea.iBr.iY - 1;
   775 		}
   776 
   777 	TRgb pixel;
   778 	iScreenDevice->GetPixel(pixel, aPt);
   779 	if (aMatch)
   780 		{
   781 		ASSERT_EQUALS_X(pixel.Internal(), aColor.Internal());
   782 		}
   783 	else
   784 		{
   785 		ASSERT_NOT_EQUALS_X(pixel.Internal(), aColor.Internal());
   786 		}
   787 	}
   788 
   789 struct CountColour
   790 	{
   791 	TRgb	iColor;
   792 	TInt	iCount;
   793 	TBool operator  < (const CountColour& aRhs)const	
   794 		{	return iColor.Value()<aRhs.iColor.Value();	}
   795 	
   796 	CountColour(TRgb	aColor,TInt	aCount=0): 
   797 			iColor(aColor),iCount(aCount) {}
   798 	
   799 	CountColour(const CountColour& aRhs): 
   800 			iColor(aRhs.iColor),iCount(aRhs.iCount) {}
   801 	};
   802 
   803 void LogColorL(TRgb aPixel,RArray<CountColour>& aColors)
   804 	{
   805 	//I am sure one of the find methods would do this, but life is too short!
   806 	TInt existingIndex;
   807 	for (existingIndex=0;existingIndex<aColors.Count();existingIndex++)
   808 		if (aColors[existingIndex].iColor==aPixel)
   809 			break;
   810 	if (existingIndex==aColors.Count())
   811 		aColors.AppendL(CountColour(aPixel,1));
   812 	else
   813 		aColors[existingIndex].iCount++;
   814 	}
   815 
   816 /**
   817  * Tests the outline of the given rectangle to verify that it has the expected inner and outer colors
   818  * There may be a limited number of other colors present.
   819  * If the given count of other colors is exceeded then false is returned
   820  * If the majority of inner and outer edge pixels are not the given colors then returns false
   821  * If the  colors are repeated on inside and outside then returns false
   822  * If there are corners then the insides of the corners are also check for outside color
   823  * Note that the right and bottom edge coordinates are outside the rectangle.
   824  * Note that I am not performing any safety clipping at present. The rectangle must be on-screen!
   825  * A negative value for corner size indicates that the window may or may not have corners that size.
   826  * Only leaves if fatal memory condition!
   827 **/
   828 TBool CWsDynamicResWinBase::TestRectL(TRect aRect,TRgb aInnerColor,TInt aOtherInnerColors,TRgb aOuterColor,TInt aOtherOuterColors,TInt aExpectedCornerSize)
   829 	{
   830 	if (aRect.iTl.iX<=0 || aRect.iTl.iY<=0)
   831 		return ETrue;	//can't perform the test against the outside of the screen
   832 	//quantise the expectation based on the current mode.
   833 	TDisplayMode displayMode=iScreenDevice->DisplayMode();
   834 	switch (displayMode)
   835 		{
   836 	case EColor4K:
   837 		aInnerColor=aInnerColor.Color4K(aInnerColor.Color4K());
   838 		aOuterColor=aOuterColor.Color4K(aOuterColor.Color4K());
   839 		break;
   840 	case EColor64K:
   841 		aInnerColor=aInnerColor.Color64K(aInnerColor.Color64K());
   842 		aOuterColor=aOuterColor.Color64K(aOuterColor.Color64K());
   843 		break;
   844 	case EColor16M:
   845 	case EColor16MU:
   846 	case EColor16MA:
   847 	case EColor16MAP:
   848 		break;
   849 	default:
   850 		ASSERT_EQUALS(EColor16MA,displayMode);		//Can't quantise color for this display mode!
   851 		}
   852 
   853 	RArray<CountColour> innerColors;
   854 	innerColors.AppendL(aInnerColor);
   855 	RArray<CountColour> outerColors;
   856 	outerColors.AppendL(aOuterColor);
   857 	TInt cornerSize=aExpectedCornerSize>=0?aExpectedCornerSize:-aExpectedCornerSize;
   858 	//Check outside first!
   859 	TRgb pixelVal;
   860 	for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY-1);pixelPos.iX<aRect.iBr.iX;pixelPos.iX++)
   861 		{
   862 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   863 		LogColorL(pixelVal,outerColors);
   864 		}
   865 	for(TPoint pixelPos(aRect.iTl.iX,aRect.iBr.iY);pixelPos.iX<=aRect.iBr.iX;pixelPos.iX++)
   866 		{
   867 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   868 		LogColorL(pixelVal,outerColors);
   869 		}
   870 	for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY);pixelPos.iY<=aRect.iBr.iY;pixelPos.iY++)
   871 		{
   872 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   873 		LogColorL(pixelVal,outerColors);
   874 		}
   875 	for(TPoint pixelPos(aRect.iBr.iX,aRect.iTl.iY-1);pixelPos.iY<aRect.iBr.iY;pixelPos.iY++)
   876 		{
   877 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   878 		LogColorL(pixelVal,outerColors);
   879 		}
   880 	TInt cornerStart=1;
   881 	if (cornerSize)
   882 		{
   883 		cornerStart=cornerSize;
   884 		if (aExpectedCornerSize>0)
   885 			{
   886 			iScreenDevice->GetPixel(pixelVal, aRect.iTl);
   887 			LogColorL(pixelVal,outerColors);
   888 			iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX,aRect.iBr.iY-1));
   889 			LogColorL(pixelVal,outerColors);
   890 			iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iTl.iY));
   891 			LogColorL(pixelVal,outerColors);
   892 			iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1));
   893 			LogColorL(pixelVal,outerColors);
   894 			}
   895 		}
   896 	
   897 	//test inside edges (excluding 4 corner pixels - do them seperately)
   898 	for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iTl.iY);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
   899 		{
   900 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   901 		LogColorL(pixelVal,innerColors);
   902 		}
   903 	for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iBr.iY-1);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
   904 		{
   905 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   906 		LogColorL(pixelVal,innerColors);
   907 		}
   908 	for(TPoint pixelPos(aRect.iTl.iX,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
   909 		{
   910 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   911 		LogColorL(pixelVal,innerColors);
   912 		}
   913 	for(TPoint pixelPos(aRect.iBr.iX-1,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
   914 		{
   915 		iScreenDevice->GetPixel(pixelVal, pixelPos);
   916 		LogColorL(pixelVal,innerColors);
   917 		}
   918 	//the 4 corner cells - not checking the whole corner area...
   919 	if (aExpectedCornerSize>=0)
   920 		{
   921 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iTl.iY+cornerSize));
   922 		LogColorL(pixelVal,innerColors);
   923 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iBr.iY-1-cornerSize));
   924 		LogColorL(pixelVal,innerColors);
   925 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iBr.iY-1-cornerSize));
   926 		LogColorL(pixelVal,innerColors);
   927 		iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iTl.iY+cornerSize));
   928 		LogColorL(pixelVal,innerColors);
   929 		}
   930 	//OK... that has tested all the pixels, now check the result
   931 	if (innerColors.Count()>aOtherInnerColors+1)
   932 		return EFalse;
   933 	if (outerColors.Count()>aOtherOuterColors+1)
   934 		return EFalse;
   935 	for (TInt index=1;index<innerColors.Count();index++)
   936 		if (innerColors[0].iCount<innerColors[index].iCount)
   937 			{
   938 			return EFalse;
   939 			}
   940 	for (TInt index=1;index<outerColors.Count();index++)
   941 		if (outerColors[0].iCount<outerColors[index].iCount)
   942 			{
   943 			return EFalse;
   944 			}
   945 	for (TInt indexIn=1;indexIn<innerColors.Count();indexIn++)
   946 		for (TInt indexOut=0;indexOut<outerColors.Count();indexOut++)
   947 			if (innerColors[indexIn].iColor.Value()==outerColors[indexOut].iColor.Value())
   948 				{
   949 				return EFalse;
   950 				}
   951 	return ETrue;
   952 	}
   953 
   954 TRect CWsDynamicResWinBase::PentCellRect(const TRect& aFullRect,char aStartLetter,char aEndLetter)
   955 	{
   956 	if (aEndLetter==0)
   957 		aEndLetter=aStartLetter;
   958 	aStartLetter&=0x1f;
   959 	aEndLetter&=0x1f;
   960 	TInt startx=(aStartLetter-1)%5;
   961 	TInt starty=(aStartLetter-1)/5;
   962 	TInt endx=(aEndLetter-1)%5;
   963 	TInt endy=(aEndLetter-1)/5;
   964 	if (starty>endy)
   965 		{	//swap			//	s		e
   966 		starty-=endy;		//	s-e
   967 		endy+=starty;		//			s					
   968 		starty=endy-starty;	//	e
   969 		}
   970 	if (startx>endx)
   971 		{	//swap			//	s		e
   972 		startx-=endx;		//	s-e
   973 		endx+=startx;		//			s					
   974 		startx=endx-startx;	//	e
   975 		}
   976 	TSize fullSize=aFullRect.Size();
   977 	return TRect(	aFullRect.iTl.iX+fullSize.iWidth*startx/5,
   978 					aFullRect.iTl.iY+fullSize.iHeight*starty/5,
   979 					aFullRect.iTl.iX+fullSize.iWidth*(endx+1)/5,
   980 					aFullRect.iTl.iY+fullSize.iHeight*(endy+1)/5
   981 				);
   982 	}