|
1 // Copyright (c) 2006-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 "screen.h" |
|
17 |
|
18 #include <hal.h> |
|
19 #include <graphics/wsscreendevice.h> |
|
20 #include <graphics/wsscene.h> |
|
21 #include <graphics/wselement.h> |
|
22 #include "server.h" |
|
23 #include "wstop.h" |
|
24 #include "rootwin.h" |
|
25 #include "walkwindowtree.h" |
|
26 #include "EVENT.H" |
|
27 #include "windowgroup.h" |
|
28 #include "inifile.h" |
|
29 #include "pointer.h" |
|
30 #include "windowelementset.h" |
|
31 #include "registeredsurfacemap.h" |
|
32 #include "debugbar.h" |
|
33 #include "ScreenRedraw.h" |
|
34 #include "wspluginmanager.h" |
|
35 #include "devicemap.h" |
|
36 #include <graphics/wsdisplaymapping.h> |
|
37 #if defined(__WINS__) && defined(_DEBUG) |
|
38 #include "../../debuglog/osbwin.h" |
|
39 #endif |
|
40 #include <graphics/wsdisplaycontrol.h> |
|
41 |
|
42 GLREF_D CDebugLogBase *wsDebugLog; |
|
43 |
|
44 LOCAL_C inline MWsScene::TSceneRotation GcToScreen(CFbsBitGc::TGraphicsOrientation aGcOrientation) |
|
45 { |
|
46 MWsScene::TSceneRotation screenRotation = MWsScene::ESceneAntiClockwise0; |
|
47 |
|
48 switch (aGcOrientation) |
|
49 { |
|
50 case CFbsBitGc::EGraphicsOrientationRotated90: |
|
51 screenRotation = MWsScene::ESceneAntiClockwise90; |
|
52 break; |
|
53 case CFbsBitGc::EGraphicsOrientationRotated180: |
|
54 screenRotation = MWsScene::ESceneAntiClockwise180; |
|
55 break; |
|
56 case CFbsBitGc::EGraphicsOrientationRotated270: |
|
57 screenRotation = MWsScene::ESceneAntiClockwise270; |
|
58 break; |
|
59 } |
|
60 |
|
61 return screenRotation; |
|
62 } |
|
63 |
|
64 LOCAL_C inline TDeviceOrientation GcToDevice(CFbsBitGc::TGraphicsOrientation aGcOrientation) |
|
65 { |
|
66 // Each device orientation is defined to be the value where just the bit |
|
67 // corresponding to the GDI orientation value is set. |
|
68 return (TDeviceOrientation)(1 << aGcOrientation); |
|
69 } |
|
70 |
|
71 LOCAL_D TBool FindNextValue(TLex& aLex, TInt& aValue) // assumes the list cannot contain *negative* integers |
|
72 { |
|
73 while (!aLex.Eos()) |
|
74 { |
|
75 const TUint character=aLex.Peek(); |
|
76 if (Rng(TUint('0'), character, TUint('9')) || (character=='-')) |
|
77 { |
|
78 break; |
|
79 } |
|
80 aLex.Inc(); |
|
81 } |
|
82 |
|
83 return (aLex.Val(aValue)==KErrNone); |
|
84 } |
|
85 |
|
86 CScreen::CFallbackMap * CScreen::CFallbackMap::NewL(CScreen* aScreen) |
|
87 { |
|
88 CFallbackMap * self = new (ELeave) CFallbackMap(aScreen); |
|
89 CleanupStack::PushL(self); |
|
90 self->ConstructL(); |
|
91 CleanupStack::Pop(self); |
|
92 return self; |
|
93 } |
|
94 |
|
95 CScreen::CFallbackMap::CFallbackMap(CScreen* aScreen) : |
|
96 iScreen(aScreen), |
|
97 iRegion(TRect(TPoint(0,0), TSize(1,1))), |
|
98 iCount(0) |
|
99 { |
|
100 } |
|
101 |
|
102 CScreen::CFallbackMap::~CFallbackMap() |
|
103 { |
|
104 delete iMap; |
|
105 } |
|
106 |
|
107 void CScreen::CFallbackMap::ConstructL() |
|
108 { |
|
109 iMapSize = 0; |
|
110 |
|
111 for (TInt num = 0; num < iScreen->NumScreenSizeModes(); ++num) |
|
112 { |
|
113 if (iScreen->IsValidScreenSizeMode(num)) |
|
114 { |
|
115 const TSizeMode & mode = iScreen->ScreenSizeModeData(num); |
|
116 TInt width = mode.iScreenSize.iWidth / 32; |
|
117 if (mode.iScreenSize.iWidth & (32 - 1)) |
|
118 ++width; |
|
119 TInt size = width * mode.iScreenSize.iHeight; |
|
120 if (size > iMapSize) |
|
121 iMapSize = size; |
|
122 } |
|
123 } |
|
124 |
|
125 iMap = new (ELeave) TInt [iMapSize]; |
|
126 } |
|
127 |
|
128 void CScreen::CFallbackMap::Prepare() |
|
129 { |
|
130 const TSizeMode & mode = iScreen->ScreenSizeModeData(); |
|
131 Mem::FillZ(iMap, iMapSize * sizeof(TInt)); |
|
132 iCount = mode.iScreenSize.iHeight * mode.iScreenSize.iWidth; |
|
133 WS_ASSERT_DEBUG(iRegion.Count() == 1, EWsPanicScreenFallback); |
|
134 iRegion.Clear(); |
|
135 iRegion.AddRect(TRect(mode.iOrigin, mode.iScreenSize)); |
|
136 } |
|
137 |
|
138 TBool CScreen::CFallbackMap::FillRegion(const TRegion& aRegion) |
|
139 { |
|
140 WS_ASSERT_DEBUG(!aRegion.CheckError(), EWsPanicScreenFallback); |
|
141 if (aRegion.Count() > 20 || aRegion.CheckError()) |
|
142 return ETrue; |
|
143 TBool hit = EFalse; |
|
144 if (iCount > 0) |
|
145 { |
|
146 const TRect * rect = aRegion.RectangleList(); |
|
147 for (TInt num = 0; num < aRegion.Count(); ++num) |
|
148 { |
|
149 hit = FillRect(*rect) || hit; |
|
150 if (iCount < 1) |
|
151 break; |
|
152 ++rect; |
|
153 } |
|
154 } |
|
155 return hit; |
|
156 } |
|
157 |
|
158 // x >> 5 is equivalent to x / 32 |
|
159 // 0x1F is the rounding error when dividing by 32 |
|
160 // 0x20 is 32. |
|
161 // The compiler might do all the optimizations for us - not checked. |
|
162 TBool CScreen::CFallbackMap::FillRect(const TRect& aRect) |
|
163 { |
|
164 TBool hit = EFalse; |
|
165 const TSizeMode & mode = iScreen->ScreenSizeModeData(); |
|
166 TRect scrrect(mode.iOrigin, mode.iScreenSize); |
|
167 TRect rect = aRect; |
|
168 rect.Intersection(scrrect); |
|
169 TInt rowWidthInInts = mode.iScreenSize.iWidth; |
|
170 if (rowWidthInInts & 0x1F) |
|
171 rowWidthInInts += 0x20; |
|
172 rowWidthInInts >>= 5; |
|
173 |
|
174 TInt colStartInInts = rect.iTl.iX >> 5; |
|
175 TInt firstOffsetInBits = rect.iTl.iX & 0x1F; |
|
176 |
|
177 for(TInt row = rect.iTl.iY; row < rect.iBr.iY; ++row) |
|
178 { |
|
179 TInt * map = iMap + row * rowWidthInInts + colStartInInts; |
|
180 TInt offsetShift = 31 - firstOffsetInBits; |
|
181 for (TInt col = rect.iTl.iX; col < rect.iBr.iX; ++col) |
|
182 { |
|
183 WS_ASSERT_DEBUG(map - iMap < iMapSize, EWsPanicScreenFallback); |
|
184 if (!(*map & 1 << offsetShift)) |
|
185 { |
|
186 --iCount; |
|
187 hit = ETrue; |
|
188 if (iCount < 1) |
|
189 break; |
|
190 (*map) |= (1 << offsetShift); |
|
191 } |
|
192 --offsetShift; |
|
193 if (offsetShift < 0) |
|
194 { |
|
195 offsetShift = 31; |
|
196 ++map; |
|
197 } |
|
198 } |
|
199 } |
|
200 return hit; |
|
201 } |
|
202 |
|
203 TInt CScreen::CFallbackMap::Count() const |
|
204 { |
|
205 return iCount; |
|
206 } |
|
207 |
|
208 const TRect * CScreen::CFallbackMap::Rect() const |
|
209 { |
|
210 return iRegion.RectangleList(); |
|
211 } |
|
212 |
|
213 const RRegion * CScreen::CFallbackMap::Region() const |
|
214 { |
|
215 return &iRegion; |
|
216 } |
|
217 |
|
218 TInt CScreen::CFallbackMap::Resize(const TSize& aSize) |
|
219 { |
|
220 TInt err = KErrNone; |
|
221 TInt width = (aSize.iWidth+31) >> 5; // divide by 32 |
|
222 TInt invertedWidth = (aSize.iHeight+31) >> 5; // divide by 32 |
|
223 |
|
224 TInt maxSize = Max(width * aSize.iHeight,invertedWidth * aSize.iWidth); |
|
225 if (maxSize > iMapSize) |
|
226 { |
|
227 TInt* newMap=NULL; |
|
228 newMap = new TInt [maxSize]; |
|
229 if (newMap) |
|
230 { |
|
231 delete iMap; |
|
232 iMap = newMap; |
|
233 iMapSize = maxSize; |
|
234 } |
|
235 else |
|
236 { |
|
237 err = KErrNoMemory; |
|
238 } |
|
239 } |
|
240 return err; |
|
241 } |
|
242 |
|
243 // |
|
244 // CScreen |
|
245 // |
|
246 CScreen::CScreen(): iDirects(_FOFF(CWsDirectScreenAccess,iLink)), iMaxContrast(-1), iMaxBrightness(-1) |
|
247 , iDisplayChangeSpinner(0), iConfigChangeSpinner(0) |
|
248 { |
|
249 } |
|
250 |
|
251 CScreen::~CScreen() |
|
252 { |
|
253 delete iDebugBar; |
|
254 TInt ii; |
|
255 if(iModes) |
|
256 { |
|
257 for(ii=iNumScreenSizeModes-1;ii>=0;--ii) |
|
258 { |
|
259 delete (*iModes)[ii]; |
|
260 } |
|
261 iModes->Close(); |
|
262 delete iModes; |
|
263 } |
|
264 delete iRootWindow; |
|
265 iScreenDevice = NULL; |
|
266 delete iDsaDevice; |
|
267 delete iDeviceMap; |
|
268 delete iFallbackMap; |
|
269 delete iSpriteManager; |
|
270 delete iWindowElementSet; |
|
271 if (!iDsaSurface.IsNull()) |
|
272 { |
|
273 TInt err = iScene->UnregisterSurface(iDsaSurface); |
|
274 WS_ASSERT_DEBUG(KErrNone == err, EWsPanicDirectScreenAccess); |
|
275 } |
|
276 |
|
277 delete iSurfaceMap; |
|
278 delete iRedraw; |
|
279 #if defined(__WINS__) && defined(_DEBUG) |
|
280 delete iDebugWin; |
|
281 #endif |
|
282 |
|
283 if(iDisplayChangeNotifier) |
|
284 delete iDisplayChangeNotifier; |
|
285 if(iConfigChangeNotifier) |
|
286 delete iConfigChangeNotifier; |
|
287 iWsClientList.Close(); |
|
288 } |
|
289 |
|
290 void CScreen::ConstructL(const TRect& aDigitiserArea, TInt aScreenNumber) |
|
291 { |
|
292 iScreenNumber = aScreenNumber ; |
|
293 |
|
294 if (wsDebugLog) |
|
295 { |
|
296 _LIT(KWSERVInitScreen,"Initialising for Screen %d"); |
|
297 wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, KWSERVInitScreen, aScreenNumber); |
|
298 } |
|
299 |
|
300 // create screen redraw with render stages |
|
301 iRedraw = CScreenRedraw::NewL(*this); |
|
302 iScreenDevice = iRedraw->ObjectInterface<MWsScreenDevice>(); |
|
303 WS_ASSERT_ALWAYS(iScreenDevice, EWsPanicScreenDeviceMissing); |
|
304 iScene = iRedraw->ObjectInterface<MWsScene>(); |
|
305 WS_ASSERT_ALWAYS(iScene, EWsPanicSceneMissing); |
|
306 |
|
307 iDeviceMap = CGraphicsDeviceMap::NewL(*iScreenDevice); |
|
308 |
|
309 iDisplayControl = MWsScreen::ObjectInterface<MWsDisplayControl>(); |
|
310 iDisplayMapping = MWsScreen::ObjectInterface<MWsDisplayMapping>(); |
|
311 iDisplayPolicy = MWsScreen::ObjectInterface<MWsDisplayPolicy>(); |
|
312 |
|
313 |
|
314 // initialize screen size mode data |
|
315 LoadScreenSizesL(iScreenDevice->SizeInPixels()); |
|
316 iFallbackMap = CFallbackMap::NewL(this); |
|
317 |
|
318 LoadScreenSizeProperties(iScreenDevice->DisplayMode()); |
|
319 |
|
320 if (iDisplayPolicy) |
|
321 { |
|
322 iDisplayPolicy->NewAppModesAvailable(); |
|
323 } |
|
324 |
|
325 iDigitiserArea = aDigitiserArea; |
|
326 SetInitialScreenSizeModeAndRotation(); //get the first/lowest valid mode. Also calls SetDigitiserAreas |
|
327 |
|
328 ApplyRemainingWsiniSettingsL(); |
|
329 |
|
330 iRootWindow = new (ELeave) CWsRootWindow(NULL, this); |
|
331 iRootWindow->ConstructL(); |
|
332 |
|
333 // Default fading parameters |
|
334 iBlackMap=128; |
|
335 iWhiteMap=255; |
|
336 |
|
337 iSpriteManager = CWsSpriteManager::NewL(); |
|
338 |
|
339 InitializeSceneL(); |
|
340 InitializeUiElementsL(); |
|
341 iSurfaceMap = new (ELeave) CRegisteredSurfaceMap(*iScene); |
|
342 |
|
343 //if the interface for notification is available. start notification AO. |
|
344 if (iDisplayControl) |
|
345 { |
|
346 iDisplayChangeNotifier = CWsDisplayChangeNotifier::NewL(iDisplayControl, this); |
|
347 iDisplayChangeNotifier->IssueNotificationRequest(); |
|
348 iConfigChangeNotifier = CWsConfigChangeNotifier::NewL(iDisplayControl, this); |
|
349 iConfigChangeNotifier->IssueNotificationRequest(); |
|
350 } |
|
351 doSetScreenMode(iScreenSizeMode,ETrue); |
|
352 } |
|
353 |
|
354 void CScreen::ApplyRemainingWsiniSettingsL() |
|
355 { |
|
356 #if defined(__WINS__) && defined(_DEBUG) |
|
357 _LIT(KDebugOsb,"DEBUGOSB"); |
|
358 if(WsIniFile->FindVar(iScreenNumber, KDebugOsb)) |
|
359 { |
|
360 _LIT(KDebugWinTitleFormat, "Screen %d, DSA surface"); |
|
361 TBuf<32> title; |
|
362 title.Format(KDebugWinTitleFormat, iScreenNumber); |
|
363 iDebugWin = CDebugOsbWin::NewL(title, iScreenDevice->SizeInPixels()); |
|
364 } |
|
365 #endif |
|
366 |
|
367 TInt autoClear = 1; |
|
368 _LIT(KWSERVIniFileVarAutoClear,"AUTOCLEAR"); |
|
369 WsIniFile->FindVar(iScreenNumber,KWSERVIniFileVarAutoClear,autoClear); |
|
370 if (autoClear != 0) |
|
371 { |
|
372 iFlags|=EAutoClear; |
|
373 } |
|
374 |
|
375 _LIT(KBackLight,"BACKLIGHTCONTROL"); |
|
376 iBackLightFlag=WsIniFile->FindVar( iScreenNumber, KBackLight); |
|
377 |
|
378 _LIT(KWSERVIniFileVarBlankScreen, "BLANKSCREENONROTATION"); |
|
379 if (WsIniFile->FindVar(iScreenNumber, KWSERVIniFileVarBlankScreen)) |
|
380 { |
|
381 iFlags|=EBlankScreenOnRotation; |
|
382 } |
|
383 |
|
384 //Cache pointers to renderstage APIs required in CHANGETRACKING mode |
|
385 iWindowTreeObserver = iRedraw->ObjectInterface<MWsWindowTreeObserver>(); |
|
386 iDrawAnnotationObserver = iRedraw->ObjectInterface<MWsDrawAnnotationObserver>(); |
|
387 iWindowVisibilityNotifier = iRedraw->ObjectInterface<MWsWindowVisibilityNotifier>(); |
|
388 if(iWindowVisibilityNotifier) |
|
389 { |
|
390 iWindowVisibilityNotifier->RegisterWindowVisibilityObserver(iRedraw); |
|
391 } |
|
392 if (WsIniFile->FindVar(iScreenNumber, KWSERVIniFileVarChangeTracking)) |
|
393 { |
|
394 iFlags|=EChangeTracking; |
|
395 } |
|
396 |
|
397 //coverity[const] |
|
398 TInt refreshRate = 1000000; |
|
399 _LIT(KDebugBar, "DEBUGBAR"); |
|
400 if (WsIniFile->FindVar(KDebugBar, refreshRate)) |
|
401 { |
|
402 if (refreshRate < 100000) |
|
403 // coverity [dead_error_line] |
|
404 refreshRate = 50000; |
|
405 iDebugBar = CDebugBar::NewL(this, refreshRate); |
|
406 } |
|
407 } |
|
408 |
|
409 void CScreen::AcquireDsaScreenDeviceL() |
|
410 { |
|
411 //creates WSERV's DSA buffer handle |
|
412 //registers the DSA surface into the scene accordingly to the value of aRegisterSurface |
|
413 if(!iDsaDevice) |
|
414 { |
|
415 TDisplayMode screenMode = ENone; |
|
416 screenMode = iScreenDevice->DisplayMode(); |
|
417 if(screenMode != ENone) |
|
418 { |
|
419 CreateDsaScreenDeviceIfSupportedL(screenMode); |
|
420 // initialize DSA |
|
421 iDsaDevice->SetAutoUpdate(EFalse); |
|
422 iDsaDevice->SetDeviceOrientation(GcToDevice(ScreenSizeModeData().iRotation)); |
|
423 iDsaDevice->ChangeScreenDevice(NULL); //This is necessary to initialise the screen |
|
424 // register DSA Surface |
|
425 TInt err = InitializeDsaSurface(); |
|
426 // create a graphics context to clear the DSA surface |
|
427 if (!err) |
|
428 err = iDsaDevice->CreateContext(iDsaGc); |
|
429 if (!err) |
|
430 iDsaGc->Activate(iDsaDevice); |
|
431 if (err != KErrNone) |
|
432 { |
|
433 //Creation of the DSA surface failed |
|
434 //Cleanup the DSA Surface ID |
|
435 iDsaSurface = TSurfaceId::CreateNullId(); |
|
436 //and the iDsaDevice |
|
437 delete iDsaDevice; |
|
438 iDsaDevice = NULL; |
|
439 User::Leave(err); |
|
440 } |
|
441 } |
|
442 else |
|
443 { |
|
444 User::Leave(KErrNotSupported); |
|
445 } |
|
446 } |
|
447 iNumberDrawingDsa++; |
|
448 } |
|
449 |
|
450 void CScreen::CreateDsaScreenDeviceIfSupportedL(TDisplayMode aScreenMode) |
|
451 { |
|
452 if(DoCreateDsaScreenDevice(aScreenMode)) |
|
453 return; |
|
454 // Try creating the screen device with all available display modes, going from best to worst |
|
455 __ASSERT_COMPILE(EColorLast == 14); // if any display mode is added to TDisplayMode we must update the list below |
|
456 // (the list below contains all enums in TDisplayMode except ENone, ERgb, EColorLast) |
|
457 if(DoCreateDsaScreenDevice(EColor16MAP)) |
|
458 return; |
|
459 if(DoCreateDsaScreenDevice(EColor16MA)) |
|
460 return; |
|
461 if(DoCreateDsaScreenDevice(EColor16MU)) |
|
462 return; |
|
463 if(DoCreateDsaScreenDevice(EColor16M)) |
|
464 return; |
|
465 if(DoCreateDsaScreenDevice(EColor64K)) |
|
466 return; |
|
467 if(DoCreateDsaScreenDevice(EColor4K)) |
|
468 return; |
|
469 if(DoCreateDsaScreenDevice(EColor256)) |
|
470 return; |
|
471 if(DoCreateDsaScreenDevice(EColor16)) |
|
472 return; |
|
473 if(DoCreateDsaScreenDevice(EGray256)) |
|
474 return; |
|
475 if(DoCreateDsaScreenDevice(EGray16)) |
|
476 return; |
|
477 if(DoCreateDsaScreenDevice(EGray4)) |
|
478 return; |
|
479 if(DoCreateDsaScreenDevice(EGray2)) |
|
480 return; |
|
481 User::Leave(KErrNotSupported); |
|
482 } |
|
483 |
|
484 TBool CScreen::DoCreateDsaScreenDevice(TDisplayMode aScreenMode) |
|
485 { |
|
486 TRAPD(err, iDsaDevice = CFbsScreenDevice::NewL(iScreenNumber, aScreenMode)); |
|
487 if(err == KErrNone) |
|
488 { |
|
489 TUint supportedDsaRotationModes = iDsaDevice->DeviceOrientationsAvailable(); |
|
490 MWsScene::TSceneRotation currenTSceneRotation = iScene->SceneRotation(); |
|
491 TBool doesDsaSupportThisMode = EFalse; |
|
492 switch(currenTSceneRotation) |
|
493 { |
|
494 case MWsScene::ESceneAntiClockwise0: |
|
495 if(supportedDsaRotationModes & EDeviceOrientationNormal) |
|
496 { |
|
497 doesDsaSupportThisMode = ETrue; |
|
498 } |
|
499 break; |
|
500 case MWsScene::ESceneAntiClockwise90: |
|
501 if(supportedDsaRotationModes & EDeviceOrientation90CW) |
|
502 { |
|
503 doesDsaSupportThisMode = ETrue; |
|
504 } |
|
505 break; |
|
506 case MWsScene::ESceneAntiClockwise180: |
|
507 if(supportedDsaRotationModes & EDeviceOrientation180) |
|
508 { |
|
509 doesDsaSupportThisMode = ETrue; |
|
510 } |
|
511 break; |
|
512 case MWsScene::ESceneAntiClockwise270: |
|
513 if(supportedDsaRotationModes & EDeviceOrientation270CW) |
|
514 { |
|
515 doesDsaSupportThisMode = ETrue; |
|
516 } |
|
517 break; |
|
518 default: |
|
519 RDebug::Print(_L("** CScreen::DoCreateDsaScreenDevice Panic, non existing rotation mode")); |
|
520 WS_PANIC_ALWAYS(EWsPanicInvalidOperation); |
|
521 break; |
|
522 } |
|
523 if(!doesDsaSupportThisMode) |
|
524 { |
|
525 delete iDsaDevice; |
|
526 iDsaDevice = NULL; |
|
527 RDebug::Print(_L("** Current Rotation Mode not supported by the DSA device")); |
|
528 err = KErrNotSupported; |
|
529 } |
|
530 } |
|
531 return (err == KErrNone); |
|
532 } |
|
533 |
|
534 void CScreen::AbortDSAs(RDirectScreenAccess::TTerminationReasons aReason, TSglQue<CWsDirectScreenAccess>& aDirects) |
|
535 { |
|
536 if (aDirects.IsEmpty()) |
|
537 return; |
|
538 |
|
539 TInt nofDSAs = 0; |
|
540 CWsDirectScreenAccess* direct= NULL; |
|
541 TSglQueIter<CWsDirectScreenAccess> iter(aDirects); |
|
542 while ((direct=iter++)!=NULL) |
|
543 { |
|
544 nofDSAs++; |
|
545 direct->SignalAbort(aReason); |
|
546 } |
|
547 |
|
548 TRequestStatus timerStatus; |
|
549 RTimer& timer=CWsTop::Timer(); |
|
550 timer.Cancel(); |
|
551 |
|
552 TRequestStatus** cancelReqList = (TRequestStatus**) User::AllocZ(sizeof(TRequestStatus*) * (nofDSAs + 1)); |
|
553 if (NULL != cancelReqList) |
|
554 { |
|
555 TInt dsaNo = 1; |
|
556 timer.After(timerStatus, KDSAAbortingImmediateRespAwaitFrameMicrosec); |
|
557 iter.SetToFirst(); |
|
558 while ((direct=iter++)!=NULL) |
|
559 { |
|
560 WS_ASSERT_DEBUG((dsaNo<=(nofDSAs)),EWsPanicDirectScreenAccess); |
|
561 cancelReqList[ dsaNo ] = &direct->AbortStatus(); |
|
562 dsaNo++; |
|
563 } |
|
564 cancelReqList[ 0 ] = &timerStatus; |
|
565 |
|
566 //wait for response or timeout |
|
567 User::WaitForNRequest(cancelReqList, nofDSAs + 1); |
|
568 |
|
569 iter.SetToFirst(); |
|
570 while ((direct=iter++)!=NULL) |
|
571 { |
|
572 if (direct->AbortStatus() != KRequestPending) |
|
573 direct->CancelAbortObject(); // responded |
|
574 else |
|
575 direct->Abort(); |
|
576 } |
|
577 |
|
578 if (timerStatus == KRequestPending) |
|
579 { |
|
580 timer.Cancel(); |
|
581 User::WaitForRequest(timerStatus); |
|
582 } |
|
583 |
|
584 User::Free(cancelReqList); |
|
585 } |
|
586 else |
|
587 { |
|
588 iter.SetToFirst(); |
|
589 while ((direct=iter++) != NULL) |
|
590 { |
|
591 TRequestStatus timerStatus; |
|
592 RTimer& timer=CWsTop::Timer(); |
|
593 timer.Cancel(); |
|
594 timer.After(timerStatus, KDSAAbortingImmediateRespAwaitFrameMicrosec); |
|
595 |
|
596 //wait for response or timeout |
|
597 User::WaitForRequest(direct->AbortStatus(), timerStatus); |
|
598 |
|
599 if (direct->AbortStatus() != KRequestPending) |
|
600 direct->CancelAbortObject(); //responded |
|
601 else |
|
602 direct->Abort(); //timed out |
|
603 |
|
604 if (timerStatus == KRequestPending) |
|
605 { |
|
606 timer.Cancel(); |
|
607 User::WaitForRequest(timerStatus); |
|
608 } |
|
609 } |
|
610 } |
|
611 } |
|
612 |
|
613 void CScreen::AbortAllDirectDrawing(RDirectScreenAccess::TTerminationReasons aReason) |
|
614 { |
|
615 AbortDSAs(aReason,iDirects); |
|
616 } |
|
617 |
|
618 void CScreen::AddDirect(CWsDirectScreenAccess& aDirect) |
|
619 { |
|
620 TBool emptyBefore = iDirects.IsEmpty(); |
|
621 iDirects.AddLast(aDirect); |
|
622 TBool emptyAfter = iDirects.IsEmpty(); |
|
623 if (emptyBefore && ! emptyAfter) |
|
624 { |
|
625 TWsEvent wsevent; |
|
626 wsevent.SetType(EEventDirectScreenAccessBegin); |
|
627 *(wsevent.Int()) = iScreenNumber; |
|
628 TWindowServerEvent::PublishNotification(wsevent); |
|
629 } |
|
630 |
|
631 if (iDsaDrawState==EDsaDrawStateIdle && aDirect.IsVisible()) |
|
632 { |
|
633 iDsaDrawState = EDsaDrawStateDrawing; |
|
634 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EDsaDrawingBegin, iScreenNumber)); |
|
635 } |
|
636 } |
|
637 |
|
638 void CScreen::RemoveDirect(CWsDirectScreenAccess& aDirect) |
|
639 { |
|
640 TBool emptyBefore = iDirects.IsEmpty(); |
|
641 iDirects.Remove(aDirect); |
|
642 TBool emptyAfter = iDirects.IsEmpty(); |
|
643 if (emptyAfter && ! emptyBefore) |
|
644 { |
|
645 TWsEvent wsevent; |
|
646 wsevent.SetType(EEventDirectScreenAccessEnd); |
|
647 *(wsevent.Int()) = iScreenNumber; |
|
648 TWindowServerEvent::PublishNotification(wsevent); |
|
649 } |
|
650 |
|
651 if (iDsaDrawState==EDsaDrawStateDrawing && aDirect.IsVisible() && !HasVisibleDirectOnQueue()) |
|
652 { |
|
653 iDsaDrawState = EDsaDrawStateIdle; |
|
654 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EDsaDrawingEnd, iScreenNumber)); |
|
655 } |
|
656 } |
|
657 |
|
658 TBool CScreen::HasVisibleDirectOnQueue() |
|
659 { |
|
660 if (iDirects.IsEmpty()) |
|
661 return EFalse; |
|
662 |
|
663 TSglQueIter<CWsDirectScreenAccess> iter(iDirects); |
|
664 CWsDirectScreenAccess* dsa; |
|
665 while ((dsa=iter++)!=NULL) |
|
666 { |
|
667 if (dsa->IsVisible()) |
|
668 return ETrue; |
|
669 } |
|
670 |
|
671 return EFalse; |
|
672 } |
|
673 |
|
674 #if defined(_DEBUG) |
|
675 TBool CScreen::IsDirectOnQueue(const CWsDirectScreenAccess* aDirect) |
|
676 { |
|
677 TSglQueIter<CWsDirectScreenAccess> iter(iDirects); |
|
678 CWsDirectScreenAccess* direct; |
|
679 while ((direct=iter++)!=NULL) |
|
680 { |
|
681 if (direct==aDirect) |
|
682 return ETrue; |
|
683 } |
|
684 return EFalse; |
|
685 } |
|
686 #endif |
|
687 |
|
688 void CScreen::KillForegroundSession() |
|
689 { |
|
690 if (iCurrentFocus) |
|
691 { |
|
692 _LIT(KWSERVKillWinGp,"Killing Session owning Window Group with Id=%d"); |
|
693 if (wsDebugLog) |
|
694 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVKillWinGp,iCurrentFocus->Identifier()); |
|
695 iCurrentFocus->WsOwner()->SessionTerminate(); |
|
696 } |
|
697 } |
|
698 |
|
699 CWsWindowGroup* CScreen::FindNewFocus(CWsRootWindow* aRootWindow) |
|
700 { |
|
701 CWsWindowGroup* newFocus; |
|
702 for(newFocus=aRootWindow->Child();newFocus && newFocus->CanReceiveFocus()==EFalse;newFocus=newFocus->NextSibling()) {} |
|
703 |
|
704 return newFocus; |
|
705 } |
|
706 |
|
707 void CScreen::ResetFocus(CWsWindowGroup* aClosingWindow) |
|
708 { |
|
709 CWsWindowGroup* oldFocus=iCurrentFocus; |
|
710 CWsWindowGroup* newFocus=NULL; |
|
711 CScreen* newFocusedScreen=NULL; |
|
712 iCurrentFocus=FindNewFocus(iRootWindow); |
|
713 TBool focusedScreen= EFalse; |
|
714 /*Focus policy is specified in the wsini.ini file using the keyword 'MULTIFOCUSPOLICY'. |
|
715 If the keyword is not specified, then the default policy is run. |
|
716 */ |
|
717 if(!CWsTop::MultiFocusPolicy()) |
|
718 { |
|
719 focusedScreen=(this==CWsTop::CurrentFocusScreen()); //check if this screen is the focus screen |
|
720 if (!iCurrentFocus && focusedScreen) |
|
721 { |
|
722 /*If this screen is the focused screen but does not have a focusable window group, then search for the |
|
723 next screen that has a focusable window group and set that screen as the focused screen. |
|
724 */ |
|
725 CScreen* screen=NULL; |
|
726 TInt screenNo; |
|
727 for (screenNo=0; screenNo<CWsTop::NumberOfScreens() && !newFocus; ++screenNo) |
|
728 { |
|
729 if (screenNo!=iScreenNumber) |
|
730 { |
|
731 screen=CWsTop::Screen(screenNo); |
|
732 newFocus=FindNewFocus(screen->RootWindow()); |
|
733 } |
|
734 } |
|
735 if (newFocus) |
|
736 newFocusedScreen=screen; |
|
737 } |
|
738 } |
|
739 /*Scenario A: multi-focus policy |
|
740 newFocusedScreen is NULL |
|
741 focusedScreen is EFalse |
|
742 CWsTop::MultiFocusPolicy() returns ETrue |
|
743 Check if the new focusable window group is not the same, send focus lost message to window group |
|
744 that has just lost focus and send focus gain message to window group that can receive focus. |
|
745 Scenario B: single-focus policy (default) |
|
746 CWsTop::MultiFocusPolicy() returns EFalse |
|
747 Check if the new focusable window group is not the same or if there is a new focused screen, send focus lost |
|
748 message to window group that has just lost focus and send focus gain message to window group that can receive focus. |
|
749 */ |
|
750 if (iCurrentFocus!=oldFocus || newFocusedScreen) |
|
751 { |
|
752 if (oldFocus && (focusedScreen || CWsTop::MultiFocusPolicy()) && oldFocus!=aClosingWindow) |
|
753 { |
|
754 oldFocus->LostFocus(); |
|
755 } |
|
756 if (newFocusedScreen) |
|
757 { |
|
758 CWsTop::SetCurrentFocusScreen(newFocusedScreen); |
|
759 newFocus->ReceivedFocus(); |
|
760 } |
|
761 else if (iCurrentFocus && (focusedScreen || CWsTop::MultiFocusPolicy())) |
|
762 { |
|
763 iCurrentFocus->ReceivedFocus(); |
|
764 } |
|
765 TWsPointer::UpdatePointerCursor(); |
|
766 TWindowServerEvent::SendFocusChangedEvents(); |
|
767 } |
|
768 TWindowServerEvent::SendGroupListChangedEvents(); |
|
769 } |
|
770 |
|
771 void CScreen::RemoveFromDefaultOwningList(CWsWindowGroup *aDestroyedGroup) |
|
772 { |
|
773 for (CWsWindowGroup **group=&iDefaultOwningWindow;*group;group=(*group)->NextDefaultOwningWindowPtr()) |
|
774 { |
|
775 if (*group==aDestroyedGroup) |
|
776 { |
|
777 *group=*aDestroyedGroup->NextDefaultOwningWindowPtr(); |
|
778 break; |
|
779 } |
|
780 } |
|
781 } |
|
782 |
|
783 void CScreen::SetDefaultOwningWindow(CWsWindowGroup *aGroup) |
|
784 { |
|
785 RemoveFromDefaultOwningList(aGroup); |
|
786 aGroup->SetNextDefaultOwningWindow(iDefaultOwningWindow); |
|
787 iDefaultOwningWindow=aGroup; |
|
788 } |
|
789 |
|
790 void CScreen::GetScanLine(const TWsSdCmdGetScanLine *aGetScanLine) |
|
791 { |
|
792 TRgb buf[EGetScanLineBufLen]; |
|
793 TPtr8 des((TUint8 *)&buf[0],EGetScanLineBufLen*sizeof(TRgb)); |
|
794 TPoint pos(aGetScanLine->pos); |
|
795 TInt read=0; |
|
796 TInt len=(des.MaxLength()*EGetScanLineBufLen)/CFbsBitmap::ScanLineLength(EGetScanLineBufLen,aGetScanLine->dispMode); |
|
797 if (aGetScanLine->len < 0 || (CFbsBitmap::ScanLineLength(aGetScanLine->len, aGetScanLine->dispMode) > |
|
798 CWsClient::CurrentClient()->ClientMessage().GetDesMaxLength(1))) |
|
799 { |
|
800 CWsClient::PanicCurrentClient(EWservPanicInvalidParameter); |
|
801 } |
|
802 FOREVER |
|
803 { |
|
804 if ((aGetScanLine->len-read)<len) |
|
805 len=aGetScanLine->len-read; |
|
806 iScreenDevice->GetScanLine(des,pos,len,aGetScanLine->dispMode); |
|
807 CWsClient::ReplyBuf(des); |
|
808 read+=len; |
|
809 if (read==aGetScanLine->len) |
|
810 break; |
|
811 pos.iX+=len; |
|
812 } |
|
813 } |
|
814 |
|
815 void CScreen::MaxNumColors(TInt& aColors,TInt& aGrays) |
|
816 { |
|
817 aGrays=0; |
|
818 aColors=TDisplayModeUtils::NumDisplayModeColors(DisplayMode()); |
|
819 if (!TDisplayModeUtils::IsDisplayModeColor(DisplayMode())) |
|
820 { |
|
821 aGrays=aColors; |
|
822 aColors=0; |
|
823 } |
|
824 } |
|
825 |
|
826 #define MODE_TO_FLAG(x) 1<<(x-1) |
|
827 #define ROTATION_TO_FLAG(x) 1<<x |
|
828 const TUint allRotationsMask = ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationNormal) |
|
829 | ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationRotated90) |
|
830 | ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationRotated180) |
|
831 | ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationRotated270); |
|
832 const TUint KRotation0_180Mask = ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationNormal) |
|
833 | ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationRotated180); |
|
834 const TUint KRotation90_270Mask = ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationRotated90) |
|
835 | ROTATION_TO_FLAG(CFbsBitGc::EGraphicsOrientationRotated270); |
|
836 TInt CScreen::ColorModesFlag() |
|
837 { |
|
838 return MODE_TO_FLAG(DisplayMode()); |
|
839 } |
|
840 |
|
841 void CScreen::UpdateDsa() |
|
842 { |
|
843 if(iDsaDevice) |
|
844 { |
|
845 #if defined(__WINS__) && defined(_DEBUG) |
|
846 if (iDebugWin) |
|
847 iDebugWin->Refresh(iDsaDevice->SizeInPixels(), iDsaDevice->DisplayMode(), iDsaDevice->Bits()); |
|
848 #endif |
|
849 |
|
850 iDsaDevice->Update(); |
|
851 } |
|
852 } |
|
853 |
|
854 const CGraphicsDeviceMap& CScreen::DeviceMap() const |
|
855 { |
|
856 return *iDeviceMap; |
|
857 } |
|
858 |
|
859 const MWsScreenDevice& CScreen::ScreenDevice() const |
|
860 { |
|
861 return *iScreenDevice; |
|
862 } |
|
863 |
|
864 void CScreen::SetPointerCursorArea(TInt aMode,const TRect& aRect) |
|
865 { |
|
866 (*iModes)[aMode]->iPointerCursorArea=aRect; |
|
867 (*iModes)[aMode]->iFlags |= EClientDefinedDigitiserArea; |
|
868 TWsPointer::SetPointerCursorPos(TWsPointer::PointerCursorPos()); |
|
869 } |
|
870 |
|
871 CFbsBitGc::TGraphicsOrientation CScreen::Orientation() const |
|
872 { |
|
873 WS_ASSERT_DEBUG(IsValidScreenSizeMode(iScreenSizeMode),EWsPanicInvalidScreenSizeMode); |
|
874 return (*iModes)[iScreenSizeMode]->iRotation; |
|
875 } |
|
876 |
|
877 TRect CScreen::DrawableArea() const |
|
878 { |
|
879 TRect drawRect=iScreenDevice->SizeInPixels(); |
|
880 if (iDisplayMapping) |
|
881 { |
|
882 iDisplayMapping->MapCoordinates(EFullScreenSpace,drawRect,EApplicationSpace,drawRect); |
|
883 } |
|
884 return drawRect; |
|
885 } |
|
886 |
|
887 TClientPanic CScreen::SetModeRotation(TInt aMode,CFbsBitGc::TGraphicsOrientation aRotation) |
|
888 { |
|
889 if (!IsValidScreenSizeMode(aMode)) |
|
890 return EWservPanicScreenModeNumber; |
|
891 TSizeMode& mode=*(*iModes)[aMode]; |
|
892 if (!(ROTATION_TO_FLAG(aRotation)&mode.iAlternativeRotations)) |
|
893 return EWservPanicRotation; |
|
894 CFbsBitGc::TGraphicsOrientation oldRotation=mode.iRotation; |
|
895 mode.iRotation=aRotation; |
|
896 CWsWindowGroup::NewOrientation(aMode,aRotation, iRootWindow); |
|
897 if (aMode==ScreenSizeMode()) |
|
898 { |
|
899 if(iDisplayPolicy && iDisplayControl && (mode.iAlternativeRotations == allRotationsMask)) |
|
900 { |
|
901 //square mode supports all 4 rotations. We'd better do a complete Setconfiguration |
|
902 //all parameters are recalculated for 90 degree rotation |
|
903 //The most important one is the offset, since we need to re-center the appmode and it's a policy behaviour |
|
904 TDisplayConfiguration config; |
|
905 iDisplayControl->GetConfiguration(config); |
|
906 //update rotation |
|
907 config.SetRotation((TDisplayConfiguration::TRotation)aRotation); |
|
908 SetConfiguration(config); |
|
909 } |
|
910 else if (!UpdateOrientation()) |
|
911 { |
|
912 // Roll back earlier change |
|
913 mode.iRotation=oldRotation; |
|
914 CWsWindowGroup::NewOrientation(aMode, oldRotation, iRootWindow); |
|
915 } |
|
916 } |
|
917 return EWservNoPanic; |
|
918 } |
|
919 |
|
920 void CScreen::CycleDisplaySize() |
|
921 { |
|
922 TInt newMode = iScreenSizeMode; |
|
923 TSizeMode* sizeMode = NULL; |
|
924 do |
|
925 { |
|
926 newMode = (newMode+1)%iModes->Count(); |
|
927 sizeMode = (*iModes)[newMode]; |
|
928 } |
|
929 while (sizeMode==NULL); |
|
930 doSetScreenMode(newMode); |
|
931 } |
|
932 |
|
933 void CScreen::doSetScreenMode(TInt aMode,TBool aInsideStartup) |
|
934 { |
|
935 WS_ASSERT_DEBUG(IsValidScreenSizeMode(aMode),EWsPanicInvalidScreenSizeMode); |
|
936 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EScreenSizeModeAboutToChange, aMode)); |
|
937 |
|
938 if (iDisplayControl && iDisplayPolicy) |
|
939 { |
|
940 TDisplayConfiguration config; |
|
941 TRect sizeModePosition; |
|
942 TInt error; |
|
943 TSizeMode& mode=*(*iModes)[aMode]; |
|
944 config.SetRotation((TDisplayConfiguration::TRotation)mode.iRotation); |
|
945 //This will return suitable config when display is connected |
|
946 //and UI size equal to smallest appmode when disconnected |
|
947 error = iDisplayPolicy->GetSizeModeConfiguration(aMode,config,sizeModePosition); |
|
948 //set appmode in policy |
|
949 if (iDisplayMapping) |
|
950 { |
|
951 iDisplayMapping->SetSizeModeExtent(sizeModePosition,MWsDisplayMapping::KOffsetAll); |
|
952 } |
|
953 MWsScene::TSceneRotation oldRotation; |
|
954 TSize newUiSize; |
|
955 config.GetResolution(newUiSize); |
|
956 if (error == KErrNone) |
|
957 { |
|
958 oldRotation = iScene->SceneRotation(); |
|
959 //The config info will always be set in policy. If display is connected, policy will have |
|
960 //correct composition, Ui and app res. otherwise Ui and appmode will be both set to smallest |
|
961 //app mode, composition will be set to zero |
|
962 if (iFlags&EHasDynamicSizeModes) |
|
963 { |
|
964 error = iFallbackMap->Resize(newUiSize); |
|
965 } |
|
966 if (error == KErrNone) |
|
967 { |
|
968 error = iDisplayControl->SetConfiguration(config); |
|
969 } |
|
970 } |
|
971 if (error == KErrNone) |
|
972 { |
|
973 UpdateDynamicScreenModes(); |
|
974 AbortAllDirectDrawing(RDirectScreenAccess::ETerminateScreenMode); |
|
975 |
|
976 if(iDsaDevice && iDsaDevice->GraphicsAccelerator()) |
|
977 { |
|
978 iDsaDevice->ChangeScreenDevice(iDsaDevice); // orientation has changed, therefore we need to re-initialise the screen device's graphics accelerator |
|
979 } |
|
980 |
|
981 iScreenSizeMode=aMode; |
|
982 //This could fail (to set orientation on the context, or to register the rotated DSA). |
|
983 //Previously, the update rotation was deferred, leaving the size mode out of step with the actual rotation |
|
984 //It also returns false if the orientation is "intentionally" not modified. |
|
985 (void) UpdateOrientation(&oldRotation); |
|
986 |
|
987 //SetDigitiserAreas needs revisiting if/when we support dynamic resolutions |
|
988 //on a screen with touch input. |
|
989 //SetDigitiserAreas(newUiSize); |
|
990 |
|
991 CWsWindowGroup::SetScreenDeviceValidStates(this); |
|
992 |
|
993 if (!aInsideStartup) |
|
994 { |
|
995 iWindowElementSet->ResubmitAllElementExtents(); |
|
996 //TODO jonas: we'd like to not have to clear at all... make the actual change to compositor etc lazily! |
|
997 if(BlankScreenOnRotation()) |
|
998 { |
|
999 iRootWindow->ClearDisplay(); |
|
1000 } |
|
1001 |
|
1002 CWsTop::ClearAllRedrawStores(); |
|
1003 DiscardAllSchedules(); |
|
1004 iRootWindow->InvalidateWholeScreen(); |
|
1005 } |
|
1006 } |
|
1007 } |
|
1008 else |
|
1009 { |
|
1010 if (iDisplayMapping) |
|
1011 { |
|
1012 TRect sizeModePosition; |
|
1013 TRAPD(err,sizeModePosition=TRect(OriginL(aMode),ScreenModeSizeInPixelsL(aMode))); |
|
1014 if (err==KErrNone) |
|
1015 { |
|
1016 iDisplayMapping->SetSizeModeExtent(sizeModePosition,MWsDisplayMapping::KOffsetAll); |
|
1017 } |
|
1018 } |
|
1019 if (!aInsideStartup && (*iModes)[aMode]->iOrigin != (*iModes)[iScreenSizeMode]->iOrigin) |
|
1020 { |
|
1021 iWindowElementSet->ResubmitAllElementExtents(); |
|
1022 if ((*iModes)[aMode]->iRotation == (*iModes)[iScreenSizeMode]->iRotation) |
|
1023 { |
|
1024 //TODO jonas: we'd like to not have to clear at all... make the actual change to compositor etc lazily! |
|
1025 if(BlankScreenOnRotation()) |
|
1026 { |
|
1027 iRootWindow->ClearDisplay(); |
|
1028 } |
|
1029 |
|
1030 CWsTop::ClearAllRedrawStores(); |
|
1031 DiscardAllSchedules(); |
|
1032 iRootWindow->InvalidateWholeScreen(); |
|
1033 } |
|
1034 } |
|
1035 iScreenSizeMode=aMode; |
|
1036 //This could fail (to set orientation on the context, or to register the rotated DSA). |
|
1037 //Previously, the update rotation was deferred, leaving the size mode out of step with the actual rotation |
|
1038 //It also returns false if the orientation is not modified. |
|
1039 (void)UpdateOrientation(); |
|
1040 CWsWindowGroup::SetScreenDeviceValidStates(this); |
|
1041 } |
|
1042 TWindowServerEvent::SendScreenDeviceChangedEvents(this); |
|
1043 ResetFocus(NULL); |
|
1044 } |
|
1045 |
|
1046 void CScreen::CycleOrientation() |
|
1047 { |
|
1048 WS_ASSERT_DEBUG(IsValidScreenSizeMode(iScreenSizeMode),EWsPanicInvalidScreenSizeMode); |
|
1049 TSizeMode& currentSizeMode=*(*iModes)[iScreenSizeMode]; |
|
1050 TUint rotations=currentSizeMode.iAlternativeRotations; |
|
1051 TInt currentRotation=currentSizeMode.iRotation; |
|
1052 TInt rotation=currentRotation+1; |
|
1053 while (rotation!=currentRotation) |
|
1054 { |
|
1055 if (rotation>CFbsBitGc::EGraphicsOrientationRotated270) |
|
1056 rotation=CFbsBitGc::EGraphicsOrientationNormal; |
|
1057 if (ROTATION_TO_FLAG(rotation)&rotations) |
|
1058 break; |
|
1059 ++rotation; |
|
1060 } |
|
1061 if (rotation==currentRotation) |
|
1062 { |
|
1063 if (rotation>CFbsBitGc::EGraphicsOrientationRotated90) |
|
1064 rotation-=2; |
|
1065 else |
|
1066 rotation+=2; |
|
1067 } |
|
1068 currentSizeMode.iRotation=REINTERPRET_CAST(CFbsBitGc::TGraphicsOrientation&,rotation); |
|
1069 CWsWindowGroup::NewOrientation(iScreenSizeMode,currentSizeMode.iRotation, iRootWindow); |
|
1070 |
|
1071 if (!UpdateOrientation()) |
|
1072 { |
|
1073 // Roll back earlier changes |
|
1074 currentSizeMode.iRotation=REINTERPRET_CAST(CFbsBitGc::TGraphicsOrientation&,currentRotation); |
|
1075 CWsWindowGroup::NewOrientation(iScreenSizeMode, currentSizeMode.iRotation, iRootWindow); |
|
1076 } |
|
1077 } |
|
1078 |
|
1079 /** |
|
1080 * This method is called either when switching screen size mode, or when the |
|
1081 * orientation of the currently active screen size mode is changed. |
|
1082 */ |
|
1083 TBool CScreen::UpdateOrientation(MWsScene::TSceneRotation* aOldRotation) |
|
1084 { |
|
1085 CFbsBitGc::TGraphicsOrientation gcOrientation = Orientation(); |
|
1086 |
|
1087 MWsScene::TSceneRotation oldRotation = aOldRotation? (*aOldRotation):(iScene->SceneRotation()); |
|
1088 MWsScene::TSceneRotation newRotation = GcToScreen(gcOrientation); |
|
1089 TDeviceOrientation newDeviceOrientation = GcToDevice(gcOrientation); |
|
1090 |
|
1091 // We have to disable the text cursor here while we are still in the |
|
1092 // same orientation or offset as we drew it. |
|
1093 RWsTextCursor* cursor = CWsTop::CurrentTextCursor(); |
|
1094 if (cursor) |
|
1095 { |
|
1096 cursor->Disable(); |
|
1097 } |
|
1098 |
|
1099 // Some of this method has to be done when changing mode even if not changing rotation |
|
1100 TBool rotating=(oldRotation != newRotation); |
|
1101 if (rotating) |
|
1102 { |
|
1103 |
|
1104 // Set the new screen rotation and update the UI element extent |
|
1105 if (iScene->SetSceneRotation(newRotation) != KErrNone) |
|
1106 return EFalse; |
|
1107 // Set the new orientation for the DSA device and update the DSA surface |
|
1108 if(iDsaDevice) |
|
1109 { |
|
1110 iDsaDevice->SetDeviceOrientation(newDeviceOrientation); |
|
1111 |
|
1112 TSurfaceId newSurface; |
|
1113 iDsaDevice->GetSurface(newSurface); |
|
1114 TInt errRegister = iScene->RegisterSurface(newSurface); |
|
1115 WS_ASSERT_DEBUG(KErrNone == errRegister, EWsPanicDirectScreenAccess); |
|
1116 // This will remove all the DSA elements from the scene |
|
1117 AbortAllDirectDrawing(RDirectScreenAccess::ETerminateRotation); |
|
1118 |
|
1119 TInt errUnregister = iScene->UnregisterSurface(iDsaSurface); |
|
1120 WS_ASSERT_DEBUG(KErrNone == errUnregister, EWsPanicDirectScreenAccess); |
|
1121 iDsaSurface = newSurface; |
|
1122 } |
|
1123 |
|
1124 //updaterotation should not fail after this point (no cleanup) |
|
1125 |
|
1126 TWservCrEvent crEvent(TWservCrEvent::EDeviceOrientationChanged,iScreenNumber,&gcOrientation); |
|
1127 TWindowServerEvent::NotifyDrawer(crEvent); |
|
1128 |
|
1129 if(iDsaDevice && iDsaDevice->GraphicsAccelerator()) |
|
1130 { |
|
1131 iDsaDevice->ChangeScreenDevice(iDsaDevice); // orientation has changed, therefore we need to re-initialise the screen device's graphics accelerator |
|
1132 } |
|
1133 |
|
1134 } |
|
1135 |
|
1136 iRootWindow->AdjustCoordsDueToRotation(); |
|
1137 if (rotating) |
|
1138 { |
|
1139 if(BlankScreenOnRotation()) |
|
1140 { |
|
1141 iRootWindow->ClearDisplay(); |
|
1142 } |
|
1143 |
|
1144 CWsTop::ClearAllRedrawStores(); |
|
1145 DiscardAllSchedules(); |
|
1146 iRootWindow->InvalidateWholeScreen(); |
|
1147 } |
|
1148 return ETrue; |
|
1149 } |
|
1150 |
|
1151 TPoint CScreen::PhysicalToLogical(TPoint aPhysicalPt) |
|
1152 { |
|
1153 const TSizeMode& mode=ScreenSizeModeData(); |
|
1154 TPoint logicalPt; |
|
1155 if(!iDisplayMapping) |
|
1156 { |
|
1157 //old behaviour |
|
1158 logicalPt=aPhysicalPt-mode.iOrigin; |
|
1159 if (mode.iScreenScale.iWidth!=1) |
|
1160 logicalPt.iX=(logicalPt.iX>=0 ? logicalPt.iX/mode.iScreenScale.iWidth : (logicalPt.iX-(mode.iScreenScale.iWidth-1))/mode.iScreenScale.iWidth); |
|
1161 if (mode.iScreenScale.iHeight!=1) |
|
1162 logicalPt.iY=(logicalPt.iY>=0 ? logicalPt.iY/mode.iScreenScale.iHeight : (logicalPt.iY-(mode.iScreenScale.iHeight-1))/mode.iScreenScale.iHeight); |
|
1163 } |
|
1164 else |
|
1165 { |
|
1166 //rect with dummy size for coordinates mapping purpose |
|
1167 TRect rectInComp(aPhysicalPt, TSize(1,1)); |
|
1168 TRect rectInApp; |
|
1169 iDisplayMapping->MapCoordinates(ECompositionSpace, rectInComp, EApplicationSpace,rectInApp); |
|
1170 logicalPt = rectInApp.iTl; |
|
1171 } |
|
1172 |
|
1173 return logicalPt; |
|
1174 } |
|
1175 |
|
1176 void CScreen::LoadScreenSizesL(TSize aScreenSize) |
|
1177 { |
|
1178 _LIT(KWSERVNumScrSizeMode, "NUMSCREENMODES"); |
|
1179 TBool allowScrGap=WsIniFile->FindVar(iScreenNumber, KWSERVNumScrSizeMode, iNumScreenSizeModes); |
|
1180 iModes=new(ELeave) RPointerArray<TInternalSizeMode>(1); |
|
1181 WS_ASSERT_DEBUG(!allowScrGap || (allowScrGap && iNumScreenSizeModes>0), EWsPanicInvalidScreenSizeMode); |
|
1182 TInt screenNum=0; |
|
1183 FOREVER |
|
1184 { |
|
1185 ++screenNum; |
|
1186 TBuf<32> varNameWidth; |
|
1187 TBuf<32> varNameHeight; |
|
1188 _LIT(KWSERVScreenWidthPattern,"SCR_WIDTH%d"); |
|
1189 varNameWidth.Format(KWSERVScreenWidthPattern,screenNum); |
|
1190 _LIT(KWSERVScreenHeightPattern,"SCR_HEIGHT%d"); |
|
1191 varNameHeight.Format(KWSERVScreenHeightPattern,screenNum); |
|
1192 TSize screenSize; |
|
1193 if (!WsIniFile->FindVar(iScreenNumber, varNameWidth, screenSize.iWidth) || |
|
1194 !WsIniFile->FindVar(iScreenNumber, varNameHeight, screenSize.iHeight)) |
|
1195 { |
|
1196 if (allowScrGap && screenNum<=iNumScreenSizeModes) |
|
1197 { |
|
1198 iModes->AppendL(NULL); |
|
1199 continue; |
|
1200 } |
|
1201 else |
|
1202 break; |
|
1203 } |
|
1204 TInt flags=0; |
|
1205 if (screenSize.iWidth==0 && screenSize.iHeight==0) |
|
1206 { |
|
1207 screenSize=aScreenSize; |
|
1208 flags|=EHalDefault; |
|
1209 } |
|
1210 if (screenSize.iWidth==-1 && screenSize.iHeight==-1) |
|
1211 { |
|
1212 screenSize=aScreenSize; |
|
1213 flags|=EDynamic; |
|
1214 iFlags|=EHasDynamicSizeModes; |
|
1215 } |
|
1216 TInternalSizeMode* newSizeMode=new(ELeave) TInternalSizeMode(screenSize); |
|
1217 newSizeMode->iFlags|=flags; |
|
1218 CleanupStack::PushL(newSizeMode); |
|
1219 iModes->AppendL(newSizeMode); |
|
1220 CleanupStack::Pop(newSizeMode); |
|
1221 ++iNumSupportedScreenSizeModes; |
|
1222 } |
|
1223 // If sparse index is enabled and no screen size mode defined, all iModes entries will be NULL |
|
1224 // Otherwise iModes will be empty |
|
1225 if (iModes->Count()==0 || iNumSupportedScreenSizeModes==0) |
|
1226 { |
|
1227 TInternalSizeMode* defaultSizeMode=new(ELeave) TInternalSizeMode(aScreenSize); |
|
1228 defaultSizeMode->iFlags|=EHalDefault; |
|
1229 if (iModes->Count()>0) |
|
1230 (*iModes)[0]=defaultSizeMode; |
|
1231 else |
|
1232 { |
|
1233 CleanupStack::PushL(defaultSizeMode); |
|
1234 iModes->AppendL(defaultSizeMode); |
|
1235 CleanupStack::Pop(defaultSizeMode); |
|
1236 } |
|
1237 ++iNumSupportedScreenSizeModes; |
|
1238 } |
|
1239 if (!allowScrGap) |
|
1240 iNumScreenSizeModes=iNumSupportedScreenSizeModes; |
|
1241 } |
|
1242 |
|
1243 void CScreen::LoadScreenRotationProperties(TInternalSizeMode& aMode, const TInt aModeIndex) |
|
1244 { |
|
1245 TBuf<32> varRotation; |
|
1246 _LIT(KWSERVScreenRotationPattern,"SCR_ROTATION%d"); |
|
1247 varRotation.Format(KWSERVScreenRotationPattern,aModeIndex+1); |
|
1248 TInt rotation=CFbsBitGc::EGraphicsOrientationNormal; |
|
1249 TUint allRotations=0; |
|
1250 TPtrC rotList(NULL,0); |
|
1251 if (WsIniFile->FindVar( iScreenNumber, varRotation,rotList)) |
|
1252 { |
|
1253 TLex lex(rotList); |
|
1254 TBool foundOne=EFalse; |
|
1255 TInt rot; |
|
1256 |
|
1257 while (!lex.Eos()) |
|
1258 { |
|
1259 if (!FindNextValue(lex, rot)) |
|
1260 { |
|
1261 break; |
|
1262 } |
|
1263 if (rot<0 || rot>360) |
|
1264 { |
|
1265 continue; |
|
1266 } |
|
1267 if (rot>4) |
|
1268 { |
|
1269 rot/=90; |
|
1270 } |
|
1271 if (!foundOne) |
|
1272 { |
|
1273 rotation=rot; |
|
1274 foundOne=ETrue; |
|
1275 } |
|
1276 if (rot<=CFbsBitGc::EGraphicsOrientationRotated270) |
|
1277 { |
|
1278 allRotations|=ROTATION_TO_FLAG(rot); |
|
1279 } |
|
1280 } |
|
1281 } |
|
1282 if (allRotations==0) |
|
1283 allRotations=ROTATION_TO_FLAG(rotation); |
|
1284 const TInt KAllRotationsMask = 0xF; //Used to keep the old behaviour |
|
1285 WS_ASSERT_ALWAYS((ROTATION_TO_FLAG(rotation)&KAllRotationsMask)>0, EWsPanicFailedToInitialise); |
|
1286 aMode.iRotation=reinterpret_cast<CFbsBitGc::TGraphicsOrientation&>(rotation); |
|
1287 aMode.iAlternativeRotations=allRotations&KAllRotationsMask; |
|
1288 } |
|
1289 |
|
1290 void CScreen::LoadScreenTwipsProperties(TInternalSizeMode& aMode, const TInt aModeIndex) |
|
1291 { |
|
1292 TBuf<32> varNameWidth; |
|
1293 _LIT(KWSERVScreenTwipWidthPattern,"SCR_TWIP_WIDTH%d"); |
|
1294 varNameWidth.Format(KWSERVScreenTwipWidthPattern,aModeIndex+1); |
|
1295 TBuf<32> varNameHeight; |
|
1296 _LIT(KWSERVScreenTwipHeightPattern,"SCR_TWIP_HEIGHT%d"); |
|
1297 varNameHeight.Format(KWSERVScreenTwipHeightPattern,aModeIndex+1); |
|
1298 |
|
1299 TSize twipsSize; |
|
1300 TBool widthFound = WsIniFile->FindVar(iScreenNumber,varNameWidth,twipsSize.iWidth); |
|
1301 TBool heightFound = WsIniFile->FindVar(iScreenNumber,varNameHeight,twipsSize.iHeight); |
|
1302 |
|
1303 // if either of the width or height wsini reads has failed we need to generate default values |
|
1304 switch(aMode.iRotation) |
|
1305 { |
|
1306 // CFbsBitGc::TGraphicsOrientation |
|
1307 case CFbsBitGc::EGraphicsOrientationRotated90: // deliberate drop-through |
|
1308 case CFbsBitGc::EGraphicsOrientationRotated270: |
|
1309 { |
|
1310 // CFbsScreenDevice knows nothing about rotation, so we can't use it's PixelsTo Twips methods |
|
1311 // So swap the axis here to use the correct twips per pixel ratio |
|
1312 if (!widthFound) |
|
1313 twipsSize.iWidth = DeviceMap().VerticalPixelsToTwips(aMode.iScreenSize.iWidth); |
|
1314 if (!heightFound) |
|
1315 twipsSize.iHeight = DeviceMap().HorizontalPixelsToTwips(aMode.iScreenSize.iHeight); |
|
1316 break; |
|
1317 } |
|
1318 case CFbsBitGc::EGraphicsOrientationNormal: // deliberate drop-through |
|
1319 case CFbsBitGc::EGraphicsOrientationRotated180: |
|
1320 if (!widthFound) |
|
1321 twipsSize.iWidth = DeviceMap().HorizontalPixelsToTwips(aMode.iScreenSize.iWidth); |
|
1322 if (!heightFound) |
|
1323 twipsSize.iHeight = DeviceMap().VerticalPixelsToTwips(aMode.iScreenSize.iHeight); |
|
1324 break; |
|
1325 default: |
|
1326 RDebug::Print(_L("** CScreen::LoadScreenTwipsProperties Panic")); |
|
1327 WS_PANIC_ALWAYS(EWsPanicFailedToInitialise); |
|
1328 break; |
|
1329 } |
|
1330 if (widthFound&&heightFound) |
|
1331 { |
|
1332 aMode.iFlags|=this->ETwipsSpecified; |
|
1333 } |
|
1334 aMode.iScreenTwipsSize=twipsSize; |
|
1335 } |
|
1336 |
|
1337 |
|
1338 void CScreen::LoadScreenSizeProperties(TDisplayMode aDefaultDisplayMode) |
|
1339 { |
|
1340 for(TInt sizeLoop=0;sizeLoop<iModes->Count();sizeLoop++) |
|
1341 { |
|
1342 TInternalSizeMode* modePtr=(*iModes)[sizeLoop]; |
|
1343 if (!modePtr) |
|
1344 continue; |
|
1345 TInternalSizeMode& mode=*modePtr; |
|
1346 TBuf<32> varDisplayMode; |
|
1347 _LIT(KWSERVScreenDisplayModePattern,"SCR_WINDOWMODE%d"); |
|
1348 |
|
1349 varDisplayMode.Format(KWSERVScreenDisplayModePattern,sizeLoop+1); |
|
1350 mode.iScreenScale.iWidth=1; |
|
1351 mode.iScreenScale.iHeight=1; |
|
1352 |
|
1353 TBuf<32> varLeft; |
|
1354 TBuf<32> varTop; |
|
1355 _LIT(KWSERVScreenLeftPattern,"SCR_LEFT%d"); |
|
1356 _LIT(KWSERVScreenTopPattern,"SCR_TOP%d"); |
|
1357 varLeft.Format(KWSERVScreenLeftPattern,sizeLoop+1); |
|
1358 varTop.Format(KWSERVScreenTopPattern,sizeLoop+1); |
|
1359 if (!WsIniFile->FindVar( iScreenNumber, varLeft,mode.iOrigin.iX)) |
|
1360 mode.iOrigin.iX=0; |
|
1361 if (!WsIniFile->FindVar( iScreenNumber, varTop,mode.iOrigin.iY)) |
|
1362 mode.iOrigin.iY=0; |
|
1363 |
|
1364 TPtrC displayModeName(NULL,0); |
|
1365 mode.iDefaultDisplayMode = aDefaultDisplayMode; |
|
1366 // must know rotation before parsing twips |
|
1367 LoadScreenRotationProperties(mode, sizeLoop); |
|
1368 LoadScreenTwipsProperties(mode, sizeLoop); |
|
1369 |
|
1370 |
|
1371 if(mode.iScreenSize.iWidth == mode.iScreenSize.iHeight && mode.iAlternativeRotations == allRotationsMask) |
|
1372 { |
|
1373 //square appmode with all four rotations allowed must have square twipsize |
|
1374 if((mode.iFlags&ETwipsSpecified) && mode.iScreenTwipsSize.iWidth != mode.iScreenTwipsSize.iHeight) |
|
1375 { |
|
1376 RDebug::Print(_L("**Panic: Square appmode with all four rotations must have square twip size")); |
|
1377 WS_PANIC_ALWAYS(EWsPanicFailedToInitialise); |
|
1378 } |
|
1379 //square appmode with all four rotations allowed must have square offset |
|
1380 if(mode.iOrigin.iX != mode.iOrigin.iY) |
|
1381 { |
|
1382 RDebug::Print(_L("**Panic: Square appmode with all four rotations must have square offset")); |
|
1383 WS_PANIC_ALWAYS(EWsPanicFailedToInitialise); |
|
1384 } |
|
1385 } |
|
1386 else |
|
1387 { |
|
1388 //Everything else is treated as rectangle appmode. Square appmode not supporting all 4 rotations is considered |
|
1389 //as rectangle appmode as well. Rectangle appmode suports 2 rotations at most (0 and 180, or 90 and 270) |
|
1390 //first rotation of the appmode is taken to apply the corresponding rotation mask |
|
1391 if(!((mode.iAlternativeRotations&KRotation0_180Mask) == mode.iAlternativeRotations |
|
1392 || (mode.iAlternativeRotations&KRotation90_270Mask) == mode.iAlternativeRotations)) |
|
1393 { |
|
1394 RDebug::Print(_L("**Panic_DEBUG: non square appmode can only define (0,180) or (90,270) rotations")); |
|
1395 WS_PANIC_DEBUG(EWsPanicFailedToInitialise); |
|
1396 //in relase build, no panic, just correct the rotations set |
|
1397 |
|
1398 } |
|
1399 //correct the rotations set |
|
1400 mode.iAlternativeRotations &= ((ROTATION_TO_FLAG(mode.iRotation) & KRotation0_180Mask)? KRotation0_180Mask: |
|
1401 KRotation90_270Mask); |
|
1402 } |
|
1403 |
|
1404 } |
|
1405 // |
|
1406 TInt intForFindVar=0; |
|
1407 _LIT(KWSERVIniFileVarSizeMode,"SIZE_MODE"); |
|
1408 WsIniFile->FindVar( iScreenNumber, KWSERVIniFileVarSizeMode,intForFindVar); |
|
1409 iSizeEnforcementMode=(TScreenModeEnforcement)intForFindVar; |
|
1410 } |
|
1411 |
|
1412 void CScreen::SetDigitiserAreas(const TSize& aUiSize) |
|
1413 { //aUiSize should be the unrotated current ui size |
|
1414 //SetDigitiserAreas needs revisiting if/when we support dynamic resolutions on a screen |
|
1415 //with touch input. It is not known how digitiser coordinates will be represented if the |
|
1416 //physical display resolution changes. Currently digitisers are only supported on screen 0, |
|
1417 //and dynamic resolution only applies to higher screen numbers on real hardware. |
|
1418 for(TInt sizeLoop=0;sizeLoop<iModes->Count();sizeLoop++) |
|
1419 { |
|
1420 TInternalSizeMode* modePtr=(*iModes)[sizeLoop]; |
|
1421 if (!modePtr) |
|
1422 continue; |
|
1423 TInternalSizeMode& mode=*modePtr; |
|
1424 if(mode.iFlags & EClientDefinedDigitiserArea) |
|
1425 { |
|
1426 //if it's client set, keep it unchanged. |
|
1427 continue; |
|
1428 } |
|
1429 switch (mode.iRotation) |
|
1430 { |
|
1431 case CFbsBitGc::EGraphicsOrientationNormal: |
|
1432 mode.iPointerCursorArea=iDigitiserArea; |
|
1433 continue; |
|
1434 case CFbsBitGc::EGraphicsOrientationRotated90: |
|
1435 mode.iPointerCursorArea.SetRect(iDigitiserArea.iTl.iY,aUiSize.iWidth-iDigitiserArea.iBr.iX, |
|
1436 iDigitiserArea.iBr.iY,aUiSize.iWidth-iDigitiserArea.iTl.iX); |
|
1437 break; |
|
1438 case CFbsBitGc::EGraphicsOrientationRotated180: |
|
1439 mode.iPointerCursorArea.SetRect(-(iDigitiserArea.iBr-aUiSize),-(iDigitiserArea.iTl-aUiSize)); |
|
1440 break; |
|
1441 case CFbsBitGc::EGraphicsOrientationRotated270: |
|
1442 mode.iPointerCursorArea.SetRect(aUiSize.iHeight-iDigitiserArea.iBr.iY,iDigitiserArea.iTl.iX, |
|
1443 aUiSize.iHeight-iDigitiserArea.iTl.iY,iDigitiserArea.iBr.iX); |
|
1444 break; |
|
1445 default: |
|
1446 WS_PANIC_ALWAYS(EWsPanicInvalidRotation); |
|
1447 } |
|
1448 } |
|
1449 } |
|
1450 |
|
1451 void CScreen::GetScreenSizeAndRotation(TPixelsTwipsAndRotation &aSar, TInt aScreenMode) |
|
1452 { |
|
1453 TSizeMode& mode=*(*iModes)[aScreenMode]; |
|
1454 aSar.iRotation=mode.iRotation; |
|
1455 aSar.iPixelSize=mode.iScreenSize; |
|
1456 aSar.iTwipsSize=mode.iScreenTwipsSize; |
|
1457 if (aSar.iTwipsSize.iWidth==0) |
|
1458 { |
|
1459 aSar.iTwipsSize.iWidth = iDeviceMap->HorizontalPixelsToTwips(aSar.iPixelSize.iWidth); |
|
1460 aSar.iTwipsSize.iHeight = iDeviceMap->VerticalPixelsToTwips(aSar.iPixelSize.iHeight); |
|
1461 } |
|
1462 } |
|
1463 |
|
1464 void CScreen::GetScreenSizeAndRotation(TPixelsAndRotation &aSar, TInt aScreenMode) |
|
1465 { |
|
1466 TSizeMode& mode=*(*iModes)[aScreenMode]; |
|
1467 aSar.iRotation=mode.iRotation; |
|
1468 aSar.iPixelSize=mode.iScreenSize; |
|
1469 } |
|
1470 |
|
1471 TBool CScreen::SetScreenModeEnforcement(TInt aMode) |
|
1472 { |
|
1473 if (aMode<0 || aMode>ESizeEnforcementPixelsTwipsAndRotation) |
|
1474 return EFalse; |
|
1475 TScreenModeEnforcement newMode=(TScreenModeEnforcement)aMode; |
|
1476 if (newMode!=iSizeEnforcementMode) |
|
1477 { |
|
1478 iSizeEnforcementMode=newMode; |
|
1479 CWsWindowGroup::SetScreenDeviceValidStates(this); |
|
1480 ResetFocus(NULL); |
|
1481 } |
|
1482 return ETrue; |
|
1483 } |
|
1484 |
|
1485 void CScreen::IncContrast() |
|
1486 { |
|
1487 TInt contrast; |
|
1488 if (iMaxContrast<0) //If failed to get it sofar get it again |
|
1489 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrastMax,iMaxContrast)); |
|
1490 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrast,contrast))) |
|
1491 return; |
|
1492 if (contrast==iMaxContrast) |
|
1493 contrast=-1; |
|
1494 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Set(iScreenNumber,HALData::EDisplayContrast,++contrast)); |
|
1495 } |
|
1496 |
|
1497 void CScreen::DecContrast() |
|
1498 { |
|
1499 TInt contrast; |
|
1500 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrast,contrast))) |
|
1501 return; |
|
1502 if (contrast==0) |
|
1503 { |
|
1504 if (iMaxContrast<0 && TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, |
|
1505 HAL::Get(iScreenNumber,HALData::EDisplayContrastMax,iMaxContrast))) |
|
1506 return; |
|
1507 contrast=iMaxContrast+1; |
|
1508 } |
|
1509 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Set(iScreenNumber,HALData::EDisplayContrast,--contrast)); |
|
1510 } |
|
1511 |
|
1512 void CScreen::IncBrightness() |
|
1513 { |
|
1514 TInt brightness; |
|
1515 if (iMaxBrightness<0) //If failed to get it sofar get it again |
|
1516 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightnessMax,iMaxBrightness)); |
|
1517 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightness,brightness))) |
|
1518 return; |
|
1519 if (brightness==iMaxBrightness) |
|
1520 brightness=-1; |
|
1521 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(iScreenNumber,HALData::EDisplayBrightness,++brightness)); |
|
1522 } |
|
1523 |
|
1524 void CScreen::DecBrightness() |
|
1525 { |
|
1526 TInt brightness; |
|
1527 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightness,brightness))) |
|
1528 return; |
|
1529 if (brightness==0) |
|
1530 { |
|
1531 if (iMaxBrightness<0 && TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, |
|
1532 HAL::Get(iScreenNumber,HALData::EDisplayBrightnessMax,iMaxBrightness))) |
|
1533 return; |
|
1534 brightness=iMaxBrightness+1; |
|
1535 } |
|
1536 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(iScreenNumber,HALData::EDisplayBrightness,--brightness)); |
|
1537 } |
|
1538 TInt CScreen::GetScreenSizeModeList(RArray<TInt>& aList) const |
|
1539 { |
|
1540 aList.Reset(); |
|
1541 TInt numModes=iNumScreenSizeModes; |
|
1542 TInt err=aList.Reserve(numModes); |
|
1543 if (err!=KErrNone) |
|
1544 return err; |
|
1545 TInt index; |
|
1546 for (index=0; index<numModes; ++index) |
|
1547 { |
|
1548 TSizeMode* modePtr=(*iModes)[index]; |
|
1549 if (modePtr) |
|
1550 aList.Append(index); //Can't fail due to reserve |
|
1551 } |
|
1552 TInt count=aList.Count(); |
|
1553 return count; |
|
1554 } |
|
1555 |
|
1556 TInt CScreen::GetScreenSizeModeListL() |
|
1557 { |
|
1558 RArray<TInt> list; |
|
1559 CleanupClosePushL(list); |
|
1560 TInt count=GetScreenSizeModeList(list); |
|
1561 User::LeaveIfError(count); |
|
1562 CWsClient::ReplyBuf(&list[0], count*sizeof(TInt)); |
|
1563 CleanupStack::PopAndDestroy(&list); |
|
1564 return count; |
|
1565 } |
|
1566 |
|
1567 void CScreen::SetInitialScreenSizeModeAndRotation() |
|
1568 { //Set first app mode that supports current supported rotations if available |
|
1569 TInt index; |
|
1570 TInt firstMode = -1; |
|
1571 TInt bestMode = -1; |
|
1572 // Since all screen rotation modes are supported. |
|
1573 TBitFlags32 rotationFlags = CFbsBitGc::EGraphicsOrientationNormal|CFbsBitGc::EGraphicsOrientationRotated90|CFbsBitGc::EGraphicsOrientationRotated180|CFbsBitGc::EGraphicsOrientationRotated270; |
|
1574 for (index=0; index<iModes->Count(); ++index) |
|
1575 { |
|
1576 TSizeMode* modePtr=(*iModes)[index]; |
|
1577 if (modePtr) |
|
1578 { |
|
1579 if (firstMode == -1) |
|
1580 { |
|
1581 firstMode = index; |
|
1582 } |
|
1583 if (rotationFlags.IsSet((TInt)modePtr->iRotation)) |
|
1584 { |
|
1585 bestMode = index; |
|
1586 break; |
|
1587 } |
|
1588 } |
|
1589 } |
|
1590 |
|
1591 if (bestMode != -1) //found a mode that supports current supported rotations |
|
1592 { |
|
1593 iScreenSizeMode = bestMode; |
|
1594 } |
|
1595 else |
|
1596 { |
|
1597 if (firstMode != -1) //could only find a mode that doesnt support current supported rotations |
|
1598 { |
|
1599 iScreenSizeMode = firstMode; |
|
1600 } |
|
1601 else |
|
1602 { |
|
1603 return; //couldn't find a mode at all |
|
1604 } |
|
1605 } |
|
1606 if(iDisplayPolicy) |
|
1607 { |
|
1608 iDisplayPolicy->SetLastAppMode(iScreenSizeMode); |
|
1609 } |
|
1610 |
|
1611 SetDigitiserAreas(iScreenDevice->SizeInPixels()); //unrotated size in pixels |
|
1612 |
|
1613 // Here we are mixing CFbsBitGc::TGraphicsOrientation with MWsScene::TSceneRotation |
|
1614 // As they both have same values it is fine for now |
|
1615 iScene->SetSceneRotation(GcToScreen(ScreenSizeModeData().iRotation)); //set rotation |
|
1616 } |
|
1617 |
|
1618 |
|
1619 TDisplayMode CScreen::FirstDefaultDisplayMode() const |
|
1620 { |
|
1621 TInt mode=-1; |
|
1622 while ((*iModes)[++mode]==NULL) |
|
1623 { |
|
1624 WS_ASSERT_DEBUG(mode<iModes->Count()-1,EWsPanicInvalidScreenSizeMode); |
|
1625 } |
|
1626 return((*iModes)[mode]->iDefaultDisplayMode); |
|
1627 } |
|
1628 |
|
1629 void CScreen::AddRedrawRegion(const TRegion& aRegion, TBool aSchedule, TRedrawDepth aDepth) |
|
1630 { |
|
1631 iRedraw->AddRedrawRegion(aRegion, aSchedule, aDepth); |
|
1632 } |
|
1633 |
|
1634 void CScreen::ScheduleRender(const TTimeIntervalMicroSeconds& aFromNow) |
|
1635 { |
|
1636 iRedraw->ScheduleRender(aFromNow); |
|
1637 } |
|
1638 |
|
1639 void CScreen::DoRedrawNow() |
|
1640 { |
|
1641 iRedraw->DoRedrawNow(); |
|
1642 } |
|
1643 |
|
1644 // See CScreenRedraw::IsUpdatePending() for important notes on usage. |
|
1645 void CScreen::RedrawNowIfPending() |
|
1646 { |
|
1647 if(iRedraw->IsUpdatePending()) |
|
1648 DoRedrawNow(); |
|
1649 } |
|
1650 |
|
1651 TBool CScreen::IsQuickFadeScheduled( CWsWindow* aWin ) const |
|
1652 { |
|
1653 return iRedraw->IsQuickFadeScheduled( aWin ); |
|
1654 } |
|
1655 |
|
1656 void CScreen::RemoveFromQuickFadeList( CWsWindow* aWin ) |
|
1657 { |
|
1658 iRedraw->RemoveFromQuickFadeList( aWin ); |
|
1659 } |
|
1660 |
|
1661 void CScreen::AcceptFadeRequest( CWsWindow* aWin, TBool aIsFaded ) |
|
1662 { |
|
1663 iRedraw->AcceptFadeRequest( aWin, aIsFaded ); |
|
1664 } |
|
1665 |
|
1666 // implementing MWsScreen |
|
1667 |
|
1668 const TTime& CScreen::Now() const |
|
1669 { |
|
1670 return iRedraw->Now(); |
|
1671 } |
|
1672 |
|
1673 void CScreen::ScheduleAnimation(TAnimType aType, const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow,const TTimeIntervalMicroSeconds& aFreq,const TTimeIntervalMicroSeconds& aStop, CWsWindow* aWindow) |
|
1674 { |
|
1675 iRedraw->ScheduleAnimation(aType, aRect,aFromNow,aFreq,aStop, aWindow); |
|
1676 } |
|
1677 |
|
1678 TBool CScreen::IsScheduled(TAnimType aType, const TRect& aRect, CWsWindow* aWindow) const |
|
1679 { |
|
1680 return iRedraw->IsScheduled(aType, aRect, aWindow); |
|
1681 } |
|
1682 |
|
1683 void CScreen::OnAnimation(TRequestStatus* aFinished) |
|
1684 { |
|
1685 iRedraw->OnAnimation(aFinished); |
|
1686 } |
|
1687 |
|
1688 void CScreen::Redraw() |
|
1689 { |
|
1690 STACK_REGION bounds; |
|
1691 bounds.AddRect(DrawableArea()); |
|
1692 AddRedrawRegion(bounds); |
|
1693 bounds.Close(); |
|
1694 } |
|
1695 |
|
1696 TBool CScreen::RedrawInvalid(const TArray<TGraphicDrawerId>& aInvalid) |
|
1697 { |
|
1698 TBool wasDirty = EFalse; |
|
1699 STACK_REGION bounds; |
|
1700 bounds.AddRect(DrawableArea()); |
|
1701 STACK_REGION dirty; |
|
1702 TWalkWindowTreeCalcInvalidGraphics calc(&bounds,dirty,aInvalid); |
|
1703 if(calc.CreateSubRegion()) |
|
1704 { |
|
1705 calc.CalcInvalid(*this); |
|
1706 if(dirty.CheckError() || dirty.Count()) |
|
1707 { |
|
1708 Redraw(); |
|
1709 wasDirty = ETrue; |
|
1710 } |
|
1711 calc.DestroyRegions(); |
|
1712 } |
|
1713 dirty.Close(); |
|
1714 bounds.Close(); |
|
1715 return wasDirty; |
|
1716 } |
|
1717 |
|
1718 /** |
|
1719 Overidding MWsObjectProvider |
|
1720 */ |
|
1721 TAny* CScreen::ResolveObjectInterface(TUint aTypeId) |
|
1722 { |
|
1723 TAny* interface = NULL; |
|
1724 |
|
1725 switch (aTypeId) |
|
1726 { |
|
1727 case MWsWindow::EWsObjectInterfaceId: |
|
1728 interface = static_cast<MWsWindow*>(RootWindow()); |
|
1729 break; |
|
1730 case MWsScreenConfigList::EWsObjectInterfaceId: |
|
1731 interface = static_cast<MWsScreenConfigList*>(this); |
|
1732 break; |
|
1733 case MWsScreenConfig::EWsObjectInterfaceId: |
|
1734 interface = static_cast<MWsScreenConfig*>(this); |
|
1735 break; |
|
1736 case MWsWindowTree::EWsObjectInterfaceId: |
|
1737 interface = static_cast<MWsWindowTree*>(this); |
|
1738 } |
|
1739 |
|
1740 if (!interface) |
|
1741 interface = iRedraw->ResolveObjectInterface(aTypeId); |
|
1742 |
|
1743 return interface; |
|
1744 } |
|
1745 |
|
1746 void CScreen::SendTree() const |
|
1747 { |
|
1748 if(!iWindowTreeObserver) |
|
1749 return; |
|
1750 |
|
1751 TWalkWindowTreeSendState wtw(*iWindowTreeObserver); |
|
1752 RootWindow()->WalkWindowTreeBackToFront(wtw, EVisitParentNodesFirst); |
|
1753 |
|
1754 //Standard text cursors |
|
1755 RWsTextCursor* cursor = CWsTop::CurrentTextCursor(); |
|
1756 if(cursor) |
|
1757 cursor->SendState(*iWindowTreeObserver); |
|
1758 |
|
1759 //Floating Sprites |
|
1760 SpriteManager()->SendState(*iWindowTreeObserver); |
|
1761 |
|
1762 //Window Group Chains |
|
1763 for(CWsWindowGroup *group=RootWindow()->Child(); group!=NULL; group=group->NextSibling()) |
|
1764 { |
|
1765 group->SendStateWindowGroupChain(*iWindowTreeObserver); |
|
1766 } |
|
1767 } |
|
1768 |
|
1769 TDisplayMode CScreen::DisplayMode() const |
|
1770 { |
|
1771 return iScreenDevice->DisplayMode(); |
|
1772 } |
|
1773 |
|
1774 TSize CScreen::SizeInPixels() const |
|
1775 { |
|
1776 return iScreenDevice->SizeInPixels(); |
|
1777 } |
|
1778 |
|
1779 TSize CScreen::SizeInTwips() const |
|
1780 { |
|
1781 return iScreenDevice->SizeInTwips(); |
|
1782 } |
|
1783 |
|
1784 void CScreen::DiscardAllSchedules() |
|
1785 { |
|
1786 iRedraw->DiscardAllSchedules(); |
|
1787 } |
|
1788 |
|
1789 void CScreen::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty) |
|
1790 { |
|
1791 iRedraw->ScheduleRegionUpdate(aDefinitelyDirty); |
|
1792 } |
|
1793 |
|
1794 TBool CScreen::IsDSAClientWindow( const CWsClientWindow* aWin ) const |
|
1795 { |
|
1796 TBool res = EFalse; |
|
1797 if ( ! iDirects.IsEmpty() ) |
|
1798 { |
|
1799 TSglQueIter<CWsDirectScreenAccess> iter( (TSglQueBase&)iDirects ); |
|
1800 iter.SetToFirst(); |
|
1801 CWsDirectScreenAccess* dsa; |
|
1802 while ( (dsa = iter++) != NULL && !res ) |
|
1803 { |
|
1804 res = (dsa->ClientWindow() == aWin) && (dsa->IsVisible()); |
|
1805 } |
|
1806 } |
|
1807 return res; |
|
1808 } |
|
1809 |
|
1810 /** |
|
1811 Update the UI element composition method based on whether |
|
1812 there are any externals surfaces present and the current display mode. |
|
1813 If the method changes, recomposition is triggered. |
|
1814 */ |
|
1815 void CScreen::UpdateCompositionMode() |
|
1816 { |
|
1817 // do nothing |
|
1818 } |
|
1819 |
|
1820 void CScreen::ElementAdded() |
|
1821 { |
|
1822 UpdateCompositionMode(); |
|
1823 } |
|
1824 |
|
1825 void CScreen::ElementRemoved() |
|
1826 { |
|
1827 UpdateCompositionMode(); |
|
1828 } |
|
1829 |
|
1830 CRegisteredSurfaceMap* CScreen::SurfaceMap() |
|
1831 { |
|
1832 return iSurfaceMap; |
|
1833 } |
|
1834 |
|
1835 void CScreen::InitializeSceneL() |
|
1836 { |
|
1837 // Ensure the surface is not valid to start with. |
|
1838 iDsaSurface = TSurfaceId::CreateNullId(); |
|
1839 iWindowElementSet = CWindowElementSet::NewL(*iScene); |
|
1840 } |
|
1841 |
|
1842 MWsElement* CScreen::CreateUiElementL(const TRect& aExtent) |
|
1843 { |
|
1844 MWsElement* pElement = iScene->CreateSceneElementL(); |
|
1845 |
|
1846 TUint32 flags = 0; |
|
1847 pElement->GetRenderStageFlags(flags); |
|
1848 flags |= MWsElement::EElementIsIndirectlyRenderedUserInterface; |
|
1849 pElement->SetRenderStageFlags(flags); |
|
1850 |
|
1851 iScene->InsertSceneElement(pElement, NULL); |
|
1852 |
|
1853 pElement->SetDestinationRectangle(aExtent); |
|
1854 pElement->SetSourceRectangle(aExtent); //initial guess... updated by PositionUiElements |
|
1855 |
|
1856 return pElement; |
|
1857 } |
|
1858 |
|
1859 void CScreen::InitializeUiElementsL() |
|
1860 { |
|
1861 const TRect screenRect(iScreenDevice->SizeInPixels()); |
|
1862 MWsElement* pElement = CreateUiElementL(screenRect); |
|
1863 |
|
1864 if(HasAlpha()) |
|
1865 { |
|
1866 TUint32 flags = 0; |
|
1867 pElement->GetTargetRendererFlags(flags); |
|
1868 flags |= MWsElement::EElementTransparencySource; |
|
1869 pElement->SetTargetRendererFlags(flags); |
|
1870 } |
|
1871 } |
|
1872 |
|
1873 TInt CScreen::InitializeDsaSurface() |
|
1874 { |
|
1875 WS_ASSERT_DEBUG(iDsaSurface.IsNull(),EWsPanicInvalidOperation); |
|
1876 iDsaDevice->GetSurface(iDsaSurface); |
|
1877 // Currently Surface Manager does not recognise DSA surface IDs originating |
|
1878 // from the Screen Driver. This causes it to fail to register such |
|
1879 // surfaces. OpenWF should be amended to properly register DSA surfaces. |
|
1880 iScene->RegisterSurface(iDsaSurface); |
|
1881 |
|
1882 return KErrNone; |
|
1883 } |
|
1884 |
|
1885 TSize CScreen::DSASizeInPixels() const |
|
1886 { |
|
1887 if(iDsaDevice) |
|
1888 { |
|
1889 return iDsaDevice->SizeInPixels(); |
|
1890 } |
|
1891 else |
|
1892 { |
|
1893 return TSize(0,0); |
|
1894 } |
|
1895 } |
|
1896 |
|
1897 MWsTextCursor* CScreen::RenderStageTextCursor() const |
|
1898 { |
|
1899 return iRedraw->RenderStageTextCursor(); |
|
1900 } |
|
1901 |
|
1902 void CScreen::ClearDsaSurface(const TRect& area, const TRgb& color) |
|
1903 { |
|
1904 WS_ASSERT_DEBUG(iDsaGc, EWsPanicInvalidOperation); |
|
1905 iDsaGc->SetBrushStyle(CFbsBitGc::ESolidBrush); |
|
1906 iDsaGc->SetPenStyle(CFbsBitGc::ENullPen); |
|
1907 iDsaGc->SetBrushColor(color); |
|
1908 iDsaGc->DrawRect(area); |
|
1909 iDsaDevice->Update(); |
|
1910 } |
|
1911 |
|
1912 void CScreen::ReleaseDsaScreenDevice() |
|
1913 { |
|
1914 //This function checks if any of the DSA currently active on the screen is actually used to draw |
|
1915 //If not it unregister the DSA surface and destroys the iDsaDevice. |
|
1916 //This function should be called only by a drawing DSA so a surface should be in place. |
|
1917 iNumberDrawingDsa--; |
|
1918 if(iNumberDrawingDsa == 0) |
|
1919 { |
|
1920 WS_ASSERT_DEBUG(!iDsaSurface.IsNull(),EWsPanicInvalidOperation); |
|
1921 delete iDsaGc; |
|
1922 iDsaGc = NULL; |
|
1923 // Currently Surface Manager does not recognise DSA surface IDs originating |
|
1924 // from the Screen Driver. This causes it to fail to unregister such |
|
1925 // surfaces. OpenWF should be amended to properly register DSA surfaces. |
|
1926 iScene->UnregisterSurface(iDsaSurface); |
|
1927 |
|
1928 delete iDsaDevice; |
|
1929 iDsaDevice = NULL; |
|
1930 //the old surface Id is now meaningless |
|
1931 iDsaSurface = TSurfaceId::CreateNullId(); |
|
1932 } |
|
1933 } |
|
1934 |
|
1935 TInt CScreen::SetConfiguration(const TDisplayConfiguration& aConfigInput) |
|
1936 { |
|
1937 TInt reply = KErrNone; |
|
1938 if(iDisplayControl) |
|
1939 { |
|
1940 TDisplayConfiguration config(aConfigInput); |
|
1941 TRect sizeModePosition; |
|
1942 if (iDisplayPolicy) |
|
1943 { //validate config and update to a valid hardware config |
|
1944 reply = iDisplayPolicy->GetSizeModeConfiguration(iScreenSizeMode,config,sizeModePosition); |
|
1945 if (reply >= KErrNone) |
|
1946 {//set appmode in policy |
|
1947 if (iDisplayMapping) |
|
1948 { |
|
1949 iDisplayMapping->SetSizeModeExtent(sizeModePosition,MWsDisplayMapping::KOffsetAll); |
|
1950 } |
|
1951 } |
|
1952 } |
|
1953 else |
|
1954 { //exessive strategy: limit rotation agains curr app mode. |
|
1955 //really we want the system to accept the rotation change regardless of the app mode. |
|
1956 TDisplayConfiguration::TRotation newRot; |
|
1957 if (aConfigInput.GetRotation(newRot)) |
|
1958 { //This should cast between rotation enumertaions "properly" |
|
1959 if (!(iModes[0][iScreenSizeMode]->iAlternativeRotations&(1<<newRot))) |
|
1960 { |
|
1961 reply=KErrArgument; |
|
1962 } |
|
1963 } |
|
1964 } |
|
1965 if (reply < KErrNone) |
|
1966 { |
|
1967 return reply; |
|
1968 } |
|
1969 MWsScene::TSceneRotation oldRotation; |
|
1970 oldRotation = iScene->SceneRotation(); |
|
1971 TSize newUiSize; |
|
1972 config.GetResolution(newUiSize); |
|
1973 TDisplayConfiguration oldConfig; |
|
1974 iDisplayControl->GetConfiguration(oldConfig); |
|
1975 if(iFlags&EHasDynamicSizeModes) |
|
1976 { |
|
1977 reply = iFallbackMap->Resize(newUiSize); |
|
1978 } |
|
1979 if (reply >= KErrNone) |
|
1980 { |
|
1981 reply=iDisplayControl->SetConfiguration(config); |
|
1982 } |
|
1983 if (reply==KErrNone) |
|
1984 { |
|
1985 TSize oldConfigRes; |
|
1986 oldConfig.GetResolution(oldConfigRes); |
|
1987 if (oldConfigRes.iWidth == 0 || oldConfigRes.iHeight == 0) |
|
1988 { |
|
1989 TDisplayConfiguration newConfig; |
|
1990 iDisplayControl->GetConfiguration(newConfig); |
|
1991 RecalculateModeTwips(&newConfig); //needs res and twips information |
|
1992 } |
|
1993 UpdateDynamicScreenModes(); |
|
1994 |
|
1995 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EScreenSizeModeAboutToChange, iScreenSizeMode)); |
|
1996 // This will remove all the DSA elements from the scene |
|
1997 AbortAllDirectDrawing(RDirectScreenAccess::ETerminateRotation); |
|
1998 |
|
1999 //SetDigitiserAreas needs revisiting if/when we support dynamic resolutions |
|
2000 //on a screen with touch input. |
|
2001 //SetDigitiserAreas(newUiSize); |
|
2002 |
|
2003 //failure here should only be because of DSA orientation change failure, which shouldn't happen, either. |
|
2004 //Or there may be no change to do. |
|
2005 (void)UpdateOrientation(&oldRotation); |
|
2006 |
|
2007 iWindowElementSet->ResubmitAllElementExtents(); |
|
2008 if(iDsaDevice && iDsaDevice->GraphicsAccelerator()) |
|
2009 { |
|
2010 iDsaDevice->ChangeScreenDevice(iDsaDevice); // orientation has changed, therefore we need to re-initialise the screen device's graphics accelerator |
|
2011 } |
|
2012 |
|
2013 iRootWindow->AdjustCoordsDueToRotation(); |
|
2014 |
|
2015 //TODO jonas: we'd like to not have to clear at all... make the actual change to compositor etc lazily! |
|
2016 if(BlankScreenOnRotation()) |
|
2017 { |
|
2018 iRootWindow->ClearDisplay(); |
|
2019 } |
|
2020 |
|
2021 CWsTop::ClearAllRedrawStores(); |
|
2022 DiscardAllSchedules(); |
|
2023 iRootWindow->InvalidateWholeScreen(); |
|
2024 CWsWindowGroup::SetScreenDeviceValidStates(this); |
|
2025 TWindowServerEvent::SendScreenDeviceChangedEvents(this); |
|
2026 } |
|
2027 else |
|
2028 { |
|
2029 return reply; |
|
2030 } |
|
2031 } |
|
2032 else |
|
2033 { |
|
2034 reply = KErrNotSupported; |
|
2035 } |
|
2036 return reply; |
|
2037 } |
|
2038 |
|
2039 void CScreen::UpdateDynamicScreenModes() |
|
2040 { |
|
2041 WS_ASSERT_DEBUG(iDisplayControl,EWsPanicNoDisplayControl); |
|
2042 TDisplayConfiguration newConfig; |
|
2043 iDisplayControl->GetConfiguration(newConfig); |
|
2044 TSize res; |
|
2045 TSize twips; |
|
2046 newConfig.GetResolution(res); |
|
2047 newConfig.GetResolutionTwips(twips); |
|
2048 for (TInt i=0; i<iModes->Count(); i++) |
|
2049 { |
|
2050 if ((*iModes)[i] && ((*iModes)[i]->iFlags & EDynamic)) |
|
2051 { |
|
2052 (*iModes)[i]->iScreenSize = res; |
|
2053 (*iModes)[i]->iScreenTwipsSize = twips; |
|
2054 } |
|
2055 } |
|
2056 } |
|
2057 |
|
2058 void CScreen::RecalculateModeTwips(const TDisplayConfiguration* aConfig) |
|
2059 { |
|
2060 TDisplayConfiguration config; |
|
2061 iDisplayControl->GetConfiguration(config); |
|
2062 TSize res; |
|
2063 TSize twips; |
|
2064 if (aConfig) //called from SetConfiguration |
|
2065 { |
|
2066 aConfig->GetResolution(res); |
|
2067 if (res.iWidth == 0 || res.iHeight == 0) |
|
2068 { |
|
2069 return; |
|
2070 } |
|
2071 aConfig->GetResolutionTwips(twips); |
|
2072 } |
|
2073 else //called from DisplayChangeNotifier during attach |
|
2074 { |
|
2075 config.GetResolution(res); |
|
2076 if ((res.iWidth == 0 || res.iHeight == 0) && !iDisplayPolicy) |
|
2077 { |
|
2078 return; |
|
2079 } |
|
2080 config.GetResolutionTwips(twips); |
|
2081 } |
|
2082 TInt err=KErrNone; |
|
2083 TInt flags=0; |
|
2084 for (TInt ii=0; ii<iModes->Count(); ii++) |
|
2085 { //for every mode |
|
2086 TRAP(err, flags = ModePtrL(ii)->iFlags); |
|
2087 if (err != KErrNone || flags&(ETwipsSpecified|EDynamic)) |
|
2088 { //continue if mode doesnt exist,twips specified or dynamic mode specified |
|
2089 continue; |
|
2090 } |
|
2091 |
|
2092 if (iDisplayPolicy) |
|
2093 { //get ideal config for app mode from policy |
|
2094 TRect modePosition; |
|
2095 config.ClearAll(); |
|
2096 TInt err = iDisplayPolicy->GetSizeModeConfiguration(ii,config,modePosition); |
|
2097 if (err != KErrNone) |
|
2098 { //nothing we can do, the twips will not be calculated correctly |
|
2099 continue; |
|
2100 } |
|
2101 config.GetResolution(res); |
|
2102 config.GetResolutionTwips(twips); |
|
2103 } |
|
2104 TSizeMode* modePtr=(*iModes)[ii]; |
|
2105 modePtr->iScreenTwipsSize.iWidth = (twips.iWidth * modePtr->iScreenSize.iWidth)/ |
|
2106 res.iWidth; |
|
2107 modePtr->iScreenTwipsSize.iHeight = (twips.iHeight * modePtr->iScreenSize.iHeight)/ |
|
2108 res.iHeight; |
|
2109 } |
|
2110 |
|
2111 } |
|
2112 |
|
2113 TInt CScreen::AddNotificationClient(CWsClient *aClient) |
|
2114 { |
|
2115 TInt err = iWsClientList.InsertInAddressOrder(aClient); |
|
2116 if(!(err == KErrNone || err == KErrAlreadyExists)) |
|
2117 { |
|
2118 return err; |
|
2119 } |
|
2120 return KErrNone; |
|
2121 } |
|
2122 void CScreen::RemoveNotificationClient(CWsClient *aClient) |
|
2123 { |
|
2124 TInt index = iWsClientList.FindInAddressOrder(aClient); |
|
2125 if(index != KErrNotFound) |
|
2126 { |
|
2127 iWsClientList.Remove(index); |
|
2128 } |
|
2129 } |
|
2130 TInt CScreen::GetNotificationClients(RPointerArray<CWsClient>& aClientsArray) |
|
2131 { |
|
2132 TInt err = aClientsArray.Reserve(iWsClientList.Count()); |
|
2133 if(err != KErrNone) |
|
2134 return err; |
|
2135 |
|
2136 for(TInt i = 0; i < iWsClientList.Count(); i++) |
|
2137 { |
|
2138 aClientsArray.Append(iWsClientList[i]); |
|
2139 } |
|
2140 return KErrNone; |
|
2141 } |
|
2142 |
|
2143 TInt CScreen::FindNotificationClient (CWsClient *aClient) |
|
2144 { |
|
2145 return iWsClientList.FindInAddressOrder(aClient); |
|
2146 } |
|
2147 |
|
2148 // implementing MWsScreenConfig... this might be better as RS interface |
|
2149 TSize CScreen::ScreenModeSizeInPixels() const |
|
2150 { |
|
2151 return (*iModes)[iScreenSizeMode]->iScreenSize; |
|
2152 } |
|
2153 TInt CScreen::Stride() const |
|
2154 { |
|
2155 return 0; |
|
2156 } |
|
2157 TInt CScreen::SizeMode() const |
|
2158 { |
|
2159 return iScreenSizeMode; |
|
2160 |
|
2161 } |
|
2162 TSize CScreen::ScalingFactor() const |
|
2163 { |
|
2164 return (*iModes)[iScreenSizeMode]->iScreenScale; |
|
2165 } |
|
2166 TPoint CScreen::Origin() const |
|
2167 { |
|
2168 return (*iModes)[iScreenSizeMode]->iOrigin; |
|
2169 } |
|
2170 TPoint CScreen::ScaledOrigin() const |
|
2171 { |
|
2172 return (*iModes)[iScreenSizeMode]->ScaledOrigin(); |
|
2173 } |
|
2174 |
|
2175 const CScreen::TInternalSizeMode* CScreen::ModePtrL(TInt aIndex) const |
|
2176 { |
|
2177 if (aIndex>=iModes->Count() || aIndex<0) |
|
2178 { |
|
2179 User::Leave(KErrArgument); |
|
2180 } |
|
2181 if (iModes==NULL) |
|
2182 { |
|
2183 User::Leave(KErrNotReady); |
|
2184 } |
|
2185 TInternalSizeMode* modePtr=(*iModes)[aIndex]; |
|
2186 if (modePtr==NULL) |
|
2187 { |
|
2188 User::Leave(KErrArgument); |
|
2189 } |
|
2190 return modePtr; |
|
2191 } |
|
2192 |
|
2193 TDisplayMode CScreen::DisplayModeL(TInt aIndex) const |
|
2194 { |
|
2195 return ModePtrL(aIndex)->iDefaultDisplayMode; |
|
2196 } |
|
2197 TSize CScreen::ScreenModeSizeInPixelsL(TInt aIndex) const |
|
2198 { |
|
2199 return ModePtrL(aIndex)->iScreenSize; |
|
2200 } |
|
2201 TSize CScreen::ScreenModeSizeInTwipsL(TInt aIndex) const |
|
2202 { |
|
2203 return ModePtrL(aIndex)->iScreenTwipsSize; |
|
2204 } |
|
2205 |
|
2206 CFbsBitGc::TGraphicsOrientation CScreen::OrientationL(TInt aIndex) const |
|
2207 { |
|
2208 return ModePtrL(aIndex)->iRotation; |
|
2209 } |
|
2210 TInt CScreen::AvailableOrientationsL(TInt aIndex) const |
|
2211 { |
|
2212 return ModePtrL(aIndex)->iAlternativeRotations; |
|
2213 } |
|
2214 TSize CScreen::ScalingFactorL(TInt aIndex) const |
|
2215 { |
|
2216 return ModePtrL(aIndex)->iScreenScale; |
|
2217 } |
|
2218 TPoint CScreen::OriginL(TInt aIndex) const |
|
2219 { |
|
2220 return ModePtrL(aIndex)->iOrigin; |
|
2221 } |
|
2222 TPoint CScreen::ScaledOriginL(TInt aIndex) const |
|
2223 { |
|
2224 return ModePtrL(aIndex)->ScaledOrigin(); |
|
2225 } |
|
2226 TInt CScreen::ModeFlagsL(TInt aIndex) const |
|
2227 { |
|
2228 return ModePtrL(aIndex)->iFlags; |
|
2229 } |
|
2230 void CScreen::SetCurrentScreenModeAttributes(const TSizeMode &aModeData) |
|
2231 { |
|
2232 TSizeMode* modeToOverwrite=(*iModes)[iScreenSizeMode]; |
|
2233 *modeToOverwrite=aModeData; |
|
2234 } |
|
2235 |
|
2236 void CScreen::ScheduleWindow(CWsWindow* aWindow) |
|
2237 { |
|
2238 iRedraw->ScheduleWindow(aWindow); |
|
2239 } |
|
2240 |
|
2241 void CScreen::RemoveFromScheduledList(CWsWindow* aWindow) |
|
2242 { |
|
2243 iRedraw->RemoveFromScheduledList(aWindow); |
|
2244 } |
|
2245 |
|
2246 void CScreen::RemoveFromTimedDrawList(CWsWindow* aWindow) |
|
2247 { |
|
2248 iRedraw->RemoveFromTimedDrawList(aWindow); |
|
2249 } |
|
2250 |
|
2251 void CScreen::SetupVisibleRegionTracking(CWsWindow& aWindow, TBool aRegister) const |
|
2252 { |
|
2253 if(ChangeTracking() && iWindowVisibilityNotifier) |
|
2254 { |
|
2255 if(aRegister) |
|
2256 { |
|
2257 iWindowVisibilityNotifier->RegisterWindow(aWindow); |
|
2258 } |
|
2259 else |
|
2260 { |
|
2261 iWindowVisibilityNotifier->UnregisterWindow(aWindow); |
|
2262 } |
|
2263 } |
|
2264 } |
|
2265 |
|
2266 TBool CScreen::IsAnimating() const |
|
2267 { |
|
2268 return iRedraw->IsAnimating(); |
|
2269 } |