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