os/graphics/windowing/windowserverplugins/openwfc/src/displaypolicy.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-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 #include <graphics/wsgraphicdrawerinterface.h>
    17 #include <e32cmn.h>
    18 #include <u32hal.h>
    19 #include "displaypolicy.h"
    20 #include "panic.h"
    21 
    22 CDisplayPolicy::CDisplayPolicy():iLastAppMode(KErrNotReady),iSmallestAppMode(KErrNotReady)
    23 	{
    24 	// No implementation required
    25 	}
    26 
    27 CDisplayPolicy::~CDisplayPolicy()
    28 	{
    29 	}
    30 
    31 CDisplayPolicy* CDisplayPolicy::NewLC(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
    32 	{
    33 	CDisplayPolicy* self = new (ELeave)CDisplayPolicy();
    34 	CleanupStack::PushL(self);
    35 	self->ConstructL(aEnv,aScreen,aScreenNumber);
    36 	return self;
    37 	}
    38 
    39 CDisplayPolicy* CDisplayPolicy::NewL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
    40 	{
    41 	CDisplayPolicy* self=CDisplayPolicy::NewLC(aEnv,aScreen,aScreenNumber);
    42 	CleanupStack::Pop(); // self;
    43 	return self;
    44 	}
    45 
    46 void CDisplayPolicy::ConstructL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
    47 	{
    48 	iScreenIniFile=aEnv->ObjectInterface<MWsIniFile>();
    49 	if (iScreenIniFile)
    50 		{
    51 		_LIT(KScale,"DP_SCALING");
    52 		//_LIT(KScaleNone,"none");
    53 		_LIT(KScaleInteger,"integer");
    54 		_LIT(KScaleIsotropic,"isotropic");
    55 		_LIT(KScaleAnisotropic,"anisotropic");
    56 		_LIT(KScreenDisconnected,"SIMULATE_STARTUP_DISCONNECTED");
    57 		
    58 		iUiScaling = ENone;
    59 		TPtrC scalingModeName;
    60 		if (iScreenIniFile->FindVar(aScreenNumber,KScale,scalingModeName))
    61 			{
    62 			if (scalingModeName == KScaleInteger)
    63 				{
    64 				iUiScaling = EInteger;
    65 				}
    66 			else if (scalingModeName == KScaleIsotropic)
    67 				{
    68 				iUiScaling = EIsotropic;
    69 				}
    70 			else if (scalingModeName == KScaleAnisotropic)
    71 				{
    72 				iUiScaling = EAnisotropic;
    73 				}
    74 			}
    75 		
    76 		if (iScreenIniFile->FindVar(aScreenNumber,KScreenDisconnected))
    77 			{
    78 			//Simulate starting up with this screen disconnected
    79 			TDisplayConnectState displayState = EDisconnect;
    80 			TInt err = UserSvr::HalFunction(EHalGroupDisplay | (aScreenNumber<<16), EDisplayHalSetDisplayState, &displayState, NULL);
    81 			STD_ASSERT_ALWAYS(err == KErrNone, EPluginPanicHalSetDisplayState);
    82 			}
    83 		}
    84 	
    85 	iScreen=aScreen;
    86 	}
    87 
    88 void CDisplayPolicy::NewAppModesAvailable()
    89 	{
    90 	//This notification allows the list to be first populated after Wserv has finished initialising itself
    91 	//It also allows for the WServ debug method CWsScreenDevice::SetCurrentScreenModeAttributes
    92 	GetAppModeList();	//get the app size mode list again because some settings have changed
    93 	}
    94 
    95 void CDisplayPolicy::GetModeInfoL(const MWsScreenConfigList& aList,TInt aIndex,TPoint& aOffset,TSize& aSize,TAppMode& aMode)const
    96 	{
    97 	aOffset=aList.OriginL(aIndex);
    98 	aSize=aList.ScreenModeSizeInPixelsL(aIndex);
    99 	aMode.iPixels=TRect(aOffset,aSize);
   100 	aMode.iTwips=aList.ScreenModeSizeInTwipsL(aIndex);
   101 	aMode.iOrientations=aList.AvailableOrientationsL(aIndex);
   102 	}
   103 
   104 void CDisplayPolicy::GetAppModeList()
   105 	{
   106 	if (iScreen)
   107 		{
   108 		iSmallestAppMode = KErrNotFound;
   109 		iSmallestAppSize = TSize(10000,10000);
   110 		MWsScreenConfigList* screenConfigList=iScreen->ObjectInterface<MWsScreenConfigList>();
   111 		iNumNormalAppModes=0;
   112 		TSize largestAppMode;
   113 		if (screenConfigList)
   114 			{
   115 			RArray<TInt> goodModeIndices;
   116 			if (screenConfigList->GetScreenSizeModeList(goodModeIndices)!=KErrNone)
   117 				{
   118 				//If reserve fails then list is empty later - we can't change display res from app mode request, just use current and try to centre app area
   119 				iAppModes.Reserve(goodModeIndices.Count());
   120 				
   121 				//iScreenIniFile: First time in, it should be a good pointer from which to extract the basicFlags
   122 				//Repeat calls only update the values inside app mode list entries, and the ini file should not be read again. 
   123 				//Specify some basic flags by reading ini file for this screen number?
   124 				TInt basicFlags=0;
   125 				
   126 				//Our demo policy uses the app mode list to generate a list of virtual resolutions.
   127 				
   128 				for (TInt modeIndex=0;modeIndex<goodModeIndices.Count();modeIndex++)
   129 					{
   130 					TInt modeNum=goodModeIndices[modeIndex];
   131 					TAppMode mode;
   132 					TSize size;
   133 					TPoint offset;
   134 					mode.iFlags=basicFlags;
   135 					TRAP_IGNORE(mode.iFlags|=screenConfigList->ModeFlagsL(modeNum)); //we know modeNum is valid-wont leave
   136 					//any further flags to read from ini file for this appmode on this screen number?
   137 	
   138 					//Probably should ignore modes flagged with Hal or Dynamic
   139 					// at the moment we want all modes in the list! 
   140 	
   141 					TInt err = KErrNone;
   142 					TRAP(err,GetModeInfoL(*screenConfigList,goodModeIndices[modeIndex],offset,size,mode));
   143 					if (err == KErrNone)	//should never fail - we never ask for info for a bad mode
   144 						{
   145 						if (1<<CFbsBitGc::EGraphicsOrientationRotated90&mode.iOrientations 
   146 								|| 1<<CFbsBitGc::EGraphicsOrientationRotated270&mode.iOrientations)
   147 							{	//flip rect and twips
   148 							mode.iPixels = TRect(mode.iPixels.iTl.iY,mode.iPixels.iTl.iX,mode.iPixels.iBr.iY,mode.iPixels.iBr.iX);
   149 							mode.iTwips = TSize(mode.iTwips.iHeight,mode.iTwips.iWidth);
   150 							}
   151 						mode.iModeIndex=modeNum;
   152 						if (modeIndex==iAppModes.Count())
   153 							{
   154 							iAppModes.Append(mode);	//can't fail if reserve succeeded
   155 							}
   156 						else if (modeIndex<iAppModes.Count())
   157 							{
   158 							iAppModes[modeIndex]=mode;	//update - wserv implementation means order never changes.
   159 							}
   160 						//This is to help policy code decide what the minimum buffer size should be 
   161 						//Switching between modes requiring smaller screen area than this will not invoke memory reallocation, so will not fail.
   162 						//Perhaps an implementation would also consider the current lowest physical resolution as a guide.
   163 						//The HAL mode may be significantly larger than the app modes require
   164 						if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
   165 							{
   166 							TSize borderedSize=offset.AsSize()+size;
   167 							if (borderedSize.iWidth>largestAppMode.iWidth)
   168 								largestAppMode.iWidth=borderedSize.iWidth;
   169 							if (borderedSize.iHeight>largestAppMode.iHeight)
   170 								largestAppMode.iHeight=borderedSize.iHeight;
   171 							iNumNormalAppModes++;
   172 							}
   173 						
   174 						//find the smallest appmode. this will be used when display is disconnected
   175 						if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
   176 							{
   177 							TSize borderedSize=offset.AsSize()+size;
   178 							if(borderedSize.iWidth*borderedSize.iHeight < iSmallestAppSize.iWidth*iSmallestAppSize.iHeight)
   179 								{
   180 								iSmallestAppSize = borderedSize;
   181 								iSmallestAppMode = modeNum;
   182 								}
   183 							}
   184 						}
   185 						
   186 					}
   187 				}
   188 			goodModeIndices.Close();
   189 			}
   190 		iMinUiBufferSize=largestAppMode;
   191 		}
   192 	iScreenIniFile=NULL;
   193 	}
   194 
   195 TInt CDisplayPolicy::MapCompositionToUi(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
   196 	{
   197 	// only scaling is involved in mapping from composition to UI
   198 	// no offset change
   199 	TFraction widthFraction;
   200 	TFraction heightFraction;
   201 	if (	iCompositionSizePixels.iWidth<=0
   202 		||	iUiSizePixels.iWidth<=0
   203 		||	iCompositionSizePixels.iHeight<=0
   204 		||	iUiSizePixels.iHeight<=0)
   205 		{
   206 		aTarget=aSource;
   207 		return KErrNotReady;
   208 		}
   209 	if(aIsReverseMapping)
   210 		{
   211 		//Ui to composition
   212 		widthFraction.iNumer = iCompositionSizePixels.iWidth;
   213 		widthFraction.iDenom = iUiSizePixels.iWidth;
   214 		heightFraction.iNumer = iCompositionSizePixels.iHeight;
   215 		heightFraction.iDenom = iUiSizePixels.iHeight;
   216 		}
   217 	else
   218 		{
   219 		//composition to ui
   220 		widthFraction.iNumer = iUiSizePixels.iWidth;
   221 		widthFraction.iDenom = iCompositionSizePixels.iWidth;
   222 		heightFraction.iNumer = iUiSizePixels.iHeight;
   223 		heightFraction.iDenom = iCompositionSizePixels.iHeight;
   224 		}
   225 	
   226 	aTarget.iTl.iX = widthFraction * aSource.iTl.iX;
   227 	aTarget.iBr.iX = widthFraction * aSource.iBr.iX;
   228 	aTarget.iTl.iY = heightFraction * aSource.iTl.iY;
   229 	aTarget.iBr.iY = heightFraction * aSource.iBr.iY;
   230 	return KErrNone;
   231 	}
   232 
   233 void CDisplayPolicy::MapUiToApplication(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
   234 	{
   235 	// only offset is involved in mapping from Ui to App
   236 	// no scaling
   237 	TPoint offset = iAppSizePixels.iTl;;
   238 	
   239 	if(aIsReverseMapping)
   240 		{
   241 		//App to ui
   242 		aTarget.iTl = aSource.iTl + offset;
   243 		aTarget.iBr = aSource.iBr + offset;
   244 		}
   245 	else
   246 		{
   247 		//Ui to App
   248 		aTarget.iTl = aSource.iTl - offset;
   249 		aTarget.iBr = aSource.iBr - offset;
   250 		}
   251 	
   252 	}
   253 
   254 TInt CDisplayPolicy::MapUiToDSA(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const 
   255 	{
   256 	//only offset is involved in mapping from Ui to DSA
   257 	//no scaling
   258 	TPoint dsaOffset(0, 0);
   259 	
   260 	MWsScreenConfig *screenConfig = iScreen->ObjectInterface<MWsScreenConfig>();
   261 	if(screenConfig)
   262 		{
   263 		dsaOffset = screenConfig->Origin();
   264 		}
   265 	TRect rectInApp;
   266 	if(aIsReverseMapping)
   267 		{
   268 		//DSA to ui
   269 		//DSA to App first
   270 		rectInApp.iTl = aSource.iTl - dsaOffset;
   271 		rectInApp.iBr = aSource.iBr - dsaOffset;
   272 		//then app to UI
   273 		MapUiToApplication(rectInApp, aTarget, ETrue);
   274 		}
   275 	else
   276 		{
   277 		//Ui to DSA
   278 		//Ui to App first
   279 		MapUiToApplication(aSource, rectInApp, EFalse);
   280 		//then app to DSA
   281 		aTarget.iTl = rectInApp.iTl + dsaOffset;
   282 		aTarget.iBr = rectInApp.iBr + dsaOffset;
   283 		}
   284 	return KErrNone;
   285 	}
   286 TInt CDisplayPolicy::MapCoordinates(TCoordinateSpace aSourceSpace, const TRect& aSource, TCoordinateSpace aTargetSpace, TRect& aTarget) const
   287 	{
   288 	TInt returnCode=KErrNone;
   289 	switch (aSourceSpace)
   290 		{
   291 		case ECompositionSpace:
   292 			{
   293 			if(aTargetSpace == ECompositionSpace)
   294 				{
   295 				aTarget = aSource;
   296 				}
   297 			else if(aTargetSpace == EFullScreenSpace)
   298 				{
   299 				//composition to Ui
   300 				returnCode=MapCompositionToUi(aSource, aTarget, EFalse);
   301 				}
   302 			else if(aTargetSpace == EApplicationSpace)
   303 				{
   304 				//composition to App
   305 				TRect rectInUi;
   306 				returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
   307 				MapUiToApplication(rectInUi, aTarget, EFalse);
   308 				}
   309 			else if(aTargetSpace == EDirectScreenAccessSpace)
   310 				{
   311 				//composition to DSA
   312 				TRect rectInUi;
   313 				returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
   314 				if(returnCode < 0)
   315 					break;
   316 				returnCode=MapUiToDSA(rectInUi, aTarget, EFalse);
   317 				}
   318 			else
   319 				{
   320 				return KErrNotSupported;
   321 				}
   322 			}
   323 			break;
   324 		case EFullScreenSpace:
   325 			{
   326 			if(aTargetSpace == ECompositionSpace)
   327 				{
   328 				//Ui to composition
   329 				returnCode=MapCompositionToUi(aSource, aTarget, ETrue);
   330 				}
   331 			else if(aTargetSpace == EFullScreenSpace)
   332 				{
   333 				aTarget = aSource;
   334 				}
   335 			else if(aTargetSpace == EApplicationSpace)
   336 				{
   337 				//Ui to app
   338 				MapUiToApplication(aSource, aTarget, EFalse);
   339 				}
   340 			else if(aTargetSpace == EDirectScreenAccessSpace)
   341 				{
   342 				//Ui to DSA
   343 				returnCode = MapUiToDSA(aSource, aTarget, EFalse);
   344 				}
   345 			else
   346 				{
   347 				return KErrNotSupported;
   348 				}
   349 			}
   350 			break;
   351 		case EApplicationSpace:
   352 			{
   353 			if(aTargetSpace == ECompositionSpace)
   354 				{
   355 				//App to composition
   356 				TRect rectInUi;
   357 				MapUiToApplication(aSource, rectInUi, ETrue);
   358 				returnCode=MapCompositionToUi(rectInUi, aTarget, ETrue);
   359 				}
   360 			else if(aTargetSpace == EFullScreenSpace)
   361 				{
   362 				//App to Ui
   363 				MapUiToApplication(aSource, aTarget, ETrue);
   364 				}
   365 			else if(aTargetSpace == EApplicationSpace)
   366 				{
   367 				aTarget = aSource;
   368 				}
   369 			else if(aTargetSpace == EDirectScreenAccessSpace)
   370 				{
   371 				//App to DSA
   372 				TRect rectInUi;
   373 				MapUiToApplication(aSource, rectInUi, ETrue);
   374 				returnCode = MapUiToDSA(rectInUi, aTarget, EFalse);
   375 				}
   376 			else
   377 				{
   378 				return KErrNotSupported;
   379 				}
   380 			}
   381 			break;
   382 		case EDirectScreenAccessSpace:
   383 			{
   384 			if(aTargetSpace == ECompositionSpace)
   385 				{
   386 				//DSA to composition
   387 				TRect rectInUi;
   388 				returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
   389 				if(returnCode < KErrNone)
   390 					break;
   391 				returnCode = MapCompositionToUi(rectInUi, aTarget, ETrue);
   392 				}
   393 			else if(aTargetSpace == EFullScreenSpace)
   394 				{
   395 				//DSA to Ui
   396 				returnCode = MapUiToDSA(aSource, aTarget, ETrue);
   397 				}
   398 			else if(aTargetSpace == EApplicationSpace)
   399 				{
   400 				//DSA to app
   401 				TRect rectInUi;
   402 				returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
   403 				MapUiToApplication(rectInUi, aTarget, EFalse);
   404 				}
   405 			else if(aTargetSpace == EDirectScreenAccessSpace)
   406 				{
   407 				aTarget = aSource;
   408 				}
   409 			else
   410 				{
   411 				return KErrNotSupported;
   412 				}
   413 			break;
   414 			}
   415 		default:
   416 			returnCode= KErrNotSupported;
   417 		}
   418 	return returnCode;
   419 	}
   420 
   421 CDisplayPolicy::TFraction::TFraction():iNumer(0),iDenom(1)
   422 	{}
   423 
   424 TInt CDisplayPolicy::TFraction::operator*(TInt aInt) const
   425 	{
   426 	if (iDenom == 0 || iNumer == 0 || aInt == 0)
   427 		{
   428 		return 0;
   429 		}
   430 	TInt aNumer = iNumer<<1;
   431 	TInt aDenom = iDenom;
   432 	TInt returnValue = (aNumer*aInt)/aDenom;
   433 	returnValue ++;
   434 	return returnValue>>1;
   435 	}
   436 
   437 void	CDisplayPolicy::CalculateMinBufferSize(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aConnectionStatus)
   438 	{
   439 	iConnectionStatus = aConnectionStatus;
   440 	//preq2102: aResolutions is likely to be changed (in future)
   441 	if(iUiScaling == ENone)
   442 		{
   443 		//this function is currently only used with no scaling
   444 		//should not be called when display is disconnected
   445 		//with scaling iMinUiBufferSize is calculated in CDisplayPolicy::GetAppModeList()
   446 		TSize largestPhysicalRes = iMinUiBufferSize;		
   447 		for(TInt i = 0;i < aResolutions.Count(); i++)
   448 			{
   449 			if(aResolutions[i].iPixelSize.iWidth > largestPhysicalRes.iWidth)
   450 				{
   451 				largestPhysicalRes.iWidth = aResolutions[i].iPixelSize.iWidth;
   452 				}
   453 			if(aResolutions[i].iPixelSize.iHeight > largestPhysicalRes.iHeight)
   454 				{
   455 				largestPhysicalRes.iHeight = aResolutions[i].iPixelSize.iHeight;
   456 				}
   457 			}
   458 		
   459 		iMinUiBufferSize = largestPhysicalRes;
   460 		}
   461 	}
   462 
   463 void	CDisplayPolicy::AdjustStageBufferSize(const TSize& /*aOldSize*/,TSize& aNewSize)
   464 	{
   465 	if (iMinUiBufferSize.iWidth==0)
   466 		{
   467 		//just in case, should never happen
   468 		iMinUiBufferSize=TSize(1,1);	
   469 		}
   470 		
   471 	if ((aNewSize.iWidth == 0 || aNewSize.iHeight == 0
   472 			|| iConnectionStatus <= 0) && iUiScaling != ENone 
   473 			&& iSmallestAppMode >= 0) // if detached or turned off (iUiScaling != ENone) and smallestAppMode is found
   474 		{
   475 		aNewSize = iSmallestAppSize;
   476 		return;
   477 		}
   478 	 	 			
   479 	if (aNewSize.iWidth < iMinUiBufferSize.iWidth)
   480 		{
   481 		aNewSize.iWidth = iMinUiBufferSize.iWidth;
   482 		}
   483 	if (aNewSize.iHeight < iMinUiBufferSize.iHeight)
   484 		{
   485 		aNewSize.iHeight = iMinUiBufferSize.iHeight;
   486 		}
   487 	}
   488 
   489 void CDisplayPolicy::AddVirtualResolutionCount(TInt& aDisplayCount) const 
   490 	{
   491 	if (iUiScaling != ENone && aDisplayCount>0)
   492 		{
   493 		aDisplayCount += iNumNormalAppModes;
   494 		}
   495 	} 
   496 
   497 TInt CDisplayPolicy::AddVirtualResolutions(RArray<MDisplayControlBase::TResolution>& aResolutions) const
   498 	{
   499 	if (aResolutions.Count()==0 || iUiScaling == ENone)
   500 		{
   501 		return KErrNone;
   502 		}
   503 	if (aResolutions.Count()==1 && aResolutions[0].iPixelSize==TSize(0,0))
   504 		{
   505 		return KErrNone;
   506 		}
   507 		
   508 	TInt appModeCount = iAppModes.Count();
   509 	if (appModeCount == 0)
   510 		{
   511 		return KErrNone;
   512 		}
   513 	TInt resolutionCount = aResolutions.Count();
   514 	TInt error = aResolutions.Reserve(iNumNormalAppModes + resolutionCount);
   515 	if (error < KErrNone)
   516 		{
   517 		aResolutions.Reset();
   518 		return error;	//could fail to reserve if out of memory 
   519 		}
   520 	for (TInt appMode = 0; appMode < appModeCount; appMode++)
   521 		{
   522 		if (!(iAppModes[appMode].iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
   523 			{
   524 			MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
   525 			aResolutions.Append(virtualResolution);
   526 			}
   527 		}
   528 	return KErrNone;
   529 	}
   530 
   531 MDisplayControlBase::TResolution CDisplayPolicy::AppModeToResolution(RArray<MDisplayControlBase::TResolution>& aResolutions,TInt appMode)const
   532 	{
   533 	TAppMode mode = iAppModes[appMode];
   534 	TBool notComplete = ETrue;
   535 	TInt bestIndex;
   536 	TInt bestScale;
   537 	MDisplayControlBase::TResolution tempResolution(TSize(0,0),TSize(0,0));
   538 	TSize appBestSize;
   539 	while (notComplete)
   540 		{
   541 		TBool modeFit = FindVirtualMode(aResolutions,mode,appBestSize,bestIndex,bestScale);
   542 		
   543 		TSize uiSize;
   544 		if (iUiScaling == EInteger || iUiScaling == EIsotropic)
   545 			{
   546 			uiSize = ResolutionSize(aResolutions,appBestSize,bestIndex,bestScale);
   547 			}
   548 		else if (iUiScaling == EAnisotropic)
   549 			{
   550 			TBool swapAxis = EFalse;
   551 			TBool fitsAppMode = EFalse;
   552 			while (!fitsAppMode)
   553 				{
   554 				if (iAppModes[appMode].iFlags&MWsScreenConfigList::ETwipsSpecified)
   555 					{
   556 					//virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
   557 					//calculate based on twips
   558 					uiSize = ResolutionSizeFromTwips(aResolutions,appMode,appBestSize,bestIndex,swapAxis);
   559 					}
   560 				else
   561 					{
   562 					//assume square pixels
   563 					//virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
   564 					uiSize = ResolutionSizeFromAssumedTwips(aResolutions,appBestSize,bestIndex,swapAxis,bestScale);
   565 					}
   566 				
   567 				//if pixelsize found is larger than resolution mode its designed for, try scaling using other axis
   568 				if (uiSize.iWidth > aResolutions[bestIndex].iPixelSize.iWidth ||
   569 						uiSize.iHeight > aResolutions[bestIndex].iPixelSize.iHeight)
   570 					{
   571 					if (!modeFit)	//no other mode it could fit, to avoid infinite loop,say it fits the mode - will be scaled down
   572 						{
   573 						fitsAppMode = ETrue;
   574 						}
   575 					else
   576 						{
   577 						STD_ASSERT_DEBUG(swapAxis == EFalse, EPluginPanicTemp);
   578 						swapAxis = ETrue;
   579 						}
   580 					}
   581 				else
   582 					{
   583 					fitsAppMode = ETrue;
   584 					}
   585 				}
   586 			//if pixelsize found does not fit app mode, must retry with an appmode larger than the one found
   587 			if (uiSize.iWidth < iAppModes[appMode].iPixels.iBr.iX ||
   588 					uiSize.iHeight < iAppModes[appMode].iPixels.iBr.iY)
   589 				{
   590 				mode.iPixels.iBr.iX = aResolutions[bestIndex].iPixelSize.iWidth+1;
   591 				mode.iPixels.iBr.iY = aResolutions[bestIndex].iPixelSize.iHeight+1;
   592 				continue;
   593 				}
   594 			}
   595 
   596 		//MDisplayControlBase::TResolution virtualResolution(TSize(0,0),TSize(0,0));
   597 		
   598 		//only supports rotations supported by both sizemode and hardware
   599 		tempResolution.iFlags = iAppModes[appMode].iOrientations&aResolutions[bestIndex].iFlags.iFlags;
   600 		tempResolution.iFlags.Set(MDisplayControlBase::TResolution::EIsVirtual);
   601 		tempResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
   602 		tempResolution.iPixelSize = uiSize;
   603 
   604 		notComplete = EFalse;	//found a resolution that fits!
   605 		}
   606 	return tempResolution;
   607 	}
   608 
   609 TBool CDisplayPolicy::MatchConfigToResolutions(const RArray<MDisplayControlBase::TResolution>& aResolutions,
   610 		const TDisplayConfiguration& aConfig, TInt aStartIndex, TInt& aResolutionIndex)const
   611 	{
   612 	if (aStartIndex < 0 || aStartIndex >= aResolutions.Count())
   613 		{
   614 		return EFalse;
   615 		}
   616 	aResolutionIndex = -1;
   617 	for (TInt i = aStartIndex; i < aResolutions.Count(); i++)
   618 		{
   619 		if (aConfig.IsDefined(TDisplayConfigurationBase::EResolution))
   620 			{
   621 			TSize resolution;
   622 			aConfig.GetResolution(resolution);
   623 			if (resolution != aResolutions[i].iPixelSize)
   624 				{
   625 				continue;
   626 				}
   627 			}
   628 		if (aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
   629 			{
   630 			TSize twips;
   631 			aConfig.GetResolutionTwips(twips);
   632 			if (twips != aResolutions[i].iTwipsSize)
   633 				{
   634 				continue;
   635 				}
   636 			}
   637 		
   638 		if (aConfig.IsDefined(TDisplayConfigurationBase::ERotation))
   639 			{
   640 			TDisplayConfiguration1::TRotation rotation;
   641 			aConfig.GetRotation(rotation);
   642 			if (aResolutions[i].iFlags.IsClear(rotation))
   643 				{
   644 				continue;
   645 				}
   646 			}
   647 		aResolutionIndex = i;
   648 		return ETrue;
   649 		}
   650 	return EFalse;
   651 	}
   652 
   653 /*
   654 	Checks if specified appmode is compatible with TResolution specified
   655 	Returns ETrue if succeeded (and fills aConfig with TResolution
   656 	Return EFalse if they are not compatible (will not touch the config) 
   657 */
   658 TBool CDisplayPolicy::SetConfigToResolution(TInt aAppMode, MDisplayControlBase::TResolution aResolution, TDisplayConfiguration& aConfig)const
   659 	{
   660 	//find intersection of appmode and hardware rotations
   661 	TDisplayConfiguration1::TRotation configRotation;
   662 	TInt compatibleRotations;
   663 	if (aConfig.GetRotation(configRotation))
   664 		{
   665 		compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF&(1<<configRotation);
   666 		}
   667 	else
   668 		{
   669 		compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF;
   670 		}
   671 
   672 	if (compatibleRotations > 0)
   673 		{	//set first compatible rotation we find
   674 		if (1<<CFbsBitGc::EGraphicsOrientationNormal & compatibleRotations)
   675 			{
   676 			aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
   677 			}
   678 		else if (1<<CFbsBitGc::EGraphicsOrientationRotated90 & compatibleRotations)
   679 			{
   680 			aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
   681 			}
   682 		else if (1<<CFbsBitGc::EGraphicsOrientationRotated180 & compatibleRotations)
   683 			{
   684 			aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
   685 			}
   686 		else
   687 			{
   688 			aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
   689 			}
   690 		aConfig.SetResolution(aResolution.iPixelSize);
   691 		aConfig.SetResolutionTwips(aResolution.iTwipsSize);
   692 		return ETrue;
   693 		}
   694 
   695 	return EFalse;
   696 	}
   697 
   698 TInt CDisplayPolicy::GetSizeModeConfiguration(RArray<MDisplayControlBase::TResolution>& aResolutions,
   699 		TInt aScreenSizeMode, TDisplayConfiguration& aConfig, TRect& aSizeModePosition) const
   700 	{
   701 	//find appMode corresponding to screensizemode
   702 	TInt appMode;
   703 	TInt appModeCount = iAppModes.Count();
   704 	for (appMode = 0; appMode < appModeCount; appMode++)
   705 		{
   706 		if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
   707 			{
   708 			break;
   709 			}
   710 		}
   711 	if (appModeCount == appMode)
   712 		{
   713 		return KErrArgument;	//invalid screen size mode
   714 		}
   715 	if (!aConfig.IsDefined(TDisplayConfigurationBase::EResolution)&&
   716 			!aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
   717 		{
   718 		if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
   719 			{
   720 			TSize resSize = iCompositionSizePixels;
   721 			TSize twipsSize = iCompositionSizeTwips;
   722 			if (iLastCompositionRotation&TDisplayConfiguration::ERotation90CW ||
   723 					iLastCompositionRotation&TDisplayConfiguration::ERotation270CW)
   724 				{
   725 				TInt tempVal = resSize.iWidth;
   726 				resSize.iWidth = resSize.iHeight;
   727 				resSize.iHeight = tempVal;
   728 				tempVal = twipsSize.iWidth;
   729 				twipsSize.iWidth = twipsSize.iHeight;
   730 				twipsSize.iHeight = tempVal;
   731 				}
   732 			aConfig.SetResolution(resSize);
   733 			aConfig.SetResolutionTwips(twipsSize);
   734 			}
   735 		else
   736 			{
   737 			MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
   738 			aConfig.SetResolution(virtualResolution.iPixelSize);
   739 			aConfig.SetResolutionTwips(virtualResolution.iTwipsSize);
   740 			}
   741 		}
   742 
   743 	//check config is valid from set of resolutions (inc virtual)
   744 	TInt error = AddVirtualResolutions(aResolutions);
   745 	if (error < KErrNone)
   746 		{
   747 		return error;
   748 		}
   749 	TInt startIndex=0;
   750 	while (startIndex < aResolutions.Count())
   751 		{
   752 		TInt resolutionIndex;
   753 		TBool boolError = MatchConfigToResolutions(aResolutions,aConfig,startIndex,resolutionIndex);
   754 		if (boolError == EFalse)
   755 			{
   756 			return KErrArgument;
   757 			}
   758 		
   759 		//if is larger than current app mode and same rotation,we have found a match and can break;
   760 		TBool boolSet = SetConfigToResolution(appMode,aResolutions[resolutionIndex],aConfig);
   761 		if (boolSet)
   762 			{	//new configuration is compatible with app mode and has been set
   763 			//center appmode within the UI
   764 			if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
   765 				{
   766 				aSizeModePosition = aResolutions[resolutionIndex].iPixelSize;
   767 				}
   768 			else
   769 				{
   770 				CenteredAppInUi(aResolutions[resolutionIndex].iPixelSize,iAppModes[appMode].iPixels,aSizeModePosition);
   771 				}
   772 			
   773 			TDisplayConfiguration::TRotation tempRot;
   774 			aConfig.GetRotation(tempRot);
   775 			if (tempRot&1)
   776 				{
   777 				aSizeModePosition = TRect(aSizeModePosition.iTl.iY,aSizeModePosition.iTl.iX,
   778 						aSizeModePosition.iBr.iY,aSizeModePosition.iBr.iX);
   779 				}
   780 
   781 			return KErrNone;
   782 			}
   783 		//otherwise
   784 		startIndex = resolutionIndex+1;	//match found will not fit current size mode, continue looking
   785 		if (startIndex == aResolutions.Count())
   786 			{
   787 			return KErrArgument;
   788 			}
   789 		}
   790 	STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
   791 	return KErrGeneral;	//shouldnt be able to get here
   792 	}
   793 
   794 void CDisplayPolicy::CenteredAppInUi(const TSize& aUiSize,const TRect& aAppExtent,TRect& aSizeModePosition) const
   795 	{
   796 	if (aUiSize.iWidth > aAppExtent.Width())
   797 		{
   798 		aSizeModePosition.iTl.iX = (aUiSize.iWidth - aAppExtent.Width()) / 2;
   799 		if (aSizeModePosition.iTl.iX < aAppExtent.iTl.iX)
   800 			{	//we want to obey screenmode offset as a minumum, so cannot center on this axis
   801 			aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
   802 			aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
   803 			}
   804 		else
   805 			{
   806 			aSizeModePosition.iBr.iX = aSizeModePosition.iTl.iX + aAppExtent.Width();
   807 			}
   808 		}
   809 	else
   810 		{
   811 		aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
   812 		aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
   813 		}
   814 	
   815 	if (aUiSize.iHeight > aAppExtent.Height())
   816 		{
   817 		aSizeModePosition.iTl.iY = (aUiSize.iHeight - aAppExtent.Height()) / 2;
   818 		if (aSizeModePosition.iTl.iY < aAppExtent.iTl.iY)
   819 			{	//we want to obey screenmode offset as a minumum, so cannot center on this axis
   820 			aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
   821 			aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
   822 			}
   823 		else
   824 			{
   825 			aSizeModePosition.iBr.iY = aSizeModePosition.iTl.iY + aAppExtent.Width();
   826 			}
   827 		}
   828 	else
   829 		{
   830 		aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
   831 		aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
   832 		}
   833 	}
   834 
   835 TInt CDisplayPolicy::GetSizeModeConfiguration(TInt aScreenSizeMode,TDisplayConfiguration& aConfig, TRect& aSizeModePosition)
   836 	{
   837 	//This function is used when display is disconnected. Set UI size same as app mode. We don't care about rotation
   838 	
   839 	//find appMode corresponding to screensizemode
   840 	TInt appMode;
   841 	TInt appModeCount = iAppModes.Count();
   842 	for (appMode = 0; appMode < appModeCount; appMode++)
   843 		{
   844 		if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
   845 			{
   846 			break;
   847 			}
   848 		}
   849 	if (appModeCount == appMode)
   850 		{
   851 		return KErrArgument;	//invalid screen size mode
   852 		}
   853 	
   854 	if (1<<CFbsBitGc::EGraphicsOrientationRotated90&iAppModes[appMode].iOrientations 
   855 			|| 1<<CFbsBitGc::EGraphicsOrientationRotated270&iAppModes[appMode].iOrientations)
   856 		{//width and height were already flipped on construction. we need to flip it back
   857 		TRect appRect = iAppModes[appMode].iPixels;
   858 		TRect uiResRect(appRect.iTl.iX, appRect.iTl.iY, appRect.iBr.iY, appRect.iBr.iX);
   859 		aConfig.SetResolution(uiResRect.Size());
   860 		}
   861 	else
   862 		{
   863 		aConfig.SetResolution(iAppModes[appMode].iPixels.iBr.AsSize());
   864 		}
   865 	
   866 	CFbsBitGc::TGraphicsOrientation cFbsOrientation=CFbsBitGc::EGraphicsOrientationNormal;
   867 	//we know aScreenSizeMode is valid-OrientationL wont leave
   868 	TRAP_IGNORE(cFbsOrientation=iScreen->ObjectInterface<MWsScreenConfigList>()->OrientationL(aScreenSizeMode));
   869 	aConfig.SetRotation(TDisplayConfiguration::TRotation(cFbsOrientation));
   870 	aSizeModePosition = iAppModes[appMode].iPixels;
   871 	return KErrNone;
   872 	}
   873 
   874 TBool CDisplayPolicy::SettingConfiguration(const RArray<MDisplayControlBase::TResolution>& aResolutions,TDisplayConfiguration& aConfig)const
   875 	{	//converts configuration to appmode
   876 	if (iUiScaling == ENone)
   877 		{
   878 		if (aConfig.IsDefined(aConfig.EResolution))
   879 			{
   880 			TSize res;
   881 			aConfig.GetResolution(res);
   882 			TInt index;
   883 			for (index=0;index<aResolutions.Count();index++)
   884 				{
   885 				if  (aResolutions[index].iPixelSize == res)
   886 					{
   887 					break;
   888 					}
   889 				}
   890 			if (index == aResolutions.Count())
   891 				{	//failed to validate the resolution
   892 				aConfig.Clear(aConfig.EResolution);
   893 				}
   894 			}
   895 		return EFalse;
   896 		}
   897 	
   898 	
   899 	TAppMode appMode;
   900 	
   901 	TBool set;
   902 	TRect zeroRect (0,0,0,0);
   903 	TSize zeroSize (0,0);
   904 	TSize size;
   905 	set = aConfig.GetResolution(size);
   906 	appMode.iPixels = set ? size : zeroRect;
   907 	
   908 	set = aConfig.GetResolutionTwips(size);
   909 	appMode.iTwips = set ? size : zeroSize;
   910 	TDisplayConfiguration::TRotation flags;
   911 	set = aConfig.GetRotation(flags);	//grr orientation again
   912 	appMode.iOrientations = set? flags : 0;	//will set the specific rotation
   913 	
   914 	TInt index=0;
   915 	TInt scale=0;
   916 	TSize bestAppSize;
   917 	FindVirtualMode(aResolutions,appMode,bestAppSize,index,scale);
   918 	
   919 	//set aConfig to resolution returned
   920 	aConfig.SetResolution(aResolutions[index].iPixelSize);
   921 	aConfig.SetResolutionTwips(aResolutions[index].iTwipsSize);
   922 	if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotationNormalSupported)
   923 			&& appMode.iOrientations == TDisplayConfiguration::ERotationNormal)
   924 		{
   925 		aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
   926 		}
   927 	else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation90Supported)
   928 			&& appMode.iOrientations == TDisplayConfiguration::ERotation90CW)
   929 		{
   930 		aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
   931 		}
   932 	else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation180Supported)
   933 			&& appMode.iOrientations == TDisplayConfiguration::ERotation180)
   934 		{
   935 		aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
   936 		}
   937 	else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation270Supported)
   938 			&& appMode.iOrientations == TDisplayConfiguration::ERotation270CW)
   939 		{
   940 		aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
   941 		}
   942 	else
   943 		{
   944 		STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
   945 		return EFalse;	
   946 		}
   947 	return ETrue;
   948 	}
   949 
   950 void CDisplayPolicy::SetCompositionInfo (const TDisplayConfiguration& aCompositionConfig,
   951 		const TDisplayConfiguration& aUiConfig)
   952 	{
   953 	TDisplayConfiguration::TRotation rotation;
   954 	TSize sizePixels;
   955 	TSize sizeTwips;
   956 	if (aCompositionConfig.GetResolution(sizePixels))
   957 		{
   958 		aCompositionConfig.GetResolutionTwips(sizeTwips);
   959 		if(aCompositionConfig.IsDefined(TDisplayConfiguration::ERotation))
   960 			{
   961 			aCompositionConfig.GetRotation(rotation);
   962 			iLastCompositionRotation=rotation;
   963 			if(rotation & TDisplayConfiguration::ERotation90CW)
   964 				{
   965 				//swap width and height to be stored in iCompositionSizePixels and iCompositionSizeTwips
   966 				iCompositionSizePixels.iHeight = sizePixels.iWidth;
   967 				iCompositionSizePixels.iWidth = sizePixels.iHeight;
   968 				iCompositionSizeTwips.iHeight = sizeTwips.iWidth;
   969 				iCompositionSizeTwips.iWidth = sizeTwips.iHeight;
   970 				}
   971 			else
   972 				{
   973 				iCompositionSizePixels = sizePixels;
   974 				iCompositionSizeTwips = sizeTwips;
   975 				}
   976 			}
   977 		else
   978 			{
   979 			iCompositionSizePixels = sizePixels;
   980 			iCompositionSizeTwips = sizeTwips;
   981 			}
   982 		
   983 		aUiConfig.GetResolution(sizePixels);
   984 		aUiConfig.GetResolutionTwips(sizeTwips);
   985 		if(aUiConfig.IsDefined(TDisplayConfiguration::ERotation))
   986 			{
   987 			aUiConfig.GetRotation(rotation);
   988 			iLastUiRotation=rotation;
   989 			if(rotation & TDisplayConfiguration::ERotation90CW)
   990 				{
   991 				//swap width and height to be stored in iUiSizePixels and iAppSizeTwips
   992 				iUiSizePixels.iHeight = sizePixels.iWidth;
   993 				iUiSizePixels.iWidth = sizePixels.iHeight;
   994 				iAppSizeTwips.iHeight = sizeTwips.iWidth;
   995 				iAppSizeTwips.iWidth = sizeTwips.iHeight;
   996 				}
   997 			else
   998 				{
   999 				iUiSizePixels = sizePixels;
  1000 				iAppSizeTwips = sizeTwips;
  1001 				}
  1002 			}
  1003 		else
  1004 			{
  1005 			iUiSizePixels = sizePixels;
  1006 			iAppSizeTwips = sizeTwips;
  1007 			}	
  1008 		}
  1009 	else
  1010 		{
  1011 		if (aUiConfig.GetRotation(rotation))
  1012 			{
  1013 			if ((rotation^iLastUiRotation)&TDisplayConfiguration::ERotation90CW)
  1014 				{
  1015 				TInt swapHeight=iUiSizePixels.iHeight;
  1016 				iUiSizePixels.iHeight = iUiSizePixels.iWidth;
  1017 				iUiSizePixels.iWidth = swapHeight;
  1018 				}
  1019 			iLastUiRotation=rotation;
  1020 			}
  1021 		
  1022 		if (aCompositionConfig.GetRotation(rotation))
  1023 			{
  1024 			if ((rotation^iLastCompositionRotation)&TDisplayConfiguration::ERotation90CW)
  1025 				{
  1026 				TInt swapHeight=iCompositionSizePixels.iHeight;
  1027 				iCompositionSizePixels.iHeight = iCompositionSizePixels.iWidth;
  1028 				iCompositionSizePixels.iWidth = swapHeight;
  1029 				swapHeight=iCompositionSizeTwips.iHeight;
  1030 				iCompositionSizeTwips.iHeight = iCompositionSizeTwips.iWidth;
  1031 				iCompositionSizeTwips.iWidth = swapHeight;
  1032 				}
  1033 			iLastCompositionRotation=rotation;
  1034 			}
  1035 		}
  1036 	}
  1037 
  1038 void CDisplayPolicy::SetSizeModeExtent(TRect& aExtent, TBitFlags32 /*aContext*/)
  1039 	{
  1040 	iAppSizePixels = aExtent;
  1041 	}
  1042 
  1043 /**	Finds the best resolution that the specified appmode can fit into
  1044 	Returns ETrue if it fits a mode
  1045 	Returns EFalse to warn if it didnt fit in that mode
  1046 	For both, it will set index and scale to the best fit
  1047 */
  1048 TBool CDisplayPolicy::FindVirtualMode(const RArray<MDisplayControlBase::TResolution>& aResolutions,
  1049 		const CDisplayPolicy::TAppMode& aAppMode,TSize& aFullAppModeSize,TInt& aIndex,TInt& aBestScale) const
  1050 	{
  1051 	const TInt KBestFit = 0x7000000; //a really big number that should get reduced during the search.
  1052 	TInt bestFit=KBestFit;
  1053 	TInt resDiffX;
  1054 	TInt resDiffY;
  1055 	TInt64 biggestArea(0);
  1056 	TInt biggestAreaIndex=0;
  1057 	TBool fullAppSize;
  1058 	
  1059 	if (aAppMode.iPixels.iTl.iX == 0 && aAppMode.iPixels.iTl.iY == 0)
  1060 		{	//no point trying again with a border on only 2 sides, as there is no border anyway!
  1061 		fullAppSize = EFalse;
  1062 		}
  1063 	else
  1064 		{
  1065 		fullAppSize = ETrue;
  1066 		}
  1067 	aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX + aAppMode.iPixels.iTl.iX,
  1068 			aAppMode.iPixels.iBr.iY + aAppMode.iPixels.iTl.iY);	//try fitting with border all 4 sides
  1069 
  1070 	while(1)
  1071 		{
  1072 		//find hardware mode that fits this best
  1073 		for (TInt j = 0; j < aResolutions.Count(); j++)
  1074 			{
  1075 			if (bestFit == 0)
  1076 				{	//found a perfect match
  1077 				break;
  1078 				}
  1079 			if (aResolutions[j].iFlags[MDisplayControlBase::TResolution::EIsVirtual])
  1080 				{	//ignore virtual resolutions
  1081 				continue;
  1082 				}
  1083 			TInt maxScaling = 1;
  1084 			if (iUiScaling == EInteger)
  1085 				{
  1086 				maxScaling = 4;
  1087 				}
  1088 			for (TInt k = maxScaling; k > 0; k--)
  1089 				{	//for every avalable integer scale
  1090 				if (bestFit == 0)
  1091 					{	//found a perfect match
  1092 					break;
  1093 					}
  1094 				TInt64 area=TInt64(aResolutions[j].iPixelSize.iWidth)*aResolutions[j].iPixelSize.iHeight;
  1095 				if (area>biggestArea)
  1096 					{
  1097 					biggestArea=area;
  1098 					biggestAreaIndex=j;
  1099 					}
  1100 				resDiffX = (aResolutions[j].iPixelSize.iWidth/k) - aFullAppModeSize.iWidth;
  1101 				resDiffY = (aResolutions[j].iPixelSize.iHeight/k) - aFullAppModeSize.iHeight;
  1102 
  1103 				if (resDiffX < 0 || resDiffY < 0)
  1104 					{	//app mode too large for this resolution
  1105 					continue;
  1106 					}
  1107 				if (resDiffX+resDiffY < bestFit)
  1108 					{
  1109 					aIndex = j;
  1110 					bestFit =  resDiffX + resDiffY;
  1111 					aBestScale = k;
  1112 					continue;
  1113 					}
  1114 				}
  1115 			}
  1116 		if (bestFit != KBestFit)
  1117 			{	//it found the best resolution to scale into
  1118 			break;
  1119 			}
  1120 		else if (fullAppSize == EFalse)
  1121 			{	//app does not fit any resolution, it will have to be scaled down to fit
  1122 			aIndex=biggestAreaIndex;
  1123 			aBestScale=1;
  1124 			return EFalse;
  1125 			}
  1126 		else
  1127 			{
  1128 			aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX,
  1129 					aAppMode.iPixels.iBr.iY);	//try fitting with border only top and left
  1130 			fullAppSize = EFalse;
  1131 			}
  1132 		}
  1133 	return ETrue;
  1134 	}
  1135 
  1136 TSize CDisplayPolicy::ResolutionSize(RArray<MDisplayControlBase::TResolution>& aResolutions,
  1137 		const TSize aBestAppSize,TInt aIndex, TInt aScale) const
  1138 	{
  1139 	TSize returnSize;
  1140 	
  1141 	if (iUiScaling == EInteger)	//only supporting integral scales
  1142 		{	//just calculate the scaled resolution
  1143 		returnSize = TSize(aResolutions[aIndex].iPixelSize.iWidth/aScale,
  1144 				aResolutions[aIndex].iPixelSize.iHeight/aScale);
  1145 		}
  1146 	else
  1147 		{	//find which axis scales best, create virtual resolution that fits this axis
  1148 		TFraction bestAxisAsFraction;
  1149 
  1150 		if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > 
  1151 				(TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
  1152 			{	//y axis scales closest
  1153 			bestAxisAsFraction.iNumer = aResolutions[aIndex].iPixelSize.iWidth;
  1154 			bestAxisAsFraction.iDenom = aResolutions[aIndex].iPixelSize.iHeight;
  1155 			returnSize = TSize(bestAxisAsFraction*aBestAppSize.iHeight,
  1156 					aBestAppSize.iHeight);
  1157 			}
  1158 		else
  1159 			{	//x axis scales closest
  1160 			bestAxisAsFraction.iNumer = aResolutions[aIndex].iPixelSize.iHeight;
  1161 			bestAxisAsFraction.iDenom = aResolutions[aIndex].iPixelSize.iWidth;
  1162 			returnSize = TSize(aBestAppSize.iWidth,
  1163 					bestAxisAsFraction*aBestAppSize.iWidth);
  1164 			}
  1165 		}
  1166 	return returnSize;
  1167 	}
  1168 
  1169 TSize CDisplayPolicy::GetUiResolution()
  1170 	{
  1171 	return this->iUiSizePixels;
  1172 	}
  1173 
  1174 TSize CDisplayPolicy::GetUiResolutionAsTwips() const
  1175     {
  1176     return this->iCompositionSizeTwips;
  1177     }
  1178 
  1179 TRect CDisplayPolicy::GetPolicyAppMode()
  1180 	{
  1181 	return iAppSizePixels;
  1182 	}
  1183 
  1184 TSize CDisplayPolicy::ResolutionSizeFromTwips(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aAppMode, const TSize& aBestAppSize,
  1185 		TInt aIndex,TBool aSwapAxis) const
  1186 	{
  1187 	TSize returnSize;
  1188 	TFraction tempFraction;
  1189 	TBool yScalesClosest;
  1190 	
  1191 	if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > (TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
  1192 		{	//y axis scales closest
  1193 		yScalesClosest = aSwapAxis?EFalse:ETrue;
  1194 		}
  1195 	else
  1196 		{	//x axis scales closest
  1197 		yScalesClosest = aSwapAxis?ETrue:EFalse;
  1198 		}
  1199 	
  1200 	if (yScalesClosest)
  1201 		{	//y axis scales closest
  1202 		tempFraction.iNumer = aBestAppSize.iHeight;	//bordered app height in pixels
  1203 		tempFraction.iDenom = iAppModes[aAppMode].iPixels.iBr.iY - iAppModes[aAppMode].iPixels.iTl.iY;	//app height in pixels
  1204 		TInt uiYTwips=tempFraction*iAppModes[aAppMode].iTwips.iHeight;	//bordered app height in twips
  1205 		
  1206 		tempFraction.iNumer = aResolutions[aIndex].iTwipsSize.iWidth;	//display width in twips
  1207 		tempFraction.iDenom = aResolutions[aIndex].iTwipsSize.iHeight;	//display height in twips
  1208 		TInt uiXTwips=tempFraction*uiYTwips;	//virtual width in twips
  1209 		
  1210 		tempFraction.iNumer = iAppModes[aAppMode].iPixels.iBr.iX - iAppModes[aAppMode].iPixels.iTl.iX;	//app width in pixels
  1211 		tempFraction.iDenom = iAppModes[aAppMode].iTwips.iWidth;	//display width in twips
  1212 		TInt uiXPixels=tempFraction*uiXTwips;	//virtual width in pixels
  1213 		
  1214 		returnSize.iWidth = uiXPixels;
  1215 		returnSize.iHeight = aBestAppSize.iHeight;
  1216 		}
  1217 	else
  1218 		{	//x axis scales closest
  1219 		tempFraction.iNumer = aBestAppSize.iWidth;	//bordered app width in pixels
  1220 		tempFraction.iDenom = iAppModes[aAppMode].iPixels.iBr.iX - iAppModes[aAppMode].iPixels.iTl.iX;	//app width in pixels
  1221 		TInt uiXTwips=tempFraction*iAppModes[aAppMode].iTwips.iWidth;	//bordered app width in twips
  1222 		
  1223 		tempFraction.iNumer = aResolutions[aIndex].iTwipsSize.iHeight;	//display height in twips
  1224 		tempFraction.iDenom = aResolutions[aIndex].iTwipsSize.iWidth;	//display width in twips
  1225 		TInt uiYTwips=tempFraction*uiXTwips;	//virtual height in twips
  1226 		
  1227 		tempFraction.iNumer = iAppModes[aAppMode].iPixels.iBr.iY - iAppModes[aAppMode].iPixels.iTl.iY;	//app height in pixels
  1228 		tempFraction.iDenom = iAppModes[aAppMode].iTwips.iHeight;	//display height in twips
  1229 		TInt uiYPixels=tempFraction*uiYTwips;	//virtual width in pixels
  1230 		
  1231 		returnSize.iWidth = aBestAppSize.iWidth;
  1232 		returnSize.iHeight = uiYPixels;
  1233 		}
  1234 	
  1235 	return returnSize;
  1236 	}
  1237 
  1238 TSize CDisplayPolicy::ResolutionSizeFromAssumedTwips(RArray<MDisplayControlBase::TResolution>& aResolutions,const TSize& aBestAppSize,
  1239 		TInt aIndex,TBool aSwapAxis, TInt aScale) const
  1240 	{
  1241 	TSize returnSize;
  1242 	
  1243 	if (iUiScaling == EInteger)	//only supporting integral scales
  1244 		{	//just calculate the scaled resolution
  1245 		returnSize = TSize(aResolutions[aIndex].iTwipsSize.iWidth/aScale,
  1246 				aResolutions[aIndex].iTwipsSize.iHeight/aScale);
  1247 		}
  1248 	else
  1249 		{	//find which axis scales best, create virtual resolution that fits this axis
  1250 		TBool yScalesClosest;
  1251 		TFraction bestAxisAsFraction;
  1252 		
  1253 		if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > 
  1254 				(TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
  1255 			{	//y axis scales closest
  1256 			yScalesClosest = aSwapAxis?EFalse:ETrue;
  1257 			}
  1258 		else
  1259 			{	//x axis scales closest
  1260 			yScalesClosest = aSwapAxis?ETrue:EFalse;
  1261 			}
  1262 		
  1263 		if (yScalesClosest)
  1264 			{	//y axis scales closest
  1265 			bestAxisAsFraction.iNumer = aResolutions[aIndex].iTwipsSize.iWidth;
  1266 			bestAxisAsFraction.iDenom = aResolutions[aIndex].iTwipsSize.iHeight;
  1267 			returnSize = TSize(bestAxisAsFraction*aBestAppSize.iHeight,
  1268 					aBestAppSize.iHeight);
  1269 			}
  1270 		else
  1271 			{	//x axis scales closest
  1272 			bestAxisAsFraction.iNumer = aResolutions[aIndex].iTwipsSize.iHeight;
  1273 			bestAxisAsFraction.iDenom = aResolutions[aIndex].iTwipsSize.iWidth;
  1274 			returnSize = TSize(aBestAppSize.iWidth,
  1275 					bestAxisAsFraction*aBestAppSize.iWidth);
  1276 			}
  1277 		}
  1278 	return returnSize;
  1279 	}
  1280 
  1281 TInt CDisplayPolicy::MinSizedModeIndex()
  1282 	{
  1283 	return iSmallestAppMode;
  1284 	}
  1285 
  1286 TInt CDisplayPolicy::SuitableAppMode(MWsDisplayPolicy::TDisplayStatus aSituation)
  1287 	{
  1288 	switch(aSituation)
  1289 		{
  1290 		case MWsDisplayPolicy::EAttach:
  1291 			{
  1292 			return iLastAppMode;
  1293 			}
  1294 		case MWsDisplayPolicy::EDetach:
  1295 			{
  1296 			return MinSizedModeIndex();
  1297 			}
  1298 		default:
  1299 			return KErrNotSupported;
  1300 		}
  1301 
  1302 	}
  1303 
  1304 void CDisplayPolicy::SetLastAppMode(TInt aMode)
  1305 	{
  1306 	iLastAppMode = aMode;
  1307 	}
  1308 
  1309