windowing/windowserverplugins/openwfc/src/displaypolicy.cpp
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/openwfc/src/displaypolicy.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1309 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <graphics/wsgraphicdrawerinterface.h>
+#include <e32cmn.h>
+#include <u32hal.h>
+#include "displaypolicy.h"
+#include "panic.h"
+
+CDisplayPolicy::CDisplayPolicy():iLastAppMode(KErrNotReady),iSmallestAppMode(KErrNotReady)
+	{
+	// No implementation required
+	}
+
+CDisplayPolicy::~CDisplayPolicy()
+	{
+	}
+
+CDisplayPolicy* CDisplayPolicy::NewLC(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
+	{
+	CDisplayPolicy* self = new (ELeave)CDisplayPolicy();
+	CleanupStack::PushL(self);
+	self->ConstructL(aEnv,aScreen,aScreenNumber);
+	return self;
+	}
+
+CDisplayPolicy* CDisplayPolicy::NewL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
+	{
+	CDisplayPolicy* self=CDisplayPolicy::NewLC(aEnv,aScreen,aScreenNumber);
+	CleanupStack::Pop(); // self;
+	return self;
+	}
+
+void CDisplayPolicy::ConstructL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
+	{
+	iScreenIniFile=aEnv->ObjectInterface<MWsIniFile>();
+	if (iScreenIniFile)
+		{
+		_LIT(KScale,"DP_SCALING");
+		//_LIT(KScaleNone,"none");
+		_LIT(KScaleInteger,"integer");
+		_LIT(KScaleIsotropic,"isotropic");
+		_LIT(KScaleAnisotropic,"anisotropic");
+		_LIT(KScreenDisconnected,"SIMULATE_STARTUP_DISCONNECTED");
+		
+		iUiScaling = ENone;
+		TPtrC scalingModeName;
+		if (iScreenIniFile->FindVar(aScreenNumber,KScale,scalingModeName))
+			{
+			if (scalingModeName == KScaleInteger)
+				{
+				iUiScaling = EInteger;
+				}
+			else if (scalingModeName == KScaleIsotropic)
+				{
+				iUiScaling = EIsotropic;
+				}
+			else if (scalingModeName == KScaleAnisotropic)
+				{
+				iUiScaling = EAnisotropic;
+				}
+			}
+		
+		if (iScreenIniFile->FindVar(aScreenNumber,KScreenDisconnected))
+			{
+			//Simulate starting up with this screen disconnected
+			TDisplayConnectState displayState = EDisconnect;
+			TInt err = UserSvr::HalFunction(EHalGroupDisplay | (aScreenNumber<<16), EDisplayHalSetDisplayState, &displayState, NULL);
+			STD_ASSERT_ALWAYS(err == KErrNone, EPluginPanicHalSetDisplayState);
+			}
+		}
+	
+	iScreen=aScreen;
+	}
+
+void CDisplayPolicy::NewAppModesAvailable()
+	{
+	//This notification allows the list to be first populated after Wserv has finished initialising itself
+	//It also allows for the WServ debug method CWsScreenDevice::SetCurrentScreenModeAttributes
+	GetAppModeList();	//get the app size mode list again because some settings have changed
+	}
+
+void CDisplayPolicy::GetModeInfoL(const MWsScreenConfigList& aList,TInt aIndex,TPoint& aOffset,TSize& aSize,TAppMode& aMode)const
+	{
+	aOffset=aList.OriginL(aIndex);
+	aSize=aList.ScreenModeSizeInPixelsL(aIndex);
+	aMode.iPixels=TRect(aOffset,aSize);
+	aMode.iTwips=aList.ScreenModeSizeInTwipsL(aIndex);
+	aMode.iOrientations=aList.AvailableOrientationsL(aIndex);
+	}
+
+void CDisplayPolicy::GetAppModeList()
+	{
+	if (iScreen)
+		{
+		iSmallestAppMode = KErrNotFound;
+		iSmallestAppSize = TSize(10000,10000);
+		MWsScreenConfigList* screenConfigList=iScreen->ObjectInterface<MWsScreenConfigList>();
+		iNumNormalAppModes=0;
+		TSize largestAppMode;
+		if (screenConfigList)
+			{
+			RArray<TInt> goodModeIndices;
+			if (screenConfigList->GetScreenSizeModeList(goodModeIndices)!=KErrNone)
+				{
+				//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
+				iAppModes.Reserve(goodModeIndices.Count());
+				
+				//iScreenIniFile: First time in, it should be a good pointer from which to extract the basicFlags
+				//Repeat calls only update the values inside app mode list entries, and the ini file should not be read again. 
+				//Specify some basic flags by reading ini file for this screen number?
+				TInt basicFlags=0;
+				
+				//Our demo policy uses the app mode list to generate a list of virtual resolutions.
+				
+				for (TInt modeIndex=0;modeIndex<goodModeIndices.Count();modeIndex++)
+					{
+					TInt modeNum=goodModeIndices[modeIndex];
+					TAppMode mode;
+					TSize size;
+					TPoint offset;
+					mode.iFlags=basicFlags;
+					TRAP_IGNORE(mode.iFlags|=screenConfigList->ModeFlagsL(modeNum)); //we know modeNum is valid-wont leave
+					//any further flags to read from ini file for this appmode on this screen number?
+	
+					//Probably should ignore modes flagged with Hal or Dynamic
+					// at the moment we want all modes in the list! 
+	
+					TInt err = KErrNone;
+					TRAP(err,GetModeInfoL(*screenConfigList,goodModeIndices[modeIndex],offset,size,mode));
+					if (err == KErrNone)	//should never fail - we never ask for info for a bad mode
+						{
+						if (1<<CFbsBitGc::EGraphicsOrientationRotated90&mode.iOrientations 
+								|| 1<<CFbsBitGc::EGraphicsOrientationRotated270&mode.iOrientations)
+							{	//flip rect and twips
+							mode.iPixels = TRect(mode.iPixels.iTl.iY,mode.iPixels.iTl.iX,mode.iPixels.iBr.iY,mode.iPixels.iBr.iX);
+							mode.iTwips = TSize(mode.iTwips.iHeight,mode.iTwips.iWidth);
+							}
+						mode.iModeIndex=modeNum;
+						if (modeIndex==iAppModes.Count())
+							{
+							iAppModes.Append(mode);	//can't fail if reserve succeeded
+							}
+						else if (modeIndex<iAppModes.Count())
+							{
+							iAppModes[modeIndex]=mode;	//update - wserv implementation means order never changes.
+							}
+						//This is to help policy code decide what the minimum buffer size should be 
+						//Switching between modes requiring smaller screen area than this will not invoke memory reallocation, so will not fail.
+						//Perhaps an implementation would also consider the current lowest physical resolution as a guide.
+						//The HAL mode may be significantly larger than the app modes require
+						if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
+							{
+							TSize borderedSize=offset.AsSize()+size;
+							if (borderedSize.iWidth>largestAppMode.iWidth)
+								largestAppMode.iWidth=borderedSize.iWidth;
+							if (borderedSize.iHeight>largestAppMode.iHeight)
+								largestAppMode.iHeight=borderedSize.iHeight;
+							iNumNormalAppModes++;
+							}
+						
+						//find the smallest appmode. this will be used when display is disconnected
+						if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
+							{
+							TSize borderedSize=offset.AsSize()+size;
+							if(borderedSize.iWidth*borderedSize.iHeight < iSmallestAppSize.iWidth*iSmallestAppSize.iHeight)
+								{
+								iSmallestAppSize = borderedSize;
+								iSmallestAppMode = modeNum;
+								}
+							}
+						}
+						
+					}
+				}
+			goodModeIndices.Close();
+			}
+		iMinUiBufferSize=largestAppMode;
+		}
+	iScreenIniFile=NULL;
+	}
+
+TInt CDisplayPolicy::MapCompositionToUi(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
+	{
+	// only scaling is involved in mapping from composition to UI
+	// no offset change
+	TFraction widthFraction;
+	TFraction heightFraction;
+	if (	iCompositionSizePixels.iWidth<=0
+		||	iUiSizePixels.iWidth<=0
+		||	iCompositionSizePixels.iHeight<=0
+		||	iUiSizePixels.iHeight<=0)
+		{
+		aTarget=aSource;
+		return KErrNotReady;
+		}
+	if(aIsReverseMapping)
+		{
+		//Ui to composition
+		widthFraction.iNumer = iCompositionSizePixels.iWidth;
+		widthFraction.iDenom = iUiSizePixels.iWidth;
+		heightFraction.iNumer = iCompositionSizePixels.iHeight;
+		heightFraction.iDenom = iUiSizePixels.iHeight;
+		}
+	else
+		{
+		//composition to ui
+		widthFraction.iNumer = iUiSizePixels.iWidth;
+		widthFraction.iDenom = iCompositionSizePixels.iWidth;
+		heightFraction.iNumer = iUiSizePixels.iHeight;
+		heightFraction.iDenom = iCompositionSizePixels.iHeight;
+		}
+	
+	aTarget.iTl.iX = widthFraction * aSource.iTl.iX;
+	aTarget.iBr.iX = widthFraction * aSource.iBr.iX;
+	aTarget.iTl.iY = heightFraction * aSource.iTl.iY;
+	aTarget.iBr.iY = heightFraction * aSource.iBr.iY;
+	return KErrNone;
+	}
+
+void CDisplayPolicy::MapUiToApplication(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
+	{
+	// only offset is involved in mapping from Ui to App
+	// no scaling
+	TPoint offset = iAppSizePixels.iTl;;
+	
+	if(aIsReverseMapping)
+		{
+		//App to ui
+		aTarget.iTl = aSource.iTl + offset;
+		aTarget.iBr = aSource.iBr + offset;
+		}
+	else
+		{
+		//Ui to App
+		aTarget.iTl = aSource.iTl - offset;
+		aTarget.iBr = aSource.iBr - offset;
+		}
+	
+	}
+
+TInt CDisplayPolicy::MapUiToDSA(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const 
+	{
+	//only offset is involved in mapping from Ui to DSA
+	//no scaling
+	TPoint dsaOffset(0, 0);
+	
+	MWsScreenConfig *screenConfig = iScreen->ObjectInterface<MWsScreenConfig>();
+	if(screenConfig)
+		{
+		dsaOffset = screenConfig->Origin();
+		}
+	TRect rectInApp;
+	if(aIsReverseMapping)
+		{
+		//DSA to ui
+		//DSA to App first
+		rectInApp.iTl = aSource.iTl - dsaOffset;
+		rectInApp.iBr = aSource.iBr - dsaOffset;
+		//then app to UI
+		MapUiToApplication(rectInApp, aTarget, ETrue);
+		}
+	else
+		{
+		//Ui to DSA
+		//Ui to App first
+		MapUiToApplication(aSource, rectInApp, EFalse);
+		//then app to DSA
+		aTarget.iTl = rectInApp.iTl + dsaOffset;
+		aTarget.iBr = rectInApp.iBr + dsaOffset;
+		}
+	return KErrNone;
+	}
+TInt CDisplayPolicy::MapCoordinates(TCoordinateSpace aSourceSpace, const TRect& aSource, TCoordinateSpace aTargetSpace, TRect& aTarget) const
+	{
+	TInt returnCode=KErrNone;
+	switch (aSourceSpace)
+		{
+		case ECompositionSpace:
+			{
+			if(aTargetSpace == ECompositionSpace)
+				{
+				aTarget = aSource;
+				}
+			else if(aTargetSpace == EFullScreenSpace)
+				{
+				//composition to Ui
+				returnCode=MapCompositionToUi(aSource, aTarget, EFalse);
+				}
+			else if(aTargetSpace == EApplicationSpace)
+				{
+				//composition to App
+				TRect rectInUi;
+				returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
+				MapUiToApplication(rectInUi, aTarget, EFalse);
+				}
+			else if(aTargetSpace == EDirectScreenAccessSpace)
+				{
+				//composition to DSA
+				TRect rectInUi;
+				returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
+				if(returnCode < 0)
+					break;
+				returnCode=MapUiToDSA(rectInUi, aTarget, EFalse);
+				}
+			else
+				{
+				return KErrNotSupported;
+				}
+			}
+			break;
+		case EFullScreenSpace:
+			{
+			if(aTargetSpace == ECompositionSpace)
+				{
+				//Ui to composition
+				returnCode=MapCompositionToUi(aSource, aTarget, ETrue);
+				}
+			else if(aTargetSpace == EFullScreenSpace)
+				{
+				aTarget = aSource;
+				}
+			else if(aTargetSpace == EApplicationSpace)
+				{
+				//Ui to app
+				MapUiToApplication(aSource, aTarget, EFalse);
+				}
+			else if(aTargetSpace == EDirectScreenAccessSpace)
+				{
+				//Ui to DSA
+				returnCode = MapUiToDSA(aSource, aTarget, EFalse);
+				}
+			else
+				{
+				return KErrNotSupported;
+				}
+			}
+			break;
+		case EApplicationSpace:
+			{
+			if(aTargetSpace == ECompositionSpace)
+				{
+				//App to composition
+				TRect rectInUi;
+				MapUiToApplication(aSource, rectInUi, ETrue);
+				returnCode=MapCompositionToUi(rectInUi, aTarget, ETrue);
+				}
+			else if(aTargetSpace == EFullScreenSpace)
+				{
+				//App to Ui
+				MapUiToApplication(aSource, aTarget, ETrue);
+				}
+			else if(aTargetSpace == EApplicationSpace)
+				{
+				aTarget = aSource;
+				}
+			else if(aTargetSpace == EDirectScreenAccessSpace)
+				{
+				//App to DSA
+				TRect rectInUi;
+				MapUiToApplication(aSource, rectInUi, ETrue);
+				returnCode = MapUiToDSA(rectInUi, aTarget, EFalse);
+				}
+			else
+				{
+				return KErrNotSupported;
+				}
+			}
+			break;
+		case EDirectScreenAccessSpace:
+			{
+			if(aTargetSpace == ECompositionSpace)
+				{
+				//DSA to composition
+				TRect rectInUi;
+				returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
+				if(returnCode < KErrNone)
+					break;
+				returnCode = MapCompositionToUi(rectInUi, aTarget, ETrue);
+				}
+			else if(aTargetSpace == EFullScreenSpace)
+				{
+				//DSA to Ui
+				returnCode = MapUiToDSA(aSource, aTarget, ETrue);
+				}
+			else if(aTargetSpace == EApplicationSpace)
+				{
+				//DSA to app
+				TRect rectInUi;
+				returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
+				MapUiToApplication(rectInUi, aTarget, EFalse);
+				}
+			else if(aTargetSpace == EDirectScreenAccessSpace)
+				{
+				aTarget = aSource;
+				}
+			else
+				{
+				return KErrNotSupported;
+				}
+			break;
+			}
+		default:
+			returnCode= KErrNotSupported;
+		}
+	return returnCode;
+	}
+
+CDisplayPolicy::TFraction::TFraction():iNumer(0),iDenom(1)
+	{}
+
+TInt CDisplayPolicy::TFraction::operator*(TInt aInt) const
+	{
+	if (iDenom == 0 || iNumer == 0 || aInt == 0)
+		{
+		return 0;
+		}
+	TInt aNumer = iNumer<<1;
+	TInt aDenom = iDenom;
+	TInt returnValue = (aNumer*aInt)/aDenom;
+	returnValue ++;
+	return returnValue>>1;
+	}
+
+void	CDisplayPolicy::CalculateMinBufferSize(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aConnectionStatus)
+	{
+	iConnectionStatus = aConnectionStatus;
+	//preq2102: aResolutions is likely to be changed (in future)
+	if(iUiScaling == ENone)
+		{
+		//this function is currently only used with no scaling
+		//should not be called when display is disconnected
+		//with scaling iMinUiBufferSize is calculated in CDisplayPolicy::GetAppModeList()
+		TSize largestPhysicalRes = iMinUiBufferSize;		
+		for(TInt i = 0;i < aResolutions.Count(); i++)
+			{
+			if(aResolutions[i].iPixelSize.iWidth > largestPhysicalRes.iWidth)
+				{
+				largestPhysicalRes.iWidth = aResolutions[i].iPixelSize.iWidth;
+				}
+			if(aResolutions[i].iPixelSize.iHeight > largestPhysicalRes.iHeight)
+				{
+				largestPhysicalRes.iHeight = aResolutions[i].iPixelSize.iHeight;
+				}
+			}
+		
+		iMinUiBufferSize = largestPhysicalRes;
+		}
+	}
+
+void	CDisplayPolicy::AdjustStageBufferSize(const TSize& /*aOldSize*/,TSize& aNewSize)
+	{
+	if (iMinUiBufferSize.iWidth==0)
+		{
+		//just in case, should never happen
+		iMinUiBufferSize=TSize(1,1);	
+		}
+		
+	if ((aNewSize.iWidth == 0 || aNewSize.iHeight == 0
+			|| iConnectionStatus <= 0) && iUiScaling != ENone 
+			&& iSmallestAppMode >= 0) // if detached or turned off (iUiScaling != ENone) and smallestAppMode is found
+		{
+		aNewSize = iSmallestAppSize;
+		return;
+		}
+	 	 			
+	if (aNewSize.iWidth < iMinUiBufferSize.iWidth)
+		{
+		aNewSize.iWidth = iMinUiBufferSize.iWidth;
+		}
+	if (aNewSize.iHeight < iMinUiBufferSize.iHeight)
+		{
+		aNewSize.iHeight = iMinUiBufferSize.iHeight;
+		}
+	}
+
+void CDisplayPolicy::AddVirtualResolutionCount(TInt& aDisplayCount) const 
+	{
+	if (iUiScaling != ENone && aDisplayCount>0)
+		{
+		aDisplayCount += iNumNormalAppModes;
+		}
+	} 
+
+TInt CDisplayPolicy::AddVirtualResolutions(RArray<MDisplayControlBase::TResolution>& aResolutions) const
+	{
+	if (aResolutions.Count()==0 || iUiScaling == ENone)
+		{
+		return KErrNone;
+		}
+	if (aResolutions.Count()==1 && aResolutions[0].iPixelSize==TSize(0,0))
+		{
+		return KErrNone;
+		}
+		
+	TInt appModeCount = iAppModes.Count();
+	if (appModeCount == 0)
+		{
+		return KErrNone;
+		}
+	TInt resolutionCount = aResolutions.Count();
+	TInt error = aResolutions.Reserve(iNumNormalAppModes + resolutionCount);
+	if (error < KErrNone)
+		{
+		aResolutions.Reset();
+		return error;	//could fail to reserve if out of memory 
+		}
+	for (TInt appMode = 0; appMode < appModeCount; appMode++)
+		{
+		if (!(iAppModes[appMode].iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
+			{
+			MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
+			aResolutions.Append(virtualResolution);
+			}
+		}
+	return KErrNone;
+	}
+
+MDisplayControlBase::TResolution CDisplayPolicy::AppModeToResolution(RArray<MDisplayControlBase::TResolution>& aResolutions,TInt appMode)const
+	{
+	TAppMode mode = iAppModes[appMode];
+	TBool notComplete = ETrue;
+	TInt bestIndex;
+	TInt bestScale;
+	MDisplayControlBase::TResolution tempResolution(TSize(0,0),TSize(0,0));
+	TSize appBestSize;
+	while (notComplete)
+		{
+		TBool modeFit = FindVirtualMode(aResolutions,mode,appBestSize,bestIndex,bestScale);
+		
+		TSize uiSize;
+		if (iUiScaling == EInteger || iUiScaling == EIsotropic)
+			{
+			uiSize = ResolutionSize(aResolutions,appBestSize,bestIndex,bestScale);
+			}
+		else if (iUiScaling == EAnisotropic)
+			{
+			TBool swapAxis = EFalse;
+			TBool fitsAppMode = EFalse;
+			while (!fitsAppMode)
+				{
+				if (iAppModes[appMode].iFlags&MWsScreenConfigList::ETwipsSpecified)
+					{
+					//virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
+					//calculate based on twips
+					uiSize = ResolutionSizeFromTwips(aResolutions,appMode,appBestSize,bestIndex,swapAxis);
+					}
+				else
+					{
+					//assume square pixels
+					//virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
+					uiSize = ResolutionSizeFromAssumedTwips(aResolutions,appBestSize,bestIndex,swapAxis,bestScale);
+					}
+				
+				//if pixelsize found is larger than resolution mode its designed for, try scaling using other axis
+				if (uiSize.iWidth > aResolutions[bestIndex].iPixelSize.iWidth ||
+						uiSize.iHeight > aResolutions[bestIndex].iPixelSize.iHeight)
+					{
+					if (!modeFit)	//no other mode it could fit, to avoid infinite loop,say it fits the mode - will be scaled down
+						{
+						fitsAppMode = ETrue;
+						}
+					else
+						{
+						STD_ASSERT_DEBUG(swapAxis == EFalse, EPluginPanicTemp);
+						swapAxis = ETrue;
+						}
+					}
+				else
+					{
+					fitsAppMode = ETrue;
+					}
+				}
+			//if pixelsize found does not fit app mode, must retry with an appmode larger than the one found
+			if (uiSize.iWidth < iAppModes[appMode].iPixels.iBr.iX ||
+					uiSize.iHeight < iAppModes[appMode].iPixels.iBr.iY)
+				{
+				mode.iPixels.iBr.iX = aResolutions[bestIndex].iPixelSize.iWidth+1;
+				mode.iPixels.iBr.iY = aResolutions[bestIndex].iPixelSize.iHeight+1;
+				continue;
+				}
+			}
+
+		//MDisplayControlBase::TResolution virtualResolution(TSize(0,0),TSize(0,0));
+		
+		//only supports rotations supported by both sizemode and hardware
+		tempResolution.iFlags = iAppModes[appMode].iOrientations&aResolutions[bestIndex].iFlags.iFlags;
+		tempResolution.iFlags.Set(MDisplayControlBase::TResolution::EIsVirtual);
+		tempResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
+		tempResolution.iPixelSize = uiSize;
+
+		notComplete = EFalse;	//found a resolution that fits!
+		}
+	return tempResolution;
+	}
+
+TBool CDisplayPolicy::MatchConfigToResolutions(const RArray<MDisplayControlBase::TResolution>& aResolutions,
+		const TDisplayConfiguration& aConfig, TInt aStartIndex, TInt& aResolutionIndex)const
+	{
+	if (aStartIndex < 0 || aStartIndex >= aResolutions.Count())
+		{
+		return EFalse;
+		}
+	aResolutionIndex = -1;
+	for (TInt i = aStartIndex; i < aResolutions.Count(); i++)
+		{
+		if (aConfig.IsDefined(TDisplayConfigurationBase::EResolution))
+			{
+			TSize resolution;
+			aConfig.GetResolution(resolution);
+			if (resolution != aResolutions[i].iPixelSize)
+				{
+				continue;
+				}
+			}
+		if (aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
+			{
+			TSize twips;
+			aConfig.GetResolutionTwips(twips);
+			if (twips != aResolutions[i].iTwipsSize)
+				{
+				continue;
+				}
+			}
+		
+		if (aConfig.IsDefined(TDisplayConfigurationBase::ERotation))
+			{
+			TDisplayConfiguration1::TRotation rotation;
+			aConfig.GetRotation(rotation);
+			if (aResolutions[i].iFlags.IsClear(rotation))
+				{
+				continue;
+				}
+			}
+		aResolutionIndex = i;
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+/*
+	Checks if specified appmode is compatible with TResolution specified
+	Returns ETrue if succeeded (and fills aConfig with TResolution
+	Return EFalse if they are not compatible (will not touch the config) 
+*/
+TBool CDisplayPolicy::SetConfigToResolution(TInt aAppMode, MDisplayControlBase::TResolution aResolution, TDisplayConfiguration& aConfig)const
+	{
+	//find intersection of appmode and hardware rotations
+	TDisplayConfiguration1::TRotation configRotation;
+	TInt compatibleRotations;
+	if (aConfig.GetRotation(configRotation))
+		{
+		compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF&(1<<configRotation);
+		}
+	else
+		{
+		compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF;
+		}
+
+	if (compatibleRotations > 0)
+		{	//set first compatible rotation we find
+		if (1<<CFbsBitGc::EGraphicsOrientationNormal & compatibleRotations)
+			{
+			aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
+			}
+		else if (1<<CFbsBitGc::EGraphicsOrientationRotated90 & compatibleRotations)
+			{
+			aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
+			}
+		else if (1<<CFbsBitGc::EGraphicsOrientationRotated180 & compatibleRotations)
+			{
+			aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
+			}
+		else
+			{
+			aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
+			}
+		aConfig.SetResolution(aResolution.iPixelSize);
+		aConfig.SetResolutionTwips(aResolution.iTwipsSize);
+		return ETrue;
+		}
+
+	return EFalse;
+	}
+
+TInt CDisplayPolicy::GetSizeModeConfiguration(RArray<MDisplayControlBase::TResolution>& aResolutions,
+		TInt aScreenSizeMode, TDisplayConfiguration& aConfig, TRect& aSizeModePosition) const
+	{
+	//find appMode corresponding to screensizemode
+	TInt appMode;
+	TInt appModeCount = iAppModes.Count();
+	for (appMode = 0; appMode < appModeCount; appMode++)
+		{
+		if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
+			{
+			break;
+			}
+		}
+	if (appModeCount == appMode)
+		{
+		return KErrArgument;	//invalid screen size mode
+		}
+	if (!aConfig.IsDefined(TDisplayConfigurationBase::EResolution)&&
+			!aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
+		{
+		if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
+			{
+			TSize resSize = iCompositionSizePixels;
+			TSize twipsSize = iCompositionSizeTwips;
+			if (iLastCompositionRotation&TDisplayConfiguration::ERotation90CW ||
+					iLastCompositionRotation&TDisplayConfiguration::ERotation270CW)
+				{
+				TInt tempVal = resSize.iWidth;
+				resSize.iWidth = resSize.iHeight;
+				resSize.iHeight = tempVal;
+				tempVal = twipsSize.iWidth;
+				twipsSize.iWidth = twipsSize.iHeight;
+				twipsSize.iHeight = tempVal;
+				}
+			aConfig.SetResolution(resSize);
+			aConfig.SetResolutionTwips(twipsSize);
+			}
+		else
+			{
+			MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
+			aConfig.SetResolution(virtualResolution.iPixelSize);
+			aConfig.SetResolutionTwips(virtualResolution.iTwipsSize);
+			}
+		}
+
+	//check config is valid from set of resolutions (inc virtual)
+	TInt error = AddVirtualResolutions(aResolutions);
+	if (error < KErrNone)
+		{
+		return error;
+		}
+	TInt startIndex=0;
+	while (startIndex < aResolutions.Count())
+		{
+		TInt resolutionIndex;
+		TBool boolError = MatchConfigToResolutions(aResolutions,aConfig,startIndex,resolutionIndex);
+		if (boolError == EFalse)
+			{
+			return KErrArgument;
+			}
+		
+		//if is larger than current app mode and same rotation,we have found a match and can break;
+		TBool boolSet = SetConfigToResolution(appMode,aResolutions[resolutionIndex],aConfig);
+		if (boolSet)
+			{	//new configuration is compatible with app mode and has been set
+			//center appmode within the UI
+			if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
+				{
+				aSizeModePosition = aResolutions[resolutionIndex].iPixelSize;
+				}
+			else
+				{
+				CenteredAppInUi(aResolutions[resolutionIndex].iPixelSize,iAppModes[appMode].iPixels,aSizeModePosition);
+				}
+			
+			TDisplayConfiguration::TRotation tempRot;
+			aConfig.GetRotation(tempRot);
+			if (tempRot&1)
+				{
+				aSizeModePosition = TRect(aSizeModePosition.iTl.iY,aSizeModePosition.iTl.iX,
+						aSizeModePosition.iBr.iY,aSizeModePosition.iBr.iX);
+				}
+
+			return KErrNone;
+			}
+		//otherwise
+		startIndex = resolutionIndex+1;	//match found will not fit current size mode, continue looking
+		if (startIndex == aResolutions.Count())
+			{
+			return KErrArgument;
+			}
+		}
+	STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
+	return KErrGeneral;	//shouldnt be able to get here
+	}
+
+void CDisplayPolicy::CenteredAppInUi(const TSize& aUiSize,const TRect& aAppExtent,TRect& aSizeModePosition) const
+	{
+	if (aUiSize.iWidth > aAppExtent.Width())
+		{
+		aSizeModePosition.iTl.iX = (aUiSize.iWidth - aAppExtent.Width()) / 2;
+		if (aSizeModePosition.iTl.iX < aAppExtent.iTl.iX)
+			{	//we want to obey screenmode offset as a minumum, so cannot center on this axis
+			aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
+			aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
+			}
+		else
+			{
+			aSizeModePosition.iBr.iX = aSizeModePosition.iTl.iX + aAppExtent.Width();
+			}
+		}
+	else
+		{
+		aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
+		aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
+		}
+	
+	if (aUiSize.iHeight > aAppExtent.Height())
+		{
+		aSizeModePosition.iTl.iY = (aUiSize.iHeight - aAppExtent.Height()) / 2;
+		if (aSizeModePosition.iTl.iY < aAppExtent.iTl.iY)
+			{	//we want to obey screenmode offset as a minumum, so cannot center on this axis
+			aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
+			aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
+			}
+		else
+			{
+			aSizeModePosition.iBr.iY = aSizeModePosition.iTl.iY + aAppExtent.Width();
+			}
+		}
+	else
+		{
+		aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
+		aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
+		}
+	}
+
+TInt CDisplayPolicy::GetSizeModeConfiguration(TInt aScreenSizeMode,TDisplayConfiguration& aConfig, TRect& aSizeModePosition)
+	{
+	//This function is used when display is disconnected. Set UI size same as app mode. We don't care about rotation
+	
+	//find appMode corresponding to screensizemode
+	TInt appMode;
+	TInt appModeCount = iAppModes.Count();
+	for (appMode = 0; appMode < appModeCount; appMode++)
+		{
+		if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
+			{
+			break;
+			}
+		}
+	if (appModeCount == appMode)
+		{
+		return KErrArgument;	//invalid screen size mode
+		}
+	
+	if (1<<CFbsBitGc::EGraphicsOrientationRotated90&iAppModes[appMode].iOrientations 
+			|| 1<<CFbsBitGc::EGraphicsOrientationRotated270&iAppModes[appMode].iOrientations)
+		{//width and height were already flipped on construction. we need to flip it back
+		TRect appRect = iAppModes[appMode].iPixels;
+		TRect uiResRect(appRect.iTl.iX, appRect.iTl.iY, appRect.iBr.iY, appRect.iBr.iX);
+		aConfig.SetResolution(uiResRect.Size());
+		}
+	else
+		{
+		aConfig.SetResolution(iAppModes[appMode].iPixels.iBr.AsSize());
+		}
+	
+	CFbsBitGc::TGraphicsOrientation cFbsOrientation=CFbsBitGc::EGraphicsOrientationNormal;
+	//we know aScreenSizeMode is valid-OrientationL wont leave
+	TRAP_IGNORE(cFbsOrientation=iScreen->ObjectInterface<MWsScreenConfigList>()->OrientationL(aScreenSizeMode));
+	aConfig.SetRotation(TDisplayConfiguration::TRotation(cFbsOrientation));
+	aSizeModePosition = iAppModes[appMode].iPixels;
+	return KErrNone;
+	}
+
+TBool CDisplayPolicy::SettingConfiguration(const RArray<MDisplayControlBase::TResolution>& aResolutions,TDisplayConfiguration& aConfig)const
+	{	//converts configuration to appmode
+	if (iUiScaling == ENone)
+		{
+		if (aConfig.IsDefined(aConfig.EResolution))
+			{
+			TSize res;
+			aConfig.GetResolution(res);
+			TInt index;
+			for (index=0;index<aResolutions.Count();index++)
+				{
+				if  (aResolutions[index].iPixelSize == res)
+					{
+					break;
+					}
+				}
+			if (index == aResolutions.Count())
+				{	//failed to validate the resolution
+				aConfig.Clear(aConfig.EResolution);
+				}
+			}
+		return EFalse;
+		}
+	
+	
+	TAppMode appMode;
+	
+	TBool set;
+	TRect zeroRect (0,0,0,0);
+	TSize zeroSize (0,0);
+	TSize size;
+	set = aConfig.GetResolution(size);
+	appMode.iPixels = set ? size : zeroRect;
+	
+	set = aConfig.GetResolutionTwips(size);
+	appMode.iTwips = set ? size : zeroSize;
+	TDisplayConfiguration::TRotation flags;
+	set = aConfig.GetRotation(flags);	//grr orientation again
+	appMode.iOrientations = set? flags : 0;	//will set the specific rotation
+	
+	TInt index=0;
+	TInt scale=0;
+	TSize bestAppSize;
+	FindVirtualMode(aResolutions,appMode,bestAppSize,index,scale);
+	
+	//set aConfig to resolution returned
+	aConfig.SetResolution(aResolutions[index].iPixelSize);
+	aConfig.SetResolutionTwips(aResolutions[index].iTwipsSize);
+	if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotationNormalSupported)
+			&& appMode.iOrientations == TDisplayConfiguration::ERotationNormal)
+		{
+		aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
+		}
+	else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation90Supported)
+			&& appMode.iOrientations == TDisplayConfiguration::ERotation90CW)
+		{
+		aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
+		}
+	else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation180Supported)
+			&& appMode.iOrientations == TDisplayConfiguration::ERotation180)
+		{
+		aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
+		}
+	else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation270Supported)
+			&& appMode.iOrientations == TDisplayConfiguration::ERotation270CW)
+		{
+		aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
+		}
+	else
+		{
+		STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
+		return EFalse;	
+		}
+	return ETrue;
+	}
+
+void CDisplayPolicy::SetCompositionInfo (const TDisplayConfiguration& aCompositionConfig,
+		const TDisplayConfiguration& aUiConfig)
+	{
+	TDisplayConfiguration::TRotation rotation;
+	TSize sizePixels;
+	TSize sizeTwips;
+	if (aCompositionConfig.GetResolution(sizePixels))
+		{
+		aCompositionConfig.GetResolutionTwips(sizeTwips);
+		if(aCompositionConfig.IsDefined(TDisplayConfiguration::ERotation))
+			{
+			aCompositionConfig.GetRotation(rotation);
+			iLastCompositionRotation=rotation;
+			if(rotation & TDisplayConfiguration::ERotation90CW)
+				{
+				//swap width and height to be stored in iCompositionSizePixels and iCompositionSizeTwips
+				iCompositionSizePixels.iHeight = sizePixels.iWidth;
+				iCompositionSizePixels.iWidth = sizePixels.iHeight;
+				iCompositionSizeTwips.iHeight = sizeTwips.iWidth;
+				iCompositionSizeTwips.iWidth = sizeTwips.iHeight;
+				}
+			else
+				{
+				iCompositionSizePixels = sizePixels;
+				iCompositionSizeTwips = sizeTwips;
+				}
+			}
+		else
+			{
+			iCompositionSizePixels = sizePixels;
+			iCompositionSizeTwips = sizeTwips;
+			}
+		
+		aUiConfig.GetResolution(sizePixels);
+		aUiConfig.GetResolutionTwips(sizeTwips);
+		if(aUiConfig.IsDefined(TDisplayConfiguration::ERotation))
+			{
+			aUiConfig.GetRotation(rotation);
+			iLastUiRotation=rotation;
+			if(rotation & TDisplayConfiguration::ERotation90CW)
+				{
+				//swap width and height to be stored in iUiSizePixels and iAppSizeTwips
+				iUiSizePixels.iHeight = sizePixels.iWidth;
+				iUiSizePixels.iWidth = sizePixels.iHeight;
+				iAppSizeTwips.iHeight = sizeTwips.iWidth;
+				iAppSizeTwips.iWidth = sizeTwips.iHeight;
+				}
+			else
+				{
+				iUiSizePixels = sizePixels;
+				iAppSizeTwips = sizeTwips;
+				}
+			}
+		else
+			{
+			iUiSizePixels = sizePixels;
+			iAppSizeTwips = sizeTwips;
+			}	
+		}
+	else
+		{
+		if (aUiConfig.GetRotation(rotation))
+			{
+			if ((rotation^iLastUiRotation)&TDisplayConfiguration::ERotation90CW)
+				{
+				TInt swapHeight=iUiSizePixels.iHeight;
+				iUiSizePixels.iHeight = iUiSizePixels.iWidth;
+				iUiSizePixels.iWidth = swapHeight;
+				}
+			iLastUiRotation=rotation;
+			}
+		
+		if (aCompositionConfig.GetRotation(rotation))
+			{
+			if ((rotation^iLastCompositionRotation)&TDisplayConfiguration::ERotation90CW)
+				{
+				TInt swapHeight=iCompositionSizePixels.iHeight;
+				iCompositionSizePixels.iHeight = iCompositionSizePixels.iWidth;
+				iCompositionSizePixels.iWidth = swapHeight;
+				swapHeight=iCompositionSizeTwips.iHeight;
+				iCompositionSizeTwips.iHeight = iCompositionSizeTwips.iWidth;
+				iCompositionSizeTwips.iWidth = swapHeight;
+				}
+			iLastCompositionRotation=rotation;
+			}
+		}
+	}
+
+void CDisplayPolicy::SetSizeModeExtent(TRect& aExtent, TBitFlags32 /*aContext*/)
+	{
+	iAppSizePixels = aExtent;
+	}
+
+/**	Finds the best resolution that the specified appmode can fit into
+	Returns ETrue if it fits a mode
+	Returns EFalse to warn if it didnt fit in that mode
+	For both, it will set index and scale to the best fit
+*/
+TBool CDisplayPolicy::FindVirtualMode(const RArray<MDisplayControlBase::TResolution>& aResolutions,
+		const CDisplayPolicy::TAppMode& aAppMode,TSize& aFullAppModeSize,TInt& aIndex,TInt& aBestScale) const
+	{
+	const TInt KBestFit = 0x7000000; //a really big number that should get reduced during the search.
+	TInt bestFit=KBestFit;
+	TInt resDiffX;
+	TInt resDiffY;
+	TInt64 biggestArea(0);
+	TInt biggestAreaIndex=0;
+	TBool fullAppSize;
+	
+	if (aAppMode.iPixels.iTl.iX == 0 && aAppMode.iPixels.iTl.iY == 0)
+		{	//no point trying again with a border on only 2 sides, as there is no border anyway!
+		fullAppSize = EFalse;
+		}
+	else
+		{
+		fullAppSize = ETrue;
+		}
+	aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX + aAppMode.iPixels.iTl.iX,
+			aAppMode.iPixels.iBr.iY + aAppMode.iPixels.iTl.iY);	//try fitting with border all 4 sides
+
+	while(1)
+		{
+		//find hardware mode that fits this best
+		for (TInt j = 0; j < aResolutions.Count(); j++)
+			{
+			if (bestFit == 0)
+				{	//found a perfect match
+				break;
+				}
+			if (aResolutions[j].iFlags[MDisplayControlBase::TResolution::EIsVirtual])
+				{	//ignore virtual resolutions
+				continue;
+				}
+			TInt maxScaling = 1;
+			if (iUiScaling == EInteger)
+				{
+				maxScaling = 4;
+				}
+			for (TInt k = maxScaling; k > 0; k--)
+				{	//for every avalable integer scale
+				if (bestFit == 0)
+					{	//found a perfect match
+					break;
+					}
+				TInt64 area=TInt64(aResolutions[j].iPixelSize.iWidth)*aResolutions[j].iPixelSize.iHeight;
+				if (area>biggestArea)
+					{
+					biggestArea=area;
+					biggestAreaIndex=j;
+					}
+				resDiffX = (aResolutions[j].iPixelSize.iWidth/k) - aFullAppModeSize.iWidth;
+				resDiffY = (aResolutions[j].iPixelSize.iHeight/k) - aFullAppModeSize.iHeight;
+
+				if (resDiffX < 0 || resDiffY < 0)
+					{	//app mode too large for this resolution
+					continue;
+					}
+				if (resDiffX+resDiffY < bestFit)
+					{
+					aIndex = j;
+					bestFit =  resDiffX + resDiffY;
+					aBestScale = k;
+					continue;
+					}
+				}
+			}
+		if (bestFit != KBestFit)
+			{	//it found the best resolution to scale into
+			break;
+			}
+		else if (fullAppSize == EFalse)
+			{	//app does not fit any resolution, it will have to be scaled down to fit
+			aIndex=biggestAreaIndex;
+			aBestScale=1;
+			return EFalse;
+			}
+		else
+			{
+			aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX,
+					aAppMode.iPixels.iBr.iY);	//try fitting with border only top and left
+			fullAppSize = EFalse;
+			}
+		}
+	return ETrue;
+	}
+
+TSize CDisplayPolicy::ResolutionSize(RArray<MDisplayControlBase::TResolution>& aResolutions,
+		const TSize aBestAppSize,TInt aIndex, TInt aScale) const
+	{
+	TSize returnSize;
+	
+	if (iUiScaling == EInteger)	//only supporting integral scales
+		{	//just calculate the scaled resolution
+		returnSize = TSize(aResolutions[aIndex].iPixelSize.iWidth/aScale,
+				aResolutions[aIndex].iPixelSize.iHeight/aScale);
+		}
+	else
+		{	//find which axis scales best, create virtual resolution that fits this axis
+		TFraction bestAxisAsFraction;
+
+		if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > 
+				(TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
+			{	//y axis scales closest
+			bestAxisAsFraction.iNumer = aResolutions[aIndex].iPixelSize.iWidth;
+			bestAxisAsFraction.iDenom = aResolutions[aIndex].iPixelSize.iHeight;
+			returnSize = TSize(bestAxisAsFraction*aBestAppSize.iHeight,
+					aBestAppSize.iHeight);
+			}
+		else
+			{	//x axis scales closest
+			bestAxisAsFraction.iNumer = aResolutions[aIndex].iPixelSize.iHeight;
+			bestAxisAsFraction.iDenom = aResolutions[aIndex].iPixelSize.iWidth;
+			returnSize = TSize(aBestAppSize.iWidth,
+					bestAxisAsFraction*aBestAppSize.iWidth);
+			}
+		}
+	return returnSize;
+	}
+
+TSize CDisplayPolicy::GetUiResolution()
+	{
+	return this->iUiSizePixels;
+	}
+
+TSize CDisplayPolicy::GetUiResolutionAsTwips() const
+    {
+    return this->iCompositionSizeTwips;
+    }
+
+TRect CDisplayPolicy::GetPolicyAppMode()
+	{
+	return iAppSizePixels;
+	}
+
+TSize CDisplayPolicy::ResolutionSizeFromTwips(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aAppMode, const TSize& aBestAppSize,
+		TInt aIndex,TBool aSwapAxis) const
+	{
+	TSize returnSize;
+	TFraction tempFraction;
+	TBool yScalesClosest;
+	
+	if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > (TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
+		{	//y axis scales closest
+		yScalesClosest = aSwapAxis?EFalse:ETrue;
+		}
+	else
+		{	//x axis scales closest
+		yScalesClosest = aSwapAxis?ETrue:EFalse;
+		}
+	
+	if (yScalesClosest)
+		{	//y axis scales closest
+		tempFraction.iNumer = aBestAppSize.iHeight;	//bordered app height in pixels
+		tempFraction.iDenom = iAppModes[aAppMode].iPixels.iBr.iY - iAppModes[aAppMode].iPixels.iTl.iY;	//app height in pixels
+		TInt uiYTwips=tempFraction*iAppModes[aAppMode].iTwips.iHeight;	//bordered app height in twips
+		
+		tempFraction.iNumer = aResolutions[aIndex].iTwipsSize.iWidth;	//display width in twips
+		tempFraction.iDenom = aResolutions[aIndex].iTwipsSize.iHeight;	//display height in twips
+		TInt uiXTwips=tempFraction*uiYTwips;	//virtual width in twips
+		
+		tempFraction.iNumer = iAppModes[aAppMode].iPixels.iBr.iX - iAppModes[aAppMode].iPixels.iTl.iX;	//app width in pixels
+		tempFraction.iDenom = iAppModes[aAppMode].iTwips.iWidth;	//display width in twips
+		TInt uiXPixels=tempFraction*uiXTwips;	//virtual width in pixels
+		
+		returnSize.iWidth = uiXPixels;
+		returnSize.iHeight = aBestAppSize.iHeight;
+		}
+	else
+		{	//x axis scales closest
+		tempFraction.iNumer = aBestAppSize.iWidth;	//bordered app width in pixels
+		tempFraction.iDenom = iAppModes[aAppMode].iPixels.iBr.iX - iAppModes[aAppMode].iPixels.iTl.iX;	//app width in pixels
+		TInt uiXTwips=tempFraction*iAppModes[aAppMode].iTwips.iWidth;	//bordered app width in twips
+		
+		tempFraction.iNumer = aResolutions[aIndex].iTwipsSize.iHeight;	//display height in twips
+		tempFraction.iDenom = aResolutions[aIndex].iTwipsSize.iWidth;	//display width in twips
+		TInt uiYTwips=tempFraction*uiXTwips;	//virtual height in twips
+		
+		tempFraction.iNumer = iAppModes[aAppMode].iPixels.iBr.iY - iAppModes[aAppMode].iPixels.iTl.iY;	//app height in pixels
+		tempFraction.iDenom = iAppModes[aAppMode].iTwips.iHeight;	//display height in twips
+		TInt uiYPixels=tempFraction*uiYTwips;	//virtual width in pixels
+		
+		returnSize.iWidth = aBestAppSize.iWidth;
+		returnSize.iHeight = uiYPixels;
+		}
+	
+	return returnSize;
+	}
+
+TSize CDisplayPolicy::ResolutionSizeFromAssumedTwips(RArray<MDisplayControlBase::TResolution>& aResolutions,const TSize& aBestAppSize,
+		TInt aIndex,TBool aSwapAxis, TInt aScale) const
+	{
+	TSize returnSize;
+	
+	if (iUiScaling == EInteger)	//only supporting integral scales
+		{	//just calculate the scaled resolution
+		returnSize = TSize(aResolutions[aIndex].iTwipsSize.iWidth/aScale,
+				aResolutions[aIndex].iTwipsSize.iHeight/aScale);
+		}
+	else
+		{	//find which axis scales best, create virtual resolution that fits this axis
+		TBool yScalesClosest;
+		TFraction bestAxisAsFraction;
+		
+		if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > 
+				(TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
+			{	//y axis scales closest
+			yScalesClosest = aSwapAxis?EFalse:ETrue;
+			}
+		else
+			{	//x axis scales closest
+			yScalesClosest = aSwapAxis?ETrue:EFalse;
+			}
+		
+		if (yScalesClosest)
+			{	//y axis scales closest
+			bestAxisAsFraction.iNumer = aResolutions[aIndex].iTwipsSize.iWidth;
+			bestAxisAsFraction.iDenom = aResolutions[aIndex].iTwipsSize.iHeight;
+			returnSize = TSize(bestAxisAsFraction*aBestAppSize.iHeight,
+					aBestAppSize.iHeight);
+			}
+		else
+			{	//x axis scales closest
+			bestAxisAsFraction.iNumer = aResolutions[aIndex].iTwipsSize.iHeight;
+			bestAxisAsFraction.iDenom = aResolutions[aIndex].iTwipsSize.iWidth;
+			returnSize = TSize(aBestAppSize.iWidth,
+					bestAxisAsFraction*aBestAppSize.iWidth);
+			}
+		}
+	return returnSize;
+	}
+
+TInt CDisplayPolicy::MinSizedModeIndex()
+	{
+	return iSmallestAppMode;
+	}
+
+TInt CDisplayPolicy::SuitableAppMode(MWsDisplayPolicy::TDisplayStatus aSituation)
+	{
+	switch(aSituation)
+		{
+		case MWsDisplayPolicy::EAttach:
+			{
+			return iLastAppMode;
+			}
+		case MWsDisplayPolicy::EDetach:
+			{
+			return MinSizedModeIndex();
+			}
+		default:
+			return KErrNotSupported;
+		}
+
+	}
+
+void CDisplayPolicy::SetLastAppMode(TInt aMode)
+	{
+	iLastAppMode = aMode;
+	}
+
+