--- /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;
+ }
+
+