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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <graphics/wsgraphicdrawerinterface.h>
19 #include "displaypolicy.h"
22 CDisplayPolicy::CDisplayPolicy():iLastAppMode(KErrNotReady),iSmallestAppMode(KErrNotReady)
24 // No implementation required
27 CDisplayPolicy::~CDisplayPolicy()
31 CDisplayPolicy* CDisplayPolicy::NewLC(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
33 CDisplayPolicy* self = new (ELeave)CDisplayPolicy();
34 CleanupStack::PushL(self);
35 self->ConstructL(aEnv,aScreen,aScreenNumber);
39 CDisplayPolicy* CDisplayPolicy::NewL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
41 CDisplayPolicy* self=CDisplayPolicy::NewLC(aEnv,aScreen,aScreenNumber);
42 CleanupStack::Pop(); // self;
46 void CDisplayPolicy::ConstructL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
48 iScreenIniFile=aEnv->ObjectInterface<MWsIniFile>();
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");
59 TPtrC scalingModeName;
60 if (iScreenIniFile->FindVar(aScreenNumber,KScale,scalingModeName))
62 if (scalingModeName == KScaleInteger)
64 iUiScaling = EInteger;
66 else if (scalingModeName == KScaleIsotropic)
68 iUiScaling = EIsotropic;
70 else if (scalingModeName == KScaleAnisotropic)
72 iUiScaling = EAnisotropic;
76 if (iScreenIniFile->FindVar(aScreenNumber,KScreenDisconnected))
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);
88 void CDisplayPolicy::NewAppModesAvailable()
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
95 void CDisplayPolicy::GetModeInfoL(const MWsScreenConfigList& aList,TInt aIndex,TPoint& aOffset,TSize& aSize,TAppMode& aMode)const
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);
104 void CDisplayPolicy::GetAppModeList()
108 iSmallestAppMode = KErrNotFound;
109 iSmallestAppSize = TSize(10000,10000);
110 MWsScreenConfigList* screenConfigList=iScreen->ObjectInterface<MWsScreenConfigList>();
111 iNumNormalAppModes=0;
112 TSize largestAppMode;
113 if (screenConfigList)
115 RArray<TInt> goodModeIndices;
116 if (screenConfigList->GetScreenSizeModeList(goodModeIndices)!=KErrNone)
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());
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?
126 //Our demo policy uses the app mode list to generate a list of virtual resolutions.
128 for (TInt modeIndex=0;modeIndex<goodModeIndices.Count();modeIndex++)
130 TInt modeNum=goodModeIndices[modeIndex];
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?
138 //Probably should ignore modes flagged with Hal or Dynamic
139 // at the moment we want all modes in the list!
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
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);
151 mode.iModeIndex=modeNum;
152 if (modeIndex==iAppModes.Count())
154 iAppModes.Append(mode); //can't fail if reserve succeeded
156 else if (modeIndex<iAppModes.Count())
158 iAppModes[modeIndex]=mode; //update - wserv implementation means order never changes.
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)))
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++;
174 //find the smallest appmode. this will be used when display is disconnected
175 if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
177 TSize borderedSize=offset.AsSize()+size;
178 if(borderedSize.iWidth*borderedSize.iHeight < iSmallestAppSize.iWidth*iSmallestAppSize.iHeight)
180 iSmallestAppSize = borderedSize;
181 iSmallestAppMode = modeNum;
188 goodModeIndices.Close();
190 iMinUiBufferSize=largestAppMode;
195 TInt CDisplayPolicy::MapCompositionToUi(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
197 // only scaling is involved in mapping from composition to UI
199 TFraction widthFraction;
200 TFraction heightFraction;
201 if ( iCompositionSizePixels.iWidth<=0
202 || iUiSizePixels.iWidth<=0
203 || iCompositionSizePixels.iHeight<=0
204 || iUiSizePixels.iHeight<=0)
209 if(aIsReverseMapping)
212 widthFraction.iNumer = iCompositionSizePixels.iWidth;
213 widthFraction.iDenom = iUiSizePixels.iWidth;
214 heightFraction.iNumer = iCompositionSizePixels.iHeight;
215 heightFraction.iDenom = iUiSizePixels.iHeight;
220 widthFraction.iNumer = iUiSizePixels.iWidth;
221 widthFraction.iDenom = iCompositionSizePixels.iWidth;
222 heightFraction.iNumer = iUiSizePixels.iHeight;
223 heightFraction.iDenom = iCompositionSizePixels.iHeight;
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;
233 void CDisplayPolicy::MapUiToApplication(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
235 // only offset is involved in mapping from Ui to App
237 TPoint offset = iAppSizePixels.iTl;;
239 if(aIsReverseMapping)
242 aTarget.iTl = aSource.iTl + offset;
243 aTarget.iBr = aSource.iBr + offset;
248 aTarget.iTl = aSource.iTl - offset;
249 aTarget.iBr = aSource.iBr - offset;
254 TInt CDisplayPolicy::MapUiToDSA(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
256 //only offset is involved in mapping from Ui to DSA
258 TPoint dsaOffset(0, 0);
260 MWsScreenConfig *screenConfig = iScreen->ObjectInterface<MWsScreenConfig>();
263 dsaOffset = screenConfig->Origin();
266 if(aIsReverseMapping)
270 rectInApp.iTl = aSource.iTl - dsaOffset;
271 rectInApp.iBr = aSource.iBr - dsaOffset;
273 MapUiToApplication(rectInApp, aTarget, ETrue);
279 MapUiToApplication(aSource, rectInApp, EFalse);
281 aTarget.iTl = rectInApp.iTl + dsaOffset;
282 aTarget.iBr = rectInApp.iBr + dsaOffset;
286 TInt CDisplayPolicy::MapCoordinates(TCoordinateSpace aSourceSpace, const TRect& aSource, TCoordinateSpace aTargetSpace, TRect& aTarget) const
288 TInt returnCode=KErrNone;
289 switch (aSourceSpace)
291 case ECompositionSpace:
293 if(aTargetSpace == ECompositionSpace)
297 else if(aTargetSpace == EFullScreenSpace)
300 returnCode=MapCompositionToUi(aSource, aTarget, EFalse);
302 else if(aTargetSpace == EApplicationSpace)
306 returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
307 MapUiToApplication(rectInUi, aTarget, EFalse);
309 else if(aTargetSpace == EDirectScreenAccessSpace)
313 returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
316 returnCode=MapUiToDSA(rectInUi, aTarget, EFalse);
320 return KErrNotSupported;
324 case EFullScreenSpace:
326 if(aTargetSpace == ECompositionSpace)
329 returnCode=MapCompositionToUi(aSource, aTarget, ETrue);
331 else if(aTargetSpace == EFullScreenSpace)
335 else if(aTargetSpace == EApplicationSpace)
338 MapUiToApplication(aSource, aTarget, EFalse);
340 else if(aTargetSpace == EDirectScreenAccessSpace)
343 returnCode = MapUiToDSA(aSource, aTarget, EFalse);
347 return KErrNotSupported;
351 case EApplicationSpace:
353 if(aTargetSpace == ECompositionSpace)
357 MapUiToApplication(aSource, rectInUi, ETrue);
358 returnCode=MapCompositionToUi(rectInUi, aTarget, ETrue);
360 else if(aTargetSpace == EFullScreenSpace)
363 MapUiToApplication(aSource, aTarget, ETrue);
365 else if(aTargetSpace == EApplicationSpace)
369 else if(aTargetSpace == EDirectScreenAccessSpace)
373 MapUiToApplication(aSource, rectInUi, ETrue);
374 returnCode = MapUiToDSA(rectInUi, aTarget, EFalse);
378 return KErrNotSupported;
382 case EDirectScreenAccessSpace:
384 if(aTargetSpace == ECompositionSpace)
388 returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
389 if(returnCode < KErrNone)
391 returnCode = MapCompositionToUi(rectInUi, aTarget, ETrue);
393 else if(aTargetSpace == EFullScreenSpace)
396 returnCode = MapUiToDSA(aSource, aTarget, ETrue);
398 else if(aTargetSpace == EApplicationSpace)
402 returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
403 MapUiToApplication(rectInUi, aTarget, EFalse);
405 else if(aTargetSpace == EDirectScreenAccessSpace)
411 return KErrNotSupported;
416 returnCode= KErrNotSupported;
421 CDisplayPolicy::TFraction::TFraction():iNumer(0),iDenom(1)
424 TInt CDisplayPolicy::TFraction::operator*(TInt aInt) const
426 if (iDenom == 0 || iNumer == 0 || aInt == 0)
430 TInt aNumer = iNumer<<1;
431 TInt aDenom = iDenom;
432 TInt returnValue = (aNumer*aInt)/aDenom;
434 return returnValue>>1;
437 void CDisplayPolicy::CalculateMinBufferSize(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aConnectionStatus)
439 iConnectionStatus = aConnectionStatus;
440 //preq2102: aResolutions is likely to be changed (in future)
441 if(iUiScaling == ENone)
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++)
449 if(aResolutions[i].iPixelSize.iWidth > largestPhysicalRes.iWidth)
451 largestPhysicalRes.iWidth = aResolutions[i].iPixelSize.iWidth;
453 if(aResolutions[i].iPixelSize.iHeight > largestPhysicalRes.iHeight)
455 largestPhysicalRes.iHeight = aResolutions[i].iPixelSize.iHeight;
459 iMinUiBufferSize = largestPhysicalRes;
463 void CDisplayPolicy::AdjustStageBufferSize(const TSize& /*aOldSize*/,TSize& aNewSize)
465 if (iMinUiBufferSize.iWidth==0)
467 //just in case, should never happen
468 iMinUiBufferSize=TSize(1,1);
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
475 aNewSize = iSmallestAppSize;
479 if (aNewSize.iWidth < iMinUiBufferSize.iWidth)
481 aNewSize.iWidth = iMinUiBufferSize.iWidth;
483 if (aNewSize.iHeight < iMinUiBufferSize.iHeight)
485 aNewSize.iHeight = iMinUiBufferSize.iHeight;
489 void CDisplayPolicy::AddVirtualResolutionCount(TInt& aDisplayCount) const
491 if (iUiScaling != ENone && aDisplayCount>0)
493 aDisplayCount += iNumNormalAppModes;
497 TInt CDisplayPolicy::AddVirtualResolutions(RArray<MDisplayControlBase::TResolution>& aResolutions) const
499 if (aResolutions.Count()==0 || iUiScaling == ENone)
503 if (aResolutions.Count()==1 && aResolutions[0].iPixelSize==TSize(0,0))
508 TInt appModeCount = iAppModes.Count();
509 if (appModeCount == 0)
513 TInt resolutionCount = aResolutions.Count();
514 TInt error = aResolutions.Reserve(iNumNormalAppModes + resolutionCount);
515 if (error < KErrNone)
517 aResolutions.Reset();
518 return error; //could fail to reserve if out of memory
520 for (TInt appMode = 0; appMode < appModeCount; appMode++)
522 if (!(iAppModes[appMode].iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
524 MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
525 aResolutions.Append(virtualResolution);
531 MDisplayControlBase::TResolution CDisplayPolicy::AppModeToResolution(RArray<MDisplayControlBase::TResolution>& aResolutions,TInt appMode)const
533 TAppMode mode = iAppModes[appMode];
534 TBool notComplete = ETrue;
537 MDisplayControlBase::TResolution tempResolution(TSize(0,0),TSize(0,0));
541 TBool modeFit = FindVirtualMode(aResolutions,mode,appBestSize,bestIndex,bestScale);
544 if (iUiScaling == EInteger || iUiScaling == EIsotropic)
546 uiSize = ResolutionSize(aResolutions,appBestSize,bestIndex,bestScale);
548 else if (iUiScaling == EAnisotropic)
550 TBool swapAxis = EFalse;
551 TBool fitsAppMode = EFalse;
554 if (iAppModes[appMode].iFlags&MWsScreenConfigList::ETwipsSpecified)
556 //virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
557 //calculate based on twips
558 uiSize = ResolutionSizeFromTwips(aResolutions,appMode,appBestSize,bestIndex,swapAxis);
562 //assume square pixels
563 //virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
564 uiSize = ResolutionSizeFromAssumedTwips(aResolutions,appBestSize,bestIndex,swapAxis,bestScale);
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)
571 if (!modeFit) //no other mode it could fit, to avoid infinite loop,say it fits the mode - will be scaled down
577 STD_ASSERT_DEBUG(swapAxis == EFalse, EPluginPanicTemp);
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)
590 mode.iPixels.iBr.iX = aResolutions[bestIndex].iPixelSize.iWidth+1;
591 mode.iPixels.iBr.iY = aResolutions[bestIndex].iPixelSize.iHeight+1;
596 //MDisplayControlBase::TResolution virtualResolution(TSize(0,0),TSize(0,0));
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;
604 notComplete = EFalse; //found a resolution that fits!
606 return tempResolution;
609 TBool CDisplayPolicy::MatchConfigToResolutions(const RArray<MDisplayControlBase::TResolution>& aResolutions,
610 const TDisplayConfiguration& aConfig, TInt aStartIndex, TInt& aResolutionIndex)const
612 if (aStartIndex < 0 || aStartIndex >= aResolutions.Count())
616 aResolutionIndex = -1;
617 for (TInt i = aStartIndex; i < aResolutions.Count(); i++)
619 if (aConfig.IsDefined(TDisplayConfigurationBase::EResolution))
622 aConfig.GetResolution(resolution);
623 if (resolution != aResolutions[i].iPixelSize)
628 if (aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
631 aConfig.GetResolutionTwips(twips);
632 if (twips != aResolutions[i].iTwipsSize)
638 if (aConfig.IsDefined(TDisplayConfigurationBase::ERotation))
640 TDisplayConfiguration1::TRotation rotation;
641 aConfig.GetRotation(rotation);
642 if (aResolutions[i].iFlags.IsClear(rotation))
647 aResolutionIndex = i;
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)
658 TBool CDisplayPolicy::SetConfigToResolution(TInt aAppMode, MDisplayControlBase::TResolution aResolution, TDisplayConfiguration& aConfig)const
660 //find intersection of appmode and hardware rotations
661 TDisplayConfiguration1::TRotation configRotation;
662 TInt compatibleRotations;
663 if (aConfig.GetRotation(configRotation))
665 compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF&(1<<configRotation);
669 compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF;
672 if (compatibleRotations > 0)
673 { //set first compatible rotation we find
674 if (1<<CFbsBitGc::EGraphicsOrientationNormal & compatibleRotations)
676 aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
678 else if (1<<CFbsBitGc::EGraphicsOrientationRotated90 & compatibleRotations)
680 aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
682 else if (1<<CFbsBitGc::EGraphicsOrientationRotated180 & compatibleRotations)
684 aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
688 aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
690 aConfig.SetResolution(aResolution.iPixelSize);
691 aConfig.SetResolutionTwips(aResolution.iTwipsSize);
698 TInt CDisplayPolicy::GetSizeModeConfiguration(RArray<MDisplayControlBase::TResolution>& aResolutions,
699 TInt aScreenSizeMode, TDisplayConfiguration& aConfig, TRect& aSizeModePosition) const
701 //find appMode corresponding to screensizemode
703 TInt appModeCount = iAppModes.Count();
704 for (appMode = 0; appMode < appModeCount; appMode++)
706 if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
711 if (appModeCount == appMode)
713 return KErrArgument; //invalid screen size mode
715 if (!aConfig.IsDefined(TDisplayConfigurationBase::EResolution)&&
716 !aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
718 if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
720 TSize resSize = iCompositionSizePixels;
721 TSize twipsSize = iCompositionSizeTwips;
722 if (iLastCompositionRotation&TDisplayConfiguration::ERotation90CW ||
723 iLastCompositionRotation&TDisplayConfiguration::ERotation270CW)
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;
732 aConfig.SetResolution(resSize);
733 aConfig.SetResolutionTwips(twipsSize);
737 MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
738 aConfig.SetResolution(virtualResolution.iPixelSize);
739 aConfig.SetResolutionTwips(virtualResolution.iTwipsSize);
743 //check config is valid from set of resolutions (inc virtual)
744 TInt error = AddVirtualResolutions(aResolutions);
745 if (error < KErrNone)
750 while (startIndex < aResolutions.Count())
752 TInt resolutionIndex;
753 TBool boolError = MatchConfigToResolutions(aResolutions,aConfig,startIndex,resolutionIndex);
754 if (boolError == EFalse)
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);
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)
766 aSizeModePosition = aResolutions[resolutionIndex].iPixelSize;
770 CenteredAppInUi(aResolutions[resolutionIndex].iPixelSize,iAppModes[appMode].iPixels,aSizeModePosition);
773 TDisplayConfiguration::TRotation tempRot;
774 aConfig.GetRotation(tempRot);
777 aSizeModePosition = TRect(aSizeModePosition.iTl.iY,aSizeModePosition.iTl.iX,
778 aSizeModePosition.iBr.iY,aSizeModePosition.iBr.iX);
784 startIndex = resolutionIndex+1; //match found will not fit current size mode, continue looking
785 if (startIndex == aResolutions.Count())
790 STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
791 return KErrGeneral; //shouldnt be able to get here
794 void CDisplayPolicy::CenteredAppInUi(const TSize& aUiSize,const TRect& aAppExtent,TRect& aSizeModePosition) const
796 if (aUiSize.iWidth > aAppExtent.Width())
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;
806 aSizeModePosition.iBr.iX = aSizeModePosition.iTl.iX + aAppExtent.Width();
811 aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
812 aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
815 if (aUiSize.iHeight > aAppExtent.Height())
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;
825 aSizeModePosition.iBr.iY = aSizeModePosition.iTl.iY + aAppExtent.Width();
830 aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
831 aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
835 TInt CDisplayPolicy::GetSizeModeConfiguration(TInt aScreenSizeMode,TDisplayConfiguration& aConfig, TRect& aSizeModePosition)
837 //This function is used when display is disconnected. Set UI size same as app mode. We don't care about rotation
839 //find appMode corresponding to screensizemode
841 TInt appModeCount = iAppModes.Count();
842 for (appMode = 0; appMode < appModeCount; appMode++)
844 if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
849 if (appModeCount == appMode)
851 return KErrArgument; //invalid screen size mode
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());
863 aConfig.SetResolution(iAppModes[appMode].iPixels.iBr.AsSize());
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;
874 TBool CDisplayPolicy::SettingConfiguration(const RArray<MDisplayControlBase::TResolution>& aResolutions,TDisplayConfiguration& aConfig)const
875 { //converts configuration to appmode
876 if (iUiScaling == ENone)
878 if (aConfig.IsDefined(aConfig.EResolution))
881 aConfig.GetResolution(res);
883 for (index=0;index<aResolutions.Count();index++)
885 if (aResolutions[index].iPixelSize == res)
890 if (index == aResolutions.Count())
891 { //failed to validate the resolution
892 aConfig.Clear(aConfig.EResolution);
902 TRect zeroRect (0,0,0,0);
903 TSize zeroSize (0,0);
905 set = aConfig.GetResolution(size);
906 appMode.iPixels = set ? size : zeroRect;
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
917 FindVirtualMode(aResolutions,appMode,bestAppSize,index,scale);
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)
925 aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
927 else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation90Supported)
928 && appMode.iOrientations == TDisplayConfiguration::ERotation90CW)
930 aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
932 else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation180Supported)
933 && appMode.iOrientations == TDisplayConfiguration::ERotation180)
935 aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
937 else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation270Supported)
938 && appMode.iOrientations == TDisplayConfiguration::ERotation270CW)
940 aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
944 STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
950 void CDisplayPolicy::SetCompositionInfo (const TDisplayConfiguration& aCompositionConfig,
951 const TDisplayConfiguration& aUiConfig)
953 TDisplayConfiguration::TRotation rotation;
956 if (aCompositionConfig.GetResolution(sizePixels))
958 aCompositionConfig.GetResolutionTwips(sizeTwips);
959 if(aCompositionConfig.IsDefined(TDisplayConfiguration::ERotation))
961 aCompositionConfig.GetRotation(rotation);
962 iLastCompositionRotation=rotation;
963 if(rotation & TDisplayConfiguration::ERotation90CW)
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;
973 iCompositionSizePixels = sizePixels;
974 iCompositionSizeTwips = sizeTwips;
979 iCompositionSizePixels = sizePixels;
980 iCompositionSizeTwips = sizeTwips;
983 aUiConfig.GetResolution(sizePixels);
984 aUiConfig.GetResolutionTwips(sizeTwips);
985 if(aUiConfig.IsDefined(TDisplayConfiguration::ERotation))
987 aUiConfig.GetRotation(rotation);
988 iLastUiRotation=rotation;
989 if(rotation & TDisplayConfiguration::ERotation90CW)
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;
999 iUiSizePixels = sizePixels;
1000 iAppSizeTwips = sizeTwips;
1005 iUiSizePixels = sizePixels;
1006 iAppSizeTwips = sizeTwips;
1011 if (aUiConfig.GetRotation(rotation))
1013 if ((rotation^iLastUiRotation)&TDisplayConfiguration::ERotation90CW)
1015 TInt swapHeight=iUiSizePixels.iHeight;
1016 iUiSizePixels.iHeight = iUiSizePixels.iWidth;
1017 iUiSizePixels.iWidth = swapHeight;
1019 iLastUiRotation=rotation;
1022 if (aCompositionConfig.GetRotation(rotation))
1024 if ((rotation^iLastCompositionRotation)&TDisplayConfiguration::ERotation90CW)
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;
1033 iLastCompositionRotation=rotation;
1038 void CDisplayPolicy::SetSizeModeExtent(TRect& aExtent, TBitFlags32 /*aContext*/)
1040 iAppSizePixels = aExtent;
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
1048 TBool CDisplayPolicy::FindVirtualMode(const RArray<MDisplayControlBase::TResolution>& aResolutions,
1049 const CDisplayPolicy::TAppMode& aAppMode,TSize& aFullAppModeSize,TInt& aIndex,TInt& aBestScale) const
1051 const TInt KBestFit = 0x7000000; //a really big number that should get reduced during the search.
1052 TInt bestFit=KBestFit;
1055 TInt64 biggestArea(0);
1056 TInt biggestAreaIndex=0;
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;
1065 fullAppSize = ETrue;
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
1072 //find hardware mode that fits this best
1073 for (TInt j = 0; j < aResolutions.Count(); j++)
1076 { //found a perfect match
1079 if (aResolutions[j].iFlags[MDisplayControlBase::TResolution::EIsVirtual])
1080 { //ignore virtual resolutions
1083 TInt maxScaling = 1;
1084 if (iUiScaling == EInteger)
1088 for (TInt k = maxScaling; k > 0; k--)
1089 { //for every avalable integer scale
1091 { //found a perfect match
1094 TInt64 area=TInt64(aResolutions[j].iPixelSize.iWidth)*aResolutions[j].iPixelSize.iHeight;
1095 if (area>biggestArea)
1100 resDiffX = (aResolutions[j].iPixelSize.iWidth/k) - aFullAppModeSize.iWidth;
1101 resDiffY = (aResolutions[j].iPixelSize.iHeight/k) - aFullAppModeSize.iHeight;
1103 if (resDiffX < 0 || resDiffY < 0)
1104 { //app mode too large for this resolution
1107 if (resDiffX+resDiffY < bestFit)
1110 bestFit = resDiffX + resDiffY;
1116 if (bestFit != KBestFit)
1117 { //it found the best resolution to scale into
1120 else if (fullAppSize == EFalse)
1121 { //app does not fit any resolution, it will have to be scaled down to fit
1122 aIndex=biggestAreaIndex;
1128 aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX,
1129 aAppMode.iPixels.iBr.iY); //try fitting with border only top and left
1130 fullAppSize = EFalse;
1136 TSize CDisplayPolicy::ResolutionSize(RArray<MDisplayControlBase::TResolution>& aResolutions,
1137 const TSize aBestAppSize,TInt aIndex, TInt aScale) const
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);
1147 { //find which axis scales best, create virtual resolution that fits this axis
1148 TFraction bestAxisAsFraction;
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);
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);
1169 TSize CDisplayPolicy::GetUiResolution()
1171 return this->iUiSizePixels;
1174 TSize CDisplayPolicy::GetUiResolutionAsTwips() const
1176 return this->iCompositionSizeTwips;
1179 TRect CDisplayPolicy::GetPolicyAppMode()
1181 return iAppSizePixels;
1184 TSize CDisplayPolicy::ResolutionSizeFromTwips(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aAppMode, const TSize& aBestAppSize,
1185 TInt aIndex,TBool aSwapAxis) const
1188 TFraction tempFraction;
1189 TBool yScalesClosest;
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;
1196 { //x axis scales closest
1197 yScalesClosest = aSwapAxis?ETrue:EFalse;
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
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
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
1214 returnSize.iWidth = uiXPixels;
1215 returnSize.iHeight = aBestAppSize.iHeight;
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
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
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
1231 returnSize.iWidth = aBestAppSize.iWidth;
1232 returnSize.iHeight = uiYPixels;
1238 TSize CDisplayPolicy::ResolutionSizeFromAssumedTwips(RArray<MDisplayControlBase::TResolution>& aResolutions,const TSize& aBestAppSize,
1239 TInt aIndex,TBool aSwapAxis, TInt aScale) const
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);
1249 { //find which axis scales best, create virtual resolution that fits this axis
1250 TBool yScalesClosest;
1251 TFraction bestAxisAsFraction;
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;
1259 { //x axis scales closest
1260 yScalesClosest = aSwapAxis?ETrue:EFalse;
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);
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);
1281 TInt CDisplayPolicy::MinSizedModeIndex()
1283 return iSmallestAppMode;
1286 TInt CDisplayPolicy::SuitableAppMode(MWsDisplayPolicy::TDisplayStatus aSituation)
1290 case MWsDisplayPolicy::EAttach:
1292 return iLastAppMode;
1294 case MWsDisplayPolicy::EDetach:
1296 return MinSizedModeIndex();
1299 return KErrNotSupported;
1304 void CDisplayPolicy::SetLastAppMode(TInt aMode)
1306 iLastAppMode = aMode;