1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/windowing/windowserverplugins/openwfc/src/displaypolicy.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1309 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <graphics/wsgraphicdrawerinterface.h>
1.20 +#include <e32cmn.h>
1.21 +#include <u32hal.h>
1.22 +#include "displaypolicy.h"
1.23 +#include "panic.h"
1.24 +
1.25 +CDisplayPolicy::CDisplayPolicy():iLastAppMode(KErrNotReady),iSmallestAppMode(KErrNotReady)
1.26 + {
1.27 + // No implementation required
1.28 + }
1.29 +
1.30 +CDisplayPolicy::~CDisplayPolicy()
1.31 + {
1.32 + }
1.33 +
1.34 +CDisplayPolicy* CDisplayPolicy::NewLC(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
1.35 + {
1.36 + CDisplayPolicy* self = new (ELeave)CDisplayPolicy();
1.37 + CleanupStack::PushL(self);
1.38 + self->ConstructL(aEnv,aScreen,aScreenNumber);
1.39 + return self;
1.40 + }
1.41 +
1.42 +CDisplayPolicy* CDisplayPolicy::NewL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
1.43 + {
1.44 + CDisplayPolicy* self=CDisplayPolicy::NewLC(aEnv,aScreen,aScreenNumber);
1.45 + CleanupStack::Pop(); // self;
1.46 + return self;
1.47 + }
1.48 +
1.49 +void CDisplayPolicy::ConstructL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen,TInt aScreenNumber)
1.50 + {
1.51 + iScreenIniFile=aEnv->ObjectInterface<MWsIniFile>();
1.52 + if (iScreenIniFile)
1.53 + {
1.54 + _LIT(KScale,"DP_SCALING");
1.55 + //_LIT(KScaleNone,"none");
1.56 + _LIT(KScaleInteger,"integer");
1.57 + _LIT(KScaleIsotropic,"isotropic");
1.58 + _LIT(KScaleAnisotropic,"anisotropic");
1.59 + _LIT(KScreenDisconnected,"SIMULATE_STARTUP_DISCONNECTED");
1.60 +
1.61 + iUiScaling = ENone;
1.62 + TPtrC scalingModeName;
1.63 + if (iScreenIniFile->FindVar(aScreenNumber,KScale,scalingModeName))
1.64 + {
1.65 + if (scalingModeName == KScaleInteger)
1.66 + {
1.67 + iUiScaling = EInteger;
1.68 + }
1.69 + else if (scalingModeName == KScaleIsotropic)
1.70 + {
1.71 + iUiScaling = EIsotropic;
1.72 + }
1.73 + else if (scalingModeName == KScaleAnisotropic)
1.74 + {
1.75 + iUiScaling = EAnisotropic;
1.76 + }
1.77 + }
1.78 +
1.79 + if (iScreenIniFile->FindVar(aScreenNumber,KScreenDisconnected))
1.80 + {
1.81 + //Simulate starting up with this screen disconnected
1.82 + TDisplayConnectState displayState = EDisconnect;
1.83 + TInt err = UserSvr::HalFunction(EHalGroupDisplay | (aScreenNumber<<16), EDisplayHalSetDisplayState, &displayState, NULL);
1.84 + STD_ASSERT_ALWAYS(err == KErrNone, EPluginPanicHalSetDisplayState);
1.85 + }
1.86 + }
1.87 +
1.88 + iScreen=aScreen;
1.89 + }
1.90 +
1.91 +void CDisplayPolicy::NewAppModesAvailable()
1.92 + {
1.93 + //This notification allows the list to be first populated after Wserv has finished initialising itself
1.94 + //It also allows for the WServ debug method CWsScreenDevice::SetCurrentScreenModeAttributes
1.95 + GetAppModeList(); //get the app size mode list again because some settings have changed
1.96 + }
1.97 +
1.98 +void CDisplayPolicy::GetModeInfoL(const MWsScreenConfigList& aList,TInt aIndex,TPoint& aOffset,TSize& aSize,TAppMode& aMode)const
1.99 + {
1.100 + aOffset=aList.OriginL(aIndex);
1.101 + aSize=aList.ScreenModeSizeInPixelsL(aIndex);
1.102 + aMode.iPixels=TRect(aOffset,aSize);
1.103 + aMode.iTwips=aList.ScreenModeSizeInTwipsL(aIndex);
1.104 + aMode.iOrientations=aList.AvailableOrientationsL(aIndex);
1.105 + }
1.106 +
1.107 +void CDisplayPolicy::GetAppModeList()
1.108 + {
1.109 + if (iScreen)
1.110 + {
1.111 + iSmallestAppMode = KErrNotFound;
1.112 + iSmallestAppSize = TSize(10000,10000);
1.113 + MWsScreenConfigList* screenConfigList=iScreen->ObjectInterface<MWsScreenConfigList>();
1.114 + iNumNormalAppModes=0;
1.115 + TSize largestAppMode;
1.116 + if (screenConfigList)
1.117 + {
1.118 + RArray<TInt> goodModeIndices;
1.119 + if (screenConfigList->GetScreenSizeModeList(goodModeIndices)!=KErrNone)
1.120 + {
1.121 + //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
1.122 + iAppModes.Reserve(goodModeIndices.Count());
1.123 +
1.124 + //iScreenIniFile: First time in, it should be a good pointer from which to extract the basicFlags
1.125 + //Repeat calls only update the values inside app mode list entries, and the ini file should not be read again.
1.126 + //Specify some basic flags by reading ini file for this screen number?
1.127 + TInt basicFlags=0;
1.128 +
1.129 + //Our demo policy uses the app mode list to generate a list of virtual resolutions.
1.130 +
1.131 + for (TInt modeIndex=0;modeIndex<goodModeIndices.Count();modeIndex++)
1.132 + {
1.133 + TInt modeNum=goodModeIndices[modeIndex];
1.134 + TAppMode mode;
1.135 + TSize size;
1.136 + TPoint offset;
1.137 + mode.iFlags=basicFlags;
1.138 + TRAP_IGNORE(mode.iFlags|=screenConfigList->ModeFlagsL(modeNum)); //we know modeNum is valid-wont leave
1.139 + //any further flags to read from ini file for this appmode on this screen number?
1.140 +
1.141 + //Probably should ignore modes flagged with Hal or Dynamic
1.142 + // at the moment we want all modes in the list!
1.143 +
1.144 + TInt err = KErrNone;
1.145 + TRAP(err,GetModeInfoL(*screenConfigList,goodModeIndices[modeIndex],offset,size,mode));
1.146 + if (err == KErrNone) //should never fail - we never ask for info for a bad mode
1.147 + {
1.148 + if (1<<CFbsBitGc::EGraphicsOrientationRotated90&mode.iOrientations
1.149 + || 1<<CFbsBitGc::EGraphicsOrientationRotated270&mode.iOrientations)
1.150 + { //flip rect and twips
1.151 + mode.iPixels = TRect(mode.iPixels.iTl.iY,mode.iPixels.iTl.iX,mode.iPixels.iBr.iY,mode.iPixels.iBr.iX);
1.152 + mode.iTwips = TSize(mode.iTwips.iHeight,mode.iTwips.iWidth);
1.153 + }
1.154 + mode.iModeIndex=modeNum;
1.155 + if (modeIndex==iAppModes.Count())
1.156 + {
1.157 + iAppModes.Append(mode); //can't fail if reserve succeeded
1.158 + }
1.159 + else if (modeIndex<iAppModes.Count())
1.160 + {
1.161 + iAppModes[modeIndex]=mode; //update - wserv implementation means order never changes.
1.162 + }
1.163 + //This is to help policy code decide what the minimum buffer size should be
1.164 + //Switching between modes requiring smaller screen area than this will not invoke memory reallocation, so will not fail.
1.165 + //Perhaps an implementation would also consider the current lowest physical resolution as a guide.
1.166 + //The HAL mode may be significantly larger than the app modes require
1.167 + if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
1.168 + {
1.169 + TSize borderedSize=offset.AsSize()+size;
1.170 + if (borderedSize.iWidth>largestAppMode.iWidth)
1.171 + largestAppMode.iWidth=borderedSize.iWidth;
1.172 + if (borderedSize.iHeight>largestAppMode.iHeight)
1.173 + largestAppMode.iHeight=borderedSize.iHeight;
1.174 + iNumNormalAppModes++;
1.175 + }
1.176 +
1.177 + //find the smallest appmode. this will be used when display is disconnected
1.178 + if (!(mode.iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
1.179 + {
1.180 + TSize borderedSize=offset.AsSize()+size;
1.181 + if(borderedSize.iWidth*borderedSize.iHeight < iSmallestAppSize.iWidth*iSmallestAppSize.iHeight)
1.182 + {
1.183 + iSmallestAppSize = borderedSize;
1.184 + iSmallestAppMode = modeNum;
1.185 + }
1.186 + }
1.187 + }
1.188 +
1.189 + }
1.190 + }
1.191 + goodModeIndices.Close();
1.192 + }
1.193 + iMinUiBufferSize=largestAppMode;
1.194 + }
1.195 + iScreenIniFile=NULL;
1.196 + }
1.197 +
1.198 +TInt CDisplayPolicy::MapCompositionToUi(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
1.199 + {
1.200 + // only scaling is involved in mapping from composition to UI
1.201 + // no offset change
1.202 + TFraction widthFraction;
1.203 + TFraction heightFraction;
1.204 + if ( iCompositionSizePixels.iWidth<=0
1.205 + || iUiSizePixels.iWidth<=0
1.206 + || iCompositionSizePixels.iHeight<=0
1.207 + || iUiSizePixels.iHeight<=0)
1.208 + {
1.209 + aTarget=aSource;
1.210 + return KErrNotReady;
1.211 + }
1.212 + if(aIsReverseMapping)
1.213 + {
1.214 + //Ui to composition
1.215 + widthFraction.iNumer = iCompositionSizePixels.iWidth;
1.216 + widthFraction.iDenom = iUiSizePixels.iWidth;
1.217 + heightFraction.iNumer = iCompositionSizePixels.iHeight;
1.218 + heightFraction.iDenom = iUiSizePixels.iHeight;
1.219 + }
1.220 + else
1.221 + {
1.222 + //composition to ui
1.223 + widthFraction.iNumer = iUiSizePixels.iWidth;
1.224 + widthFraction.iDenom = iCompositionSizePixels.iWidth;
1.225 + heightFraction.iNumer = iUiSizePixels.iHeight;
1.226 + heightFraction.iDenom = iCompositionSizePixels.iHeight;
1.227 + }
1.228 +
1.229 + aTarget.iTl.iX = widthFraction * aSource.iTl.iX;
1.230 + aTarget.iBr.iX = widthFraction * aSource.iBr.iX;
1.231 + aTarget.iTl.iY = heightFraction * aSource.iTl.iY;
1.232 + aTarget.iBr.iY = heightFraction * aSource.iBr.iY;
1.233 + return KErrNone;
1.234 + }
1.235 +
1.236 +void CDisplayPolicy::MapUiToApplication(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
1.237 + {
1.238 + // only offset is involved in mapping from Ui to App
1.239 + // no scaling
1.240 + TPoint offset = iAppSizePixels.iTl;;
1.241 +
1.242 + if(aIsReverseMapping)
1.243 + {
1.244 + //App to ui
1.245 + aTarget.iTl = aSource.iTl + offset;
1.246 + aTarget.iBr = aSource.iBr + offset;
1.247 + }
1.248 + else
1.249 + {
1.250 + //Ui to App
1.251 + aTarget.iTl = aSource.iTl - offset;
1.252 + aTarget.iBr = aSource.iBr - offset;
1.253 + }
1.254 +
1.255 + }
1.256 +
1.257 +TInt CDisplayPolicy::MapUiToDSA(const TRect& aSource, TRect& aTarget, TBool aIsReverseMapping) const
1.258 + {
1.259 + //only offset is involved in mapping from Ui to DSA
1.260 + //no scaling
1.261 + TPoint dsaOffset(0, 0);
1.262 +
1.263 + MWsScreenConfig *screenConfig = iScreen->ObjectInterface<MWsScreenConfig>();
1.264 + if(screenConfig)
1.265 + {
1.266 + dsaOffset = screenConfig->Origin();
1.267 + }
1.268 + TRect rectInApp;
1.269 + if(aIsReverseMapping)
1.270 + {
1.271 + //DSA to ui
1.272 + //DSA to App first
1.273 + rectInApp.iTl = aSource.iTl - dsaOffset;
1.274 + rectInApp.iBr = aSource.iBr - dsaOffset;
1.275 + //then app to UI
1.276 + MapUiToApplication(rectInApp, aTarget, ETrue);
1.277 + }
1.278 + else
1.279 + {
1.280 + //Ui to DSA
1.281 + //Ui to App first
1.282 + MapUiToApplication(aSource, rectInApp, EFalse);
1.283 + //then app to DSA
1.284 + aTarget.iTl = rectInApp.iTl + dsaOffset;
1.285 + aTarget.iBr = rectInApp.iBr + dsaOffset;
1.286 + }
1.287 + return KErrNone;
1.288 + }
1.289 +TInt CDisplayPolicy::MapCoordinates(TCoordinateSpace aSourceSpace, const TRect& aSource, TCoordinateSpace aTargetSpace, TRect& aTarget) const
1.290 + {
1.291 + TInt returnCode=KErrNone;
1.292 + switch (aSourceSpace)
1.293 + {
1.294 + case ECompositionSpace:
1.295 + {
1.296 + if(aTargetSpace == ECompositionSpace)
1.297 + {
1.298 + aTarget = aSource;
1.299 + }
1.300 + else if(aTargetSpace == EFullScreenSpace)
1.301 + {
1.302 + //composition to Ui
1.303 + returnCode=MapCompositionToUi(aSource, aTarget, EFalse);
1.304 + }
1.305 + else if(aTargetSpace == EApplicationSpace)
1.306 + {
1.307 + //composition to App
1.308 + TRect rectInUi;
1.309 + returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
1.310 + MapUiToApplication(rectInUi, aTarget, EFalse);
1.311 + }
1.312 + else if(aTargetSpace == EDirectScreenAccessSpace)
1.313 + {
1.314 + //composition to DSA
1.315 + TRect rectInUi;
1.316 + returnCode=MapCompositionToUi(aSource, rectInUi, EFalse);
1.317 + if(returnCode < 0)
1.318 + break;
1.319 + returnCode=MapUiToDSA(rectInUi, aTarget, EFalse);
1.320 + }
1.321 + else
1.322 + {
1.323 + return KErrNotSupported;
1.324 + }
1.325 + }
1.326 + break;
1.327 + case EFullScreenSpace:
1.328 + {
1.329 + if(aTargetSpace == ECompositionSpace)
1.330 + {
1.331 + //Ui to composition
1.332 + returnCode=MapCompositionToUi(aSource, aTarget, ETrue);
1.333 + }
1.334 + else if(aTargetSpace == EFullScreenSpace)
1.335 + {
1.336 + aTarget = aSource;
1.337 + }
1.338 + else if(aTargetSpace == EApplicationSpace)
1.339 + {
1.340 + //Ui to app
1.341 + MapUiToApplication(aSource, aTarget, EFalse);
1.342 + }
1.343 + else if(aTargetSpace == EDirectScreenAccessSpace)
1.344 + {
1.345 + //Ui to DSA
1.346 + returnCode = MapUiToDSA(aSource, aTarget, EFalse);
1.347 + }
1.348 + else
1.349 + {
1.350 + return KErrNotSupported;
1.351 + }
1.352 + }
1.353 + break;
1.354 + case EApplicationSpace:
1.355 + {
1.356 + if(aTargetSpace == ECompositionSpace)
1.357 + {
1.358 + //App to composition
1.359 + TRect rectInUi;
1.360 + MapUiToApplication(aSource, rectInUi, ETrue);
1.361 + returnCode=MapCompositionToUi(rectInUi, aTarget, ETrue);
1.362 + }
1.363 + else if(aTargetSpace == EFullScreenSpace)
1.364 + {
1.365 + //App to Ui
1.366 + MapUiToApplication(aSource, aTarget, ETrue);
1.367 + }
1.368 + else if(aTargetSpace == EApplicationSpace)
1.369 + {
1.370 + aTarget = aSource;
1.371 + }
1.372 + else if(aTargetSpace == EDirectScreenAccessSpace)
1.373 + {
1.374 + //App to DSA
1.375 + TRect rectInUi;
1.376 + MapUiToApplication(aSource, rectInUi, ETrue);
1.377 + returnCode = MapUiToDSA(rectInUi, aTarget, EFalse);
1.378 + }
1.379 + else
1.380 + {
1.381 + return KErrNotSupported;
1.382 + }
1.383 + }
1.384 + break;
1.385 + case EDirectScreenAccessSpace:
1.386 + {
1.387 + if(aTargetSpace == ECompositionSpace)
1.388 + {
1.389 + //DSA to composition
1.390 + TRect rectInUi;
1.391 + returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
1.392 + if(returnCode < KErrNone)
1.393 + break;
1.394 + returnCode = MapCompositionToUi(rectInUi, aTarget, ETrue);
1.395 + }
1.396 + else if(aTargetSpace == EFullScreenSpace)
1.397 + {
1.398 + //DSA to Ui
1.399 + returnCode = MapUiToDSA(aSource, aTarget, ETrue);
1.400 + }
1.401 + else if(aTargetSpace == EApplicationSpace)
1.402 + {
1.403 + //DSA to app
1.404 + TRect rectInUi;
1.405 + returnCode = MapUiToDSA(aSource, rectInUi, ETrue);
1.406 + MapUiToApplication(rectInUi, aTarget, EFalse);
1.407 + }
1.408 + else if(aTargetSpace == EDirectScreenAccessSpace)
1.409 + {
1.410 + aTarget = aSource;
1.411 + }
1.412 + else
1.413 + {
1.414 + return KErrNotSupported;
1.415 + }
1.416 + break;
1.417 + }
1.418 + default:
1.419 + returnCode= KErrNotSupported;
1.420 + }
1.421 + return returnCode;
1.422 + }
1.423 +
1.424 +CDisplayPolicy::TFraction::TFraction():iNumer(0),iDenom(1)
1.425 + {}
1.426 +
1.427 +TInt CDisplayPolicy::TFraction::operator*(TInt aInt) const
1.428 + {
1.429 + if (iDenom == 0 || iNumer == 0 || aInt == 0)
1.430 + {
1.431 + return 0;
1.432 + }
1.433 + TInt aNumer = iNumer<<1;
1.434 + TInt aDenom = iDenom;
1.435 + TInt returnValue = (aNumer*aInt)/aDenom;
1.436 + returnValue ++;
1.437 + return returnValue>>1;
1.438 + }
1.439 +
1.440 +void CDisplayPolicy::CalculateMinBufferSize(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aConnectionStatus)
1.441 + {
1.442 + iConnectionStatus = aConnectionStatus;
1.443 + //preq2102: aResolutions is likely to be changed (in future)
1.444 + if(iUiScaling == ENone)
1.445 + {
1.446 + //this function is currently only used with no scaling
1.447 + //should not be called when display is disconnected
1.448 + //with scaling iMinUiBufferSize is calculated in CDisplayPolicy::GetAppModeList()
1.449 + TSize largestPhysicalRes = iMinUiBufferSize;
1.450 + for(TInt i = 0;i < aResolutions.Count(); i++)
1.451 + {
1.452 + if(aResolutions[i].iPixelSize.iWidth > largestPhysicalRes.iWidth)
1.453 + {
1.454 + largestPhysicalRes.iWidth = aResolutions[i].iPixelSize.iWidth;
1.455 + }
1.456 + if(aResolutions[i].iPixelSize.iHeight > largestPhysicalRes.iHeight)
1.457 + {
1.458 + largestPhysicalRes.iHeight = aResolutions[i].iPixelSize.iHeight;
1.459 + }
1.460 + }
1.461 +
1.462 + iMinUiBufferSize = largestPhysicalRes;
1.463 + }
1.464 + }
1.465 +
1.466 +void CDisplayPolicy::AdjustStageBufferSize(const TSize& /*aOldSize*/,TSize& aNewSize)
1.467 + {
1.468 + if (iMinUiBufferSize.iWidth==0)
1.469 + {
1.470 + //just in case, should never happen
1.471 + iMinUiBufferSize=TSize(1,1);
1.472 + }
1.473 +
1.474 + if ((aNewSize.iWidth == 0 || aNewSize.iHeight == 0
1.475 + || iConnectionStatus <= 0) && iUiScaling != ENone
1.476 + && iSmallestAppMode >= 0) // if detached or turned off (iUiScaling != ENone) and smallestAppMode is found
1.477 + {
1.478 + aNewSize = iSmallestAppSize;
1.479 + return;
1.480 + }
1.481 +
1.482 + if (aNewSize.iWidth < iMinUiBufferSize.iWidth)
1.483 + {
1.484 + aNewSize.iWidth = iMinUiBufferSize.iWidth;
1.485 + }
1.486 + if (aNewSize.iHeight < iMinUiBufferSize.iHeight)
1.487 + {
1.488 + aNewSize.iHeight = iMinUiBufferSize.iHeight;
1.489 + }
1.490 + }
1.491 +
1.492 +void CDisplayPolicy::AddVirtualResolutionCount(TInt& aDisplayCount) const
1.493 + {
1.494 + if (iUiScaling != ENone && aDisplayCount>0)
1.495 + {
1.496 + aDisplayCount += iNumNormalAppModes;
1.497 + }
1.498 + }
1.499 +
1.500 +TInt CDisplayPolicy::AddVirtualResolutions(RArray<MDisplayControlBase::TResolution>& aResolutions) const
1.501 + {
1.502 + if (aResolutions.Count()==0 || iUiScaling == ENone)
1.503 + {
1.504 + return KErrNone;
1.505 + }
1.506 + if (aResolutions.Count()==1 && aResolutions[0].iPixelSize==TSize(0,0))
1.507 + {
1.508 + return KErrNone;
1.509 + }
1.510 +
1.511 + TInt appModeCount = iAppModes.Count();
1.512 + if (appModeCount == 0)
1.513 + {
1.514 + return KErrNone;
1.515 + }
1.516 + TInt resolutionCount = aResolutions.Count();
1.517 + TInt error = aResolutions.Reserve(iNumNormalAppModes + resolutionCount);
1.518 + if (error < KErrNone)
1.519 + {
1.520 + aResolutions.Reset();
1.521 + return error; //could fail to reserve if out of memory
1.522 + }
1.523 + for (TInt appMode = 0; appMode < appModeCount; appMode++)
1.524 + {
1.525 + if (!(iAppModes[appMode].iFlags&(MWsScreenConfigList::EDynamic|MWsScreenConfigList::EHalDefault)))
1.526 + {
1.527 + MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
1.528 + aResolutions.Append(virtualResolution);
1.529 + }
1.530 + }
1.531 + return KErrNone;
1.532 + }
1.533 +
1.534 +MDisplayControlBase::TResolution CDisplayPolicy::AppModeToResolution(RArray<MDisplayControlBase::TResolution>& aResolutions,TInt appMode)const
1.535 + {
1.536 + TAppMode mode = iAppModes[appMode];
1.537 + TBool notComplete = ETrue;
1.538 + TInt bestIndex;
1.539 + TInt bestScale;
1.540 + MDisplayControlBase::TResolution tempResolution(TSize(0,0),TSize(0,0));
1.541 + TSize appBestSize;
1.542 + while (notComplete)
1.543 + {
1.544 + TBool modeFit = FindVirtualMode(aResolutions,mode,appBestSize,bestIndex,bestScale);
1.545 +
1.546 + TSize uiSize;
1.547 + if (iUiScaling == EInteger || iUiScaling == EIsotropic)
1.548 + {
1.549 + uiSize = ResolutionSize(aResolutions,appBestSize,bestIndex,bestScale);
1.550 + }
1.551 + else if (iUiScaling == EAnisotropic)
1.552 + {
1.553 + TBool swapAxis = EFalse;
1.554 + TBool fitsAppMode = EFalse;
1.555 + while (!fitsAppMode)
1.556 + {
1.557 + if (iAppModes[appMode].iFlags&MWsScreenConfigList::ETwipsSpecified)
1.558 + {
1.559 + //virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
1.560 + //calculate based on twips
1.561 + uiSize = ResolutionSizeFromTwips(aResolutions,appMode,appBestSize,bestIndex,swapAxis);
1.562 + }
1.563 + else
1.564 + {
1.565 + //assume square pixels
1.566 + //virtualResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
1.567 + uiSize = ResolutionSizeFromAssumedTwips(aResolutions,appBestSize,bestIndex,swapAxis,bestScale);
1.568 + }
1.569 +
1.570 + //if pixelsize found is larger than resolution mode its designed for, try scaling using other axis
1.571 + if (uiSize.iWidth > aResolutions[bestIndex].iPixelSize.iWidth ||
1.572 + uiSize.iHeight > aResolutions[bestIndex].iPixelSize.iHeight)
1.573 + {
1.574 + if (!modeFit) //no other mode it could fit, to avoid infinite loop,say it fits the mode - will be scaled down
1.575 + {
1.576 + fitsAppMode = ETrue;
1.577 + }
1.578 + else
1.579 + {
1.580 + STD_ASSERT_DEBUG(swapAxis == EFalse, EPluginPanicTemp);
1.581 + swapAxis = ETrue;
1.582 + }
1.583 + }
1.584 + else
1.585 + {
1.586 + fitsAppMode = ETrue;
1.587 + }
1.588 + }
1.589 + //if pixelsize found does not fit app mode, must retry with an appmode larger than the one found
1.590 + if (uiSize.iWidth < iAppModes[appMode].iPixels.iBr.iX ||
1.591 + uiSize.iHeight < iAppModes[appMode].iPixels.iBr.iY)
1.592 + {
1.593 + mode.iPixels.iBr.iX = aResolutions[bestIndex].iPixelSize.iWidth+1;
1.594 + mode.iPixels.iBr.iY = aResolutions[bestIndex].iPixelSize.iHeight+1;
1.595 + continue;
1.596 + }
1.597 + }
1.598 +
1.599 + //MDisplayControlBase::TResolution virtualResolution(TSize(0,0),TSize(0,0));
1.600 +
1.601 + //only supports rotations supported by both sizemode and hardware
1.602 + tempResolution.iFlags = iAppModes[appMode].iOrientations&aResolutions[bestIndex].iFlags.iFlags;
1.603 + tempResolution.iFlags.Set(MDisplayControlBase::TResolution::EIsVirtual);
1.604 + tempResolution.iTwipsSize = aResolutions[bestIndex].iTwipsSize;
1.605 + tempResolution.iPixelSize = uiSize;
1.606 +
1.607 + notComplete = EFalse; //found a resolution that fits!
1.608 + }
1.609 + return tempResolution;
1.610 + }
1.611 +
1.612 +TBool CDisplayPolicy::MatchConfigToResolutions(const RArray<MDisplayControlBase::TResolution>& aResolutions,
1.613 + const TDisplayConfiguration& aConfig, TInt aStartIndex, TInt& aResolutionIndex)const
1.614 + {
1.615 + if (aStartIndex < 0 || aStartIndex >= aResolutions.Count())
1.616 + {
1.617 + return EFalse;
1.618 + }
1.619 + aResolutionIndex = -1;
1.620 + for (TInt i = aStartIndex; i < aResolutions.Count(); i++)
1.621 + {
1.622 + if (aConfig.IsDefined(TDisplayConfigurationBase::EResolution))
1.623 + {
1.624 + TSize resolution;
1.625 + aConfig.GetResolution(resolution);
1.626 + if (resolution != aResolutions[i].iPixelSize)
1.627 + {
1.628 + continue;
1.629 + }
1.630 + }
1.631 + if (aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
1.632 + {
1.633 + TSize twips;
1.634 + aConfig.GetResolutionTwips(twips);
1.635 + if (twips != aResolutions[i].iTwipsSize)
1.636 + {
1.637 + continue;
1.638 + }
1.639 + }
1.640 +
1.641 + if (aConfig.IsDefined(TDisplayConfigurationBase::ERotation))
1.642 + {
1.643 + TDisplayConfiguration1::TRotation rotation;
1.644 + aConfig.GetRotation(rotation);
1.645 + if (aResolutions[i].iFlags.IsClear(rotation))
1.646 + {
1.647 + continue;
1.648 + }
1.649 + }
1.650 + aResolutionIndex = i;
1.651 + return ETrue;
1.652 + }
1.653 + return EFalse;
1.654 + }
1.655 +
1.656 +/*
1.657 + Checks if specified appmode is compatible with TResolution specified
1.658 + Returns ETrue if succeeded (and fills aConfig with TResolution
1.659 + Return EFalse if they are not compatible (will not touch the config)
1.660 +*/
1.661 +TBool CDisplayPolicy::SetConfigToResolution(TInt aAppMode, MDisplayControlBase::TResolution aResolution, TDisplayConfiguration& aConfig)const
1.662 + {
1.663 + //find intersection of appmode and hardware rotations
1.664 + TDisplayConfiguration1::TRotation configRotation;
1.665 + TInt compatibleRotations;
1.666 + if (aConfig.GetRotation(configRotation))
1.667 + {
1.668 + compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF&(1<<configRotation);
1.669 + }
1.670 + else
1.671 + {
1.672 + compatibleRotations = iAppModes[aAppMode].iOrientations&aResolution.iFlags.iFlags&0xF;
1.673 + }
1.674 +
1.675 + if (compatibleRotations > 0)
1.676 + { //set first compatible rotation we find
1.677 + if (1<<CFbsBitGc::EGraphicsOrientationNormal & compatibleRotations)
1.678 + {
1.679 + aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
1.680 + }
1.681 + else if (1<<CFbsBitGc::EGraphicsOrientationRotated90 & compatibleRotations)
1.682 + {
1.683 + aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
1.684 + }
1.685 + else if (1<<CFbsBitGc::EGraphicsOrientationRotated180 & compatibleRotations)
1.686 + {
1.687 + aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
1.688 + }
1.689 + else
1.690 + {
1.691 + aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
1.692 + }
1.693 + aConfig.SetResolution(aResolution.iPixelSize);
1.694 + aConfig.SetResolutionTwips(aResolution.iTwipsSize);
1.695 + return ETrue;
1.696 + }
1.697 +
1.698 + return EFalse;
1.699 + }
1.700 +
1.701 +TInt CDisplayPolicy::GetSizeModeConfiguration(RArray<MDisplayControlBase::TResolution>& aResolutions,
1.702 + TInt aScreenSizeMode, TDisplayConfiguration& aConfig, TRect& aSizeModePosition) const
1.703 + {
1.704 + //find appMode corresponding to screensizemode
1.705 + TInt appMode;
1.706 + TInt appModeCount = iAppModes.Count();
1.707 + for (appMode = 0; appMode < appModeCount; appMode++)
1.708 + {
1.709 + if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
1.710 + {
1.711 + break;
1.712 + }
1.713 + }
1.714 + if (appModeCount == appMode)
1.715 + {
1.716 + return KErrArgument; //invalid screen size mode
1.717 + }
1.718 + if (!aConfig.IsDefined(TDisplayConfigurationBase::EResolution)&&
1.719 + !aConfig.IsDefined(TDisplayConfigurationBase::EResolutionTwips))
1.720 + {
1.721 + if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
1.722 + {
1.723 + TSize resSize = iCompositionSizePixels;
1.724 + TSize twipsSize = iCompositionSizeTwips;
1.725 + if (iLastCompositionRotation&TDisplayConfiguration::ERotation90CW ||
1.726 + iLastCompositionRotation&TDisplayConfiguration::ERotation270CW)
1.727 + {
1.728 + TInt tempVal = resSize.iWidth;
1.729 + resSize.iWidth = resSize.iHeight;
1.730 + resSize.iHeight = tempVal;
1.731 + tempVal = twipsSize.iWidth;
1.732 + twipsSize.iWidth = twipsSize.iHeight;
1.733 + twipsSize.iHeight = tempVal;
1.734 + }
1.735 + aConfig.SetResolution(resSize);
1.736 + aConfig.SetResolutionTwips(twipsSize);
1.737 + }
1.738 + else
1.739 + {
1.740 + MDisplayControlBase::TResolution virtualResolution = AppModeToResolution(aResolutions,appMode);
1.741 + aConfig.SetResolution(virtualResolution.iPixelSize);
1.742 + aConfig.SetResolutionTwips(virtualResolution.iTwipsSize);
1.743 + }
1.744 + }
1.745 +
1.746 + //check config is valid from set of resolutions (inc virtual)
1.747 + TInt error = AddVirtualResolutions(aResolutions);
1.748 + if (error < KErrNone)
1.749 + {
1.750 + return error;
1.751 + }
1.752 + TInt startIndex=0;
1.753 + while (startIndex < aResolutions.Count())
1.754 + {
1.755 + TInt resolutionIndex;
1.756 + TBool boolError = MatchConfigToResolutions(aResolutions,aConfig,startIndex,resolutionIndex);
1.757 + if (boolError == EFalse)
1.758 + {
1.759 + return KErrArgument;
1.760 + }
1.761 +
1.762 + //if is larger than current app mode and same rotation,we have found a match and can break;
1.763 + TBool boolSet = SetConfigToResolution(appMode,aResolutions[resolutionIndex],aConfig);
1.764 + if (boolSet)
1.765 + { //new configuration is compatible with app mode and has been set
1.766 + //center appmode within the UI
1.767 + if (iAppModes[appMode].iFlags&MWsScreenConfigList::EDynamic)
1.768 + {
1.769 + aSizeModePosition = aResolutions[resolutionIndex].iPixelSize;
1.770 + }
1.771 + else
1.772 + {
1.773 + CenteredAppInUi(aResolutions[resolutionIndex].iPixelSize,iAppModes[appMode].iPixels,aSizeModePosition);
1.774 + }
1.775 +
1.776 + TDisplayConfiguration::TRotation tempRot;
1.777 + aConfig.GetRotation(tempRot);
1.778 + if (tempRot&1)
1.779 + {
1.780 + aSizeModePosition = TRect(aSizeModePosition.iTl.iY,aSizeModePosition.iTl.iX,
1.781 + aSizeModePosition.iBr.iY,aSizeModePosition.iBr.iX);
1.782 + }
1.783 +
1.784 + return KErrNone;
1.785 + }
1.786 + //otherwise
1.787 + startIndex = resolutionIndex+1; //match found will not fit current size mode, continue looking
1.788 + if (startIndex == aResolutions.Count())
1.789 + {
1.790 + return KErrArgument;
1.791 + }
1.792 + }
1.793 + STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
1.794 + return KErrGeneral; //shouldnt be able to get here
1.795 + }
1.796 +
1.797 +void CDisplayPolicy::CenteredAppInUi(const TSize& aUiSize,const TRect& aAppExtent,TRect& aSizeModePosition) const
1.798 + {
1.799 + if (aUiSize.iWidth > aAppExtent.Width())
1.800 + {
1.801 + aSizeModePosition.iTl.iX = (aUiSize.iWidth - aAppExtent.Width()) / 2;
1.802 + if (aSizeModePosition.iTl.iX < aAppExtent.iTl.iX)
1.803 + { //we want to obey screenmode offset as a minumum, so cannot center on this axis
1.804 + aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
1.805 + aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
1.806 + }
1.807 + else
1.808 + {
1.809 + aSizeModePosition.iBr.iX = aSizeModePosition.iTl.iX + aAppExtent.Width();
1.810 + }
1.811 + }
1.812 + else
1.813 + {
1.814 + aSizeModePosition.iTl.iX = aAppExtent.iTl.iX;
1.815 + aSizeModePosition.iBr.iX = aAppExtent.iBr.iX;
1.816 + }
1.817 +
1.818 + if (aUiSize.iHeight > aAppExtent.Height())
1.819 + {
1.820 + aSizeModePosition.iTl.iY = (aUiSize.iHeight - aAppExtent.Height()) / 2;
1.821 + if (aSizeModePosition.iTl.iY < aAppExtent.iTl.iY)
1.822 + { //we want to obey screenmode offset as a minumum, so cannot center on this axis
1.823 + aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
1.824 + aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
1.825 + }
1.826 + else
1.827 + {
1.828 + aSizeModePosition.iBr.iY = aSizeModePosition.iTl.iY + aAppExtent.Width();
1.829 + }
1.830 + }
1.831 + else
1.832 + {
1.833 + aSizeModePosition.iTl.iY = aAppExtent.iTl.iY;
1.834 + aSizeModePosition.iBr.iY = aAppExtent.iBr.iY;
1.835 + }
1.836 + }
1.837 +
1.838 +TInt CDisplayPolicy::GetSizeModeConfiguration(TInt aScreenSizeMode,TDisplayConfiguration& aConfig, TRect& aSizeModePosition)
1.839 + {
1.840 + //This function is used when display is disconnected. Set UI size same as app mode. We don't care about rotation
1.841 +
1.842 + //find appMode corresponding to screensizemode
1.843 + TInt appMode;
1.844 + TInt appModeCount = iAppModes.Count();
1.845 + for (appMode = 0; appMode < appModeCount; appMode++)
1.846 + {
1.847 + if (iAppModes[appMode].iModeIndex == aScreenSizeMode)
1.848 + {
1.849 + break;
1.850 + }
1.851 + }
1.852 + if (appModeCount == appMode)
1.853 + {
1.854 + return KErrArgument; //invalid screen size mode
1.855 + }
1.856 +
1.857 + if (1<<CFbsBitGc::EGraphicsOrientationRotated90&iAppModes[appMode].iOrientations
1.858 + || 1<<CFbsBitGc::EGraphicsOrientationRotated270&iAppModes[appMode].iOrientations)
1.859 + {//width and height were already flipped on construction. we need to flip it back
1.860 + TRect appRect = iAppModes[appMode].iPixels;
1.861 + TRect uiResRect(appRect.iTl.iX, appRect.iTl.iY, appRect.iBr.iY, appRect.iBr.iX);
1.862 + aConfig.SetResolution(uiResRect.Size());
1.863 + }
1.864 + else
1.865 + {
1.866 + aConfig.SetResolution(iAppModes[appMode].iPixels.iBr.AsSize());
1.867 + }
1.868 +
1.869 + CFbsBitGc::TGraphicsOrientation cFbsOrientation=CFbsBitGc::EGraphicsOrientationNormal;
1.870 + //we know aScreenSizeMode is valid-OrientationL wont leave
1.871 + TRAP_IGNORE(cFbsOrientation=iScreen->ObjectInterface<MWsScreenConfigList>()->OrientationL(aScreenSizeMode));
1.872 + aConfig.SetRotation(TDisplayConfiguration::TRotation(cFbsOrientation));
1.873 + aSizeModePosition = iAppModes[appMode].iPixels;
1.874 + return KErrNone;
1.875 + }
1.876 +
1.877 +TBool CDisplayPolicy::SettingConfiguration(const RArray<MDisplayControlBase::TResolution>& aResolutions,TDisplayConfiguration& aConfig)const
1.878 + { //converts configuration to appmode
1.879 + if (iUiScaling == ENone)
1.880 + {
1.881 + if (aConfig.IsDefined(aConfig.EResolution))
1.882 + {
1.883 + TSize res;
1.884 + aConfig.GetResolution(res);
1.885 + TInt index;
1.886 + for (index=0;index<aResolutions.Count();index++)
1.887 + {
1.888 + if (aResolutions[index].iPixelSize == res)
1.889 + {
1.890 + break;
1.891 + }
1.892 + }
1.893 + if (index == aResolutions.Count())
1.894 + { //failed to validate the resolution
1.895 + aConfig.Clear(aConfig.EResolution);
1.896 + }
1.897 + }
1.898 + return EFalse;
1.899 + }
1.900 +
1.901 +
1.902 + TAppMode appMode;
1.903 +
1.904 + TBool set;
1.905 + TRect zeroRect (0,0,0,0);
1.906 + TSize zeroSize (0,0);
1.907 + TSize size;
1.908 + set = aConfig.GetResolution(size);
1.909 + appMode.iPixels = set ? size : zeroRect;
1.910 +
1.911 + set = aConfig.GetResolutionTwips(size);
1.912 + appMode.iTwips = set ? size : zeroSize;
1.913 + TDisplayConfiguration::TRotation flags;
1.914 + set = aConfig.GetRotation(flags); //grr orientation again
1.915 + appMode.iOrientations = set? flags : 0; //will set the specific rotation
1.916 +
1.917 + TInt index=0;
1.918 + TInt scale=0;
1.919 + TSize bestAppSize;
1.920 + FindVirtualMode(aResolutions,appMode,bestAppSize,index,scale);
1.921 +
1.922 + //set aConfig to resolution returned
1.923 + aConfig.SetResolution(aResolutions[index].iPixelSize);
1.924 + aConfig.SetResolutionTwips(aResolutions[index].iTwipsSize);
1.925 + if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotationNormalSupported)
1.926 + && appMode.iOrientations == TDisplayConfiguration::ERotationNormal)
1.927 + {
1.928 + aConfig.SetRotation(TDisplayConfiguration1::ERotationNormal);
1.929 + }
1.930 + else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation90Supported)
1.931 + && appMode.iOrientations == TDisplayConfiguration::ERotation90CW)
1.932 + {
1.933 + aConfig.SetRotation(TDisplayConfiguration1::ERotation90CW);
1.934 + }
1.935 + else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation180Supported)
1.936 + && appMode.iOrientations == TDisplayConfiguration::ERotation180)
1.937 + {
1.938 + aConfig.SetRotation(TDisplayConfiguration1::ERotation180);
1.939 + }
1.940 + else if (aResolutions[index].iFlags.IsSet(MDisplayControlBase::TResolution::ERotation270Supported)
1.941 + && appMode.iOrientations == TDisplayConfiguration::ERotation270CW)
1.942 + {
1.943 + aConfig.SetRotation(TDisplayConfiguration1::ERotation270CW);
1.944 + }
1.945 + else
1.946 + {
1.947 + STD_ASSERT_DEBUG(EFalse, EPluginPanicTemp);
1.948 + return EFalse;
1.949 + }
1.950 + return ETrue;
1.951 + }
1.952 +
1.953 +void CDisplayPolicy::SetCompositionInfo (const TDisplayConfiguration& aCompositionConfig,
1.954 + const TDisplayConfiguration& aUiConfig)
1.955 + {
1.956 + TDisplayConfiguration::TRotation rotation;
1.957 + TSize sizePixels;
1.958 + TSize sizeTwips;
1.959 + if (aCompositionConfig.GetResolution(sizePixels))
1.960 + {
1.961 + aCompositionConfig.GetResolutionTwips(sizeTwips);
1.962 + if(aCompositionConfig.IsDefined(TDisplayConfiguration::ERotation))
1.963 + {
1.964 + aCompositionConfig.GetRotation(rotation);
1.965 + iLastCompositionRotation=rotation;
1.966 + if(rotation & TDisplayConfiguration::ERotation90CW)
1.967 + {
1.968 + //swap width and height to be stored in iCompositionSizePixels and iCompositionSizeTwips
1.969 + iCompositionSizePixels.iHeight = sizePixels.iWidth;
1.970 + iCompositionSizePixels.iWidth = sizePixels.iHeight;
1.971 + iCompositionSizeTwips.iHeight = sizeTwips.iWidth;
1.972 + iCompositionSizeTwips.iWidth = sizeTwips.iHeight;
1.973 + }
1.974 + else
1.975 + {
1.976 + iCompositionSizePixels = sizePixels;
1.977 + iCompositionSizeTwips = sizeTwips;
1.978 + }
1.979 + }
1.980 + else
1.981 + {
1.982 + iCompositionSizePixels = sizePixels;
1.983 + iCompositionSizeTwips = sizeTwips;
1.984 + }
1.985 +
1.986 + aUiConfig.GetResolution(sizePixels);
1.987 + aUiConfig.GetResolutionTwips(sizeTwips);
1.988 + if(aUiConfig.IsDefined(TDisplayConfiguration::ERotation))
1.989 + {
1.990 + aUiConfig.GetRotation(rotation);
1.991 + iLastUiRotation=rotation;
1.992 + if(rotation & TDisplayConfiguration::ERotation90CW)
1.993 + {
1.994 + //swap width and height to be stored in iUiSizePixels and iAppSizeTwips
1.995 + iUiSizePixels.iHeight = sizePixels.iWidth;
1.996 + iUiSizePixels.iWidth = sizePixels.iHeight;
1.997 + iAppSizeTwips.iHeight = sizeTwips.iWidth;
1.998 + iAppSizeTwips.iWidth = sizeTwips.iHeight;
1.999 + }
1.1000 + else
1.1001 + {
1.1002 + iUiSizePixels = sizePixels;
1.1003 + iAppSizeTwips = sizeTwips;
1.1004 + }
1.1005 + }
1.1006 + else
1.1007 + {
1.1008 + iUiSizePixels = sizePixels;
1.1009 + iAppSizeTwips = sizeTwips;
1.1010 + }
1.1011 + }
1.1012 + else
1.1013 + {
1.1014 + if (aUiConfig.GetRotation(rotation))
1.1015 + {
1.1016 + if ((rotation^iLastUiRotation)&TDisplayConfiguration::ERotation90CW)
1.1017 + {
1.1018 + TInt swapHeight=iUiSizePixels.iHeight;
1.1019 + iUiSizePixels.iHeight = iUiSizePixels.iWidth;
1.1020 + iUiSizePixels.iWidth = swapHeight;
1.1021 + }
1.1022 + iLastUiRotation=rotation;
1.1023 + }
1.1024 +
1.1025 + if (aCompositionConfig.GetRotation(rotation))
1.1026 + {
1.1027 + if ((rotation^iLastCompositionRotation)&TDisplayConfiguration::ERotation90CW)
1.1028 + {
1.1029 + TInt swapHeight=iCompositionSizePixels.iHeight;
1.1030 + iCompositionSizePixels.iHeight = iCompositionSizePixels.iWidth;
1.1031 + iCompositionSizePixels.iWidth = swapHeight;
1.1032 + swapHeight=iCompositionSizeTwips.iHeight;
1.1033 + iCompositionSizeTwips.iHeight = iCompositionSizeTwips.iWidth;
1.1034 + iCompositionSizeTwips.iWidth = swapHeight;
1.1035 + }
1.1036 + iLastCompositionRotation=rotation;
1.1037 + }
1.1038 + }
1.1039 + }
1.1040 +
1.1041 +void CDisplayPolicy::SetSizeModeExtent(TRect& aExtent, TBitFlags32 /*aContext*/)
1.1042 + {
1.1043 + iAppSizePixels = aExtent;
1.1044 + }
1.1045 +
1.1046 +/** Finds the best resolution that the specified appmode can fit into
1.1047 + Returns ETrue if it fits a mode
1.1048 + Returns EFalse to warn if it didnt fit in that mode
1.1049 + For both, it will set index and scale to the best fit
1.1050 +*/
1.1051 +TBool CDisplayPolicy::FindVirtualMode(const RArray<MDisplayControlBase::TResolution>& aResolutions,
1.1052 + const CDisplayPolicy::TAppMode& aAppMode,TSize& aFullAppModeSize,TInt& aIndex,TInt& aBestScale) const
1.1053 + {
1.1054 + const TInt KBestFit = 0x7000000; //a really big number that should get reduced during the search.
1.1055 + TInt bestFit=KBestFit;
1.1056 + TInt resDiffX;
1.1057 + TInt resDiffY;
1.1058 + TInt64 biggestArea(0);
1.1059 + TInt biggestAreaIndex=0;
1.1060 + TBool fullAppSize;
1.1061 +
1.1062 + if (aAppMode.iPixels.iTl.iX == 0 && aAppMode.iPixels.iTl.iY == 0)
1.1063 + { //no point trying again with a border on only 2 sides, as there is no border anyway!
1.1064 + fullAppSize = EFalse;
1.1065 + }
1.1066 + else
1.1067 + {
1.1068 + fullAppSize = ETrue;
1.1069 + }
1.1070 + aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX + aAppMode.iPixels.iTl.iX,
1.1071 + aAppMode.iPixels.iBr.iY + aAppMode.iPixels.iTl.iY); //try fitting with border all 4 sides
1.1072 +
1.1073 + while(1)
1.1074 + {
1.1075 + //find hardware mode that fits this best
1.1076 + for (TInt j = 0; j < aResolutions.Count(); j++)
1.1077 + {
1.1078 + if (bestFit == 0)
1.1079 + { //found a perfect match
1.1080 + break;
1.1081 + }
1.1082 + if (aResolutions[j].iFlags[MDisplayControlBase::TResolution::EIsVirtual])
1.1083 + { //ignore virtual resolutions
1.1084 + continue;
1.1085 + }
1.1086 + TInt maxScaling = 1;
1.1087 + if (iUiScaling == EInteger)
1.1088 + {
1.1089 + maxScaling = 4;
1.1090 + }
1.1091 + for (TInt k = maxScaling; k > 0; k--)
1.1092 + { //for every avalable integer scale
1.1093 + if (bestFit == 0)
1.1094 + { //found a perfect match
1.1095 + break;
1.1096 + }
1.1097 + TInt64 area=TInt64(aResolutions[j].iPixelSize.iWidth)*aResolutions[j].iPixelSize.iHeight;
1.1098 + if (area>biggestArea)
1.1099 + {
1.1100 + biggestArea=area;
1.1101 + biggestAreaIndex=j;
1.1102 + }
1.1103 + resDiffX = (aResolutions[j].iPixelSize.iWidth/k) - aFullAppModeSize.iWidth;
1.1104 + resDiffY = (aResolutions[j].iPixelSize.iHeight/k) - aFullAppModeSize.iHeight;
1.1105 +
1.1106 + if (resDiffX < 0 || resDiffY < 0)
1.1107 + { //app mode too large for this resolution
1.1108 + continue;
1.1109 + }
1.1110 + if (resDiffX+resDiffY < bestFit)
1.1111 + {
1.1112 + aIndex = j;
1.1113 + bestFit = resDiffX + resDiffY;
1.1114 + aBestScale = k;
1.1115 + continue;
1.1116 + }
1.1117 + }
1.1118 + }
1.1119 + if (bestFit != KBestFit)
1.1120 + { //it found the best resolution to scale into
1.1121 + break;
1.1122 + }
1.1123 + else if (fullAppSize == EFalse)
1.1124 + { //app does not fit any resolution, it will have to be scaled down to fit
1.1125 + aIndex=biggestAreaIndex;
1.1126 + aBestScale=1;
1.1127 + return EFalse;
1.1128 + }
1.1129 + else
1.1130 + {
1.1131 + aFullAppModeSize = TSize(aAppMode.iPixels.iBr.iX,
1.1132 + aAppMode.iPixels.iBr.iY); //try fitting with border only top and left
1.1133 + fullAppSize = EFalse;
1.1134 + }
1.1135 + }
1.1136 + return ETrue;
1.1137 + }
1.1138 +
1.1139 +TSize CDisplayPolicy::ResolutionSize(RArray<MDisplayControlBase::TResolution>& aResolutions,
1.1140 + const TSize aBestAppSize,TInt aIndex, TInt aScale) const
1.1141 + {
1.1142 + TSize returnSize;
1.1143 +
1.1144 + if (iUiScaling == EInteger) //only supporting integral scales
1.1145 + { //just calculate the scaled resolution
1.1146 + returnSize = TSize(aResolutions[aIndex].iPixelSize.iWidth/aScale,
1.1147 + aResolutions[aIndex].iPixelSize.iHeight/aScale);
1.1148 + }
1.1149 + else
1.1150 + { //find which axis scales best, create virtual resolution that fits this axis
1.1151 + TFraction bestAxisAsFraction;
1.1152 +
1.1153 + if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight >
1.1154 + (TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
1.1155 + { //y axis scales closest
1.1156 + bestAxisAsFraction.iNumer = aResolutions[aIndex].iPixelSize.iWidth;
1.1157 + bestAxisAsFraction.iDenom = aResolutions[aIndex].iPixelSize.iHeight;
1.1158 + returnSize = TSize(bestAxisAsFraction*aBestAppSize.iHeight,
1.1159 + aBestAppSize.iHeight);
1.1160 + }
1.1161 + else
1.1162 + { //x axis scales closest
1.1163 + bestAxisAsFraction.iNumer = aResolutions[aIndex].iPixelSize.iHeight;
1.1164 + bestAxisAsFraction.iDenom = aResolutions[aIndex].iPixelSize.iWidth;
1.1165 + returnSize = TSize(aBestAppSize.iWidth,
1.1166 + bestAxisAsFraction*aBestAppSize.iWidth);
1.1167 + }
1.1168 + }
1.1169 + return returnSize;
1.1170 + }
1.1171 +
1.1172 +TSize CDisplayPolicy::GetUiResolution()
1.1173 + {
1.1174 + return this->iUiSizePixels;
1.1175 + }
1.1176 +
1.1177 +TSize CDisplayPolicy::GetUiResolutionAsTwips() const
1.1178 + {
1.1179 + return this->iCompositionSizeTwips;
1.1180 + }
1.1181 +
1.1182 +TRect CDisplayPolicy::GetPolicyAppMode()
1.1183 + {
1.1184 + return iAppSizePixels;
1.1185 + }
1.1186 +
1.1187 +TSize CDisplayPolicy::ResolutionSizeFromTwips(RArray<MDisplayControlBase::TResolution>& aResolutions, TInt aAppMode, const TSize& aBestAppSize,
1.1188 + TInt aIndex,TBool aSwapAxis) const
1.1189 + {
1.1190 + TSize returnSize;
1.1191 + TFraction tempFraction;
1.1192 + TBool yScalesClosest;
1.1193 +
1.1194 + if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight > (TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
1.1195 + { //y axis scales closest
1.1196 + yScalesClosest = aSwapAxis?EFalse:ETrue;
1.1197 + }
1.1198 + else
1.1199 + { //x axis scales closest
1.1200 + yScalesClosest = aSwapAxis?ETrue:EFalse;
1.1201 + }
1.1202 +
1.1203 + if (yScalesClosest)
1.1204 + { //y axis scales closest
1.1205 + tempFraction.iNumer = aBestAppSize.iHeight; //bordered app height in pixels
1.1206 + tempFraction.iDenom = iAppModes[aAppMode].iPixels.iBr.iY - iAppModes[aAppMode].iPixels.iTl.iY; //app height in pixels
1.1207 + TInt uiYTwips=tempFraction*iAppModes[aAppMode].iTwips.iHeight; //bordered app height in twips
1.1208 +
1.1209 + tempFraction.iNumer = aResolutions[aIndex].iTwipsSize.iWidth; //display width in twips
1.1210 + tempFraction.iDenom = aResolutions[aIndex].iTwipsSize.iHeight; //display height in twips
1.1211 + TInt uiXTwips=tempFraction*uiYTwips; //virtual width in twips
1.1212 +
1.1213 + tempFraction.iNumer = iAppModes[aAppMode].iPixels.iBr.iX - iAppModes[aAppMode].iPixels.iTl.iX; //app width in pixels
1.1214 + tempFraction.iDenom = iAppModes[aAppMode].iTwips.iWidth; //display width in twips
1.1215 + TInt uiXPixels=tempFraction*uiXTwips; //virtual width in pixels
1.1216 +
1.1217 + returnSize.iWidth = uiXPixels;
1.1218 + returnSize.iHeight = aBestAppSize.iHeight;
1.1219 + }
1.1220 + else
1.1221 + { //x axis scales closest
1.1222 + tempFraction.iNumer = aBestAppSize.iWidth; //bordered app width in pixels
1.1223 + tempFraction.iDenom = iAppModes[aAppMode].iPixels.iBr.iX - iAppModes[aAppMode].iPixels.iTl.iX; //app width in pixels
1.1224 + TInt uiXTwips=tempFraction*iAppModes[aAppMode].iTwips.iWidth; //bordered app width in twips
1.1225 +
1.1226 + tempFraction.iNumer = aResolutions[aIndex].iTwipsSize.iHeight; //display height in twips
1.1227 + tempFraction.iDenom = aResolutions[aIndex].iTwipsSize.iWidth; //display width in twips
1.1228 + TInt uiYTwips=tempFraction*uiXTwips; //virtual height in twips
1.1229 +
1.1230 + tempFraction.iNumer = iAppModes[aAppMode].iPixels.iBr.iY - iAppModes[aAppMode].iPixels.iTl.iY; //app height in pixels
1.1231 + tempFraction.iDenom = iAppModes[aAppMode].iTwips.iHeight; //display height in twips
1.1232 + TInt uiYPixels=tempFraction*uiYTwips; //virtual width in pixels
1.1233 +
1.1234 + returnSize.iWidth = aBestAppSize.iWidth;
1.1235 + returnSize.iHeight = uiYPixels;
1.1236 + }
1.1237 +
1.1238 + return returnSize;
1.1239 + }
1.1240 +
1.1241 +TSize CDisplayPolicy::ResolutionSizeFromAssumedTwips(RArray<MDisplayControlBase::TResolution>& aResolutions,const TSize& aBestAppSize,
1.1242 + TInt aIndex,TBool aSwapAxis, TInt aScale) const
1.1243 + {
1.1244 + TSize returnSize;
1.1245 +
1.1246 + if (iUiScaling == EInteger) //only supporting integral scales
1.1247 + { //just calculate the scaled resolution
1.1248 + returnSize = TSize(aResolutions[aIndex].iTwipsSize.iWidth/aScale,
1.1249 + aResolutions[aIndex].iTwipsSize.iHeight/aScale);
1.1250 + }
1.1251 + else
1.1252 + { //find which axis scales best, create virtual resolution that fits this axis
1.1253 + TBool yScalesClosest;
1.1254 + TFraction bestAxisAsFraction;
1.1255 +
1.1256 + if ((TInt64)aResolutions[aIndex].iPixelSize.iWidth * aBestAppSize.iHeight >
1.1257 + (TInt64)aResolutions[aIndex].iPixelSize.iHeight * aBestAppSize.iWidth)
1.1258 + { //y axis scales closest
1.1259 + yScalesClosest = aSwapAxis?EFalse:ETrue;
1.1260 + }
1.1261 + else
1.1262 + { //x axis scales closest
1.1263 + yScalesClosest = aSwapAxis?ETrue:EFalse;
1.1264 + }
1.1265 +
1.1266 + if (yScalesClosest)
1.1267 + { //y axis scales closest
1.1268 + bestAxisAsFraction.iNumer = aResolutions[aIndex].iTwipsSize.iWidth;
1.1269 + bestAxisAsFraction.iDenom = aResolutions[aIndex].iTwipsSize.iHeight;
1.1270 + returnSize = TSize(bestAxisAsFraction*aBestAppSize.iHeight,
1.1271 + aBestAppSize.iHeight);
1.1272 + }
1.1273 + else
1.1274 + { //x axis scales closest
1.1275 + bestAxisAsFraction.iNumer = aResolutions[aIndex].iTwipsSize.iHeight;
1.1276 + bestAxisAsFraction.iDenom = aResolutions[aIndex].iTwipsSize.iWidth;
1.1277 + returnSize = TSize(aBestAppSize.iWidth,
1.1278 + bestAxisAsFraction*aBestAppSize.iWidth);
1.1279 + }
1.1280 + }
1.1281 + return returnSize;
1.1282 + }
1.1283 +
1.1284 +TInt CDisplayPolicy::MinSizedModeIndex()
1.1285 + {
1.1286 + return iSmallestAppMode;
1.1287 + }
1.1288 +
1.1289 +TInt CDisplayPolicy::SuitableAppMode(MWsDisplayPolicy::TDisplayStatus aSituation)
1.1290 + {
1.1291 + switch(aSituation)
1.1292 + {
1.1293 + case MWsDisplayPolicy::EAttach:
1.1294 + {
1.1295 + return iLastAppMode;
1.1296 + }
1.1297 + case MWsDisplayPolicy::EDetach:
1.1298 + {
1.1299 + return MinSizedModeIndex();
1.1300 + }
1.1301 + default:
1.1302 + return KErrNotSupported;
1.1303 + }
1.1304 +
1.1305 + }
1.1306 +
1.1307 +void CDisplayPolicy::SetLastAppMode(TInt aMode)
1.1308 + {
1.1309 + iLastAppMode = aMode;
1.1310 + }
1.1311 +
1.1312 +