|
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 |
|
20 #include "server.h" |
|
21 #include "wstop.h" |
|
22 #include "rootwin.h" |
|
23 #include "walkwindowtree.h" |
|
24 #include "offscreenbitmap.h" |
|
25 #include "EVENT.H" |
|
26 #include "windowgroup.h" |
|
27 #include "gc.h" |
|
28 #include "inifile.h" |
|
29 #include "pointer.h" |
|
30 |
|
31 #include "debugbar.h" |
|
32 #include "ScreenRedraw.h" |
|
33 #include "wspluginmanager.h" |
|
34 |
|
35 GLREF_D CDebugLogBase *wsDebugLog; |
|
36 GLREF_D TDisplayMode ParseDisplayMode(const TDesC& aModeName); |
|
37 |
|
38 LOCAL_D TBool FindNextValue(TLex& aLex, TInt& aValue) // assumes the list cannot contain *negative* integers |
|
39 { |
|
40 while (!aLex.Eos()) |
|
41 { |
|
42 const TUint character=aLex.Peek(); |
|
43 if (Rng(TUint('0'), character, TUint('9')) || (character=='-')) |
|
44 { |
|
45 break; |
|
46 } |
|
47 aLex.Inc(); |
|
48 } |
|
49 |
|
50 return (aLex.Val(aValue)==KErrNone); |
|
51 } |
|
52 |
|
53 CScreen::CFallbackMap * CScreen::CFallbackMap::NewL(CScreen* aScreen) |
|
54 { |
|
55 CFallbackMap * self = new (ELeave) CFallbackMap(aScreen); |
|
56 CleanupStack::PushL(self); |
|
57 self->ConstructL(); |
|
58 CleanupStack::Pop(self); |
|
59 return self; |
|
60 } |
|
61 |
|
62 CScreen::CFallbackMap::CFallbackMap(CScreen* aScreen) : |
|
63 iScreen(aScreen), |
|
64 iRegion(TRect(TPoint(0,0), TSize(1,1))), |
|
65 iCount(0) |
|
66 { |
|
67 } |
|
68 |
|
69 CScreen::CFallbackMap::~CFallbackMap() |
|
70 { |
|
71 delete iMap; |
|
72 } |
|
73 |
|
74 void CScreen::CFallbackMap::ConstructL() |
|
75 { |
|
76 iMapSize = 0; |
|
77 |
|
78 for (TInt num = 0; num < iScreen->NumScreenSizeModes(); ++num) |
|
79 { |
|
80 if (iScreen->IsValidScreenSizeMode(num)) |
|
81 { |
|
82 const TSizeMode & mode = iScreen->ScreenSizeModeData(num); |
|
83 TInt width = mode.iScreenSize.iWidth / 32; |
|
84 if (mode.iScreenSize.iWidth & (32 - 1)) |
|
85 ++width; |
|
86 TInt size = width * mode.iScreenSize.iHeight; |
|
87 if (size > iMapSize) |
|
88 iMapSize = size; |
|
89 } |
|
90 } |
|
91 |
|
92 iMap = new (ELeave) TInt [iMapSize]; |
|
93 } |
|
94 |
|
95 void CScreen::CFallbackMap::Prepare() |
|
96 { |
|
97 const TSizeMode & mode = iScreen->ScreenSizeModeData(); |
|
98 Mem::FillZ(iMap, iMapSize * sizeof(TInt)); |
|
99 iCount = mode.iScreenSize.iHeight * mode.iScreenSize.iWidth; |
|
100 WS_ASSERT_DEBUG(iRegion.Count() == 1, EWsPanicScreenFallback); |
|
101 iRegion.Clear(); |
|
102 iRegion.AddRect(TRect(mode.iOrigin, mode.iScreenSize)); |
|
103 } |
|
104 |
|
105 TBool CScreen::CFallbackMap::FillRegion(const TRegion& aRegion) |
|
106 { |
|
107 WS_ASSERT_DEBUG(!aRegion.CheckError(), EWsPanicScreenFallback); |
|
108 if (aRegion.Count() > 20 || aRegion.CheckError()) |
|
109 return ETrue; |
|
110 TBool hit = EFalse; |
|
111 if (iCount > 0) |
|
112 { |
|
113 const TRect * rect = aRegion.RectangleList(); |
|
114 for (TInt num = 0; num < aRegion.Count(); ++num) |
|
115 { |
|
116 hit = FillRect(*rect) || hit; |
|
117 if (iCount < 1) |
|
118 break; |
|
119 ++rect; |
|
120 } |
|
121 } |
|
122 return hit; |
|
123 } |
|
124 |
|
125 // x >> 5 is equivalent to x / 32 |
|
126 // 0x1F is the rounding error when dividing by 32 |
|
127 // 0x20 is 32. |
|
128 // The compiler might do all the optimizations for us - not checked. |
|
129 TBool CScreen::CFallbackMap::FillRect(const TRect& aRect) |
|
130 { |
|
131 TBool hit = EFalse; |
|
132 const TSizeMode & mode = iScreen->ScreenSizeModeData(); |
|
133 TRect scrrect(mode.iOrigin, mode.iScreenSize); |
|
134 TRect rect = aRect; |
|
135 rect.Intersection(scrrect); |
|
136 TInt rowWidthInInts = mode.iScreenSize.iWidth; |
|
137 if (rowWidthInInts & 0x1F) |
|
138 rowWidthInInts += 0x20; |
|
139 rowWidthInInts >>= 5; |
|
140 |
|
141 TInt colStartInInts = rect.iTl.iX >> 5; |
|
142 TInt firstOffsetInBits = rect.iTl.iX & 0x1F; |
|
143 |
|
144 for(TInt row = rect.iTl.iY; row < rect.iBr.iY; ++row) |
|
145 { |
|
146 TInt * map = iMap + row * rowWidthInInts + colStartInInts; |
|
147 TInt offsetShift = 31 - firstOffsetInBits; |
|
148 for (TInt col = rect.iTl.iX; col < rect.iBr.iX; ++col) |
|
149 { |
|
150 WS_ASSERT_DEBUG(map - iMap < iMapSize, EWsPanicScreenFallback); |
|
151 if (!(*map & 1 << offsetShift)) |
|
152 { |
|
153 --iCount; |
|
154 hit = ETrue; |
|
155 if (iCount < 1) |
|
156 break; |
|
157 (*map) |= (1 << offsetShift); |
|
158 } |
|
159 --offsetShift; |
|
160 if (offsetShift < 0) |
|
161 { |
|
162 offsetShift = 31; |
|
163 ++map; |
|
164 } |
|
165 } |
|
166 } |
|
167 return hit; |
|
168 } |
|
169 |
|
170 TInt CScreen::CFallbackMap::Count() const |
|
171 { |
|
172 return iCount; |
|
173 } |
|
174 |
|
175 const TRect * CScreen::CFallbackMap::Rect() const |
|
176 { |
|
177 return iRegion.RectangleList(); |
|
178 } |
|
179 |
|
180 const RRegion * CScreen::CFallbackMap::Region() const |
|
181 { |
|
182 return &iRegion; |
|
183 } |
|
184 |
|
185 // |
|
186 // CScreen |
|
187 // |
|
188 CScreen::CScreen(): iDirects(_FOFF(CWsDirectScreenAccess,iLink)), iMaxContrast(-1), iMaxBrightness(-1) |
|
189 { |
|
190 } |
|
191 |
|
192 CScreen::~CScreen() |
|
193 { |
|
194 delete iDebugBar; |
|
195 delete iOffScreenBitmap; |
|
196 delete iScreenGdi; |
|
197 TInt ii; |
|
198 if(iModes) |
|
199 { |
|
200 for(ii=iNumScreenSizeModes-1;ii>=0;--ii) |
|
201 { |
|
202 delete (*iModes)[ii]; |
|
203 } |
|
204 iModes->Close(); |
|
205 delete iModes; |
|
206 } |
|
207 delete iRootWindow; |
|
208 delete iScreenDevice; |
|
209 delete iFallbackMap; |
|
210 delete iSpriteManager; |
|
211 delete iRedraw; |
|
212 } |
|
213 |
|
214 void CScreen::ConstructL(const TRect& aDigitiserArea, TInt aScreenNumber ) |
|
215 { |
|
216 iScreenNumber = aScreenNumber ; |
|
217 |
|
218 if (wsDebugLog) |
|
219 { |
|
220 _LIT(KWSERVInitScreen,"Initialising for Screen %d"); |
|
221 wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, KWSERVInitScreen, aScreenNumber); |
|
222 } |
|
223 |
|
224 CreateScreenDeviceL(); |
|
225 iScreenDevice->SetAutoUpdate(EFalse); |
|
226 iPhysicalScreenSize=iScreenDevice->SizeInPixels(); |
|
227 LoadScreenSizesL(iPhysicalScreenSize); |
|
228 // mode 0 might not be available, get the first/lowest valid mode |
|
229 SetInitialScreenSizeMode(); |
|
230 |
|
231 iFallbackMap = CFallbackMap::NewL(this); |
|
232 // |
|
233 iScreenGdi=CFbsBitGc::NewL(); |
|
234 iScreenGdi->Activate(iScreenDevice); |
|
235 LoadScreenSizeProperties(); |
|
236 SetDigitiserAreas(iScreenDevice->SizeInPixels(),aDigitiserArea); |
|
237 // |
|
238 iScreenGdi->SetOrientation(Orientation()); |
|
239 const TSizeMode& sizeMode=ScreenSizeModeData(ScreenSizeMode()); |
|
240 iScreenDevice->SetScalingFactor(sizeMode.iOrigin,sizeMode.iScreenScale.iWidth,sizeMode.iScreenScale.iHeight,1,1); |
|
241 iScreenDevice->ChangeScreenDevice(NULL); //This is necessary to initialise the screen |
|
242 // |
|
243 // Off Screen Bitmaps |
|
244 iOffScreenBitmap=CWsOffScreenBitmap::NewL(this); |
|
245 TSize osbSize(iOffScreenBitmap->Bitmap()->SizeInPixels()); |
|
246 TSize osbTwips(sizeMode.iScreenTwipsSize); |
|
247 if (osbSize!=sizeMode.iScreenSize) |
|
248 { |
|
249 // The specified screen twips size is for the specified screen pixel size, however the OSB |
|
250 // is potentially larger as it needs to hold the maximum possible screen size, so we need |
|
251 // to scale the twips size up correspondingly. |
|
252 osbTwips.iWidth=sizeMode.iScreenTwipsSize.iWidth*osbSize.iWidth/sizeMode.iScreenSize.iWidth; |
|
253 osbTwips.iHeight=sizeMode.iScreenTwipsSize.iHeight*osbSize.iHeight/sizeMode.iScreenSize.iHeight; |
|
254 } |
|
255 iOffScreenBitmap->Bitmap()->SetSizeInTwips(osbTwips); |
|
256 |
|
257 TInt autoClear = 1; |
|
258 _LIT(KWSERVIniFileVarAutoClear,"AUTOCLEAR"); |
|
259 WsIniFile->FindVar(iScreenNumber,KWSERVIniFileVarAutoClear,autoClear); |
|
260 if (autoClear != 0) |
|
261 { |
|
262 iFlags|=EAutoClear; |
|
263 } |
|
264 |
|
265 _LIT(KBackLight,"BACKLIGHTCONTROL"); |
|
266 iBackLightFlag=WsIniFile->FindVar( iScreenNumber, KBackLight); |
|
267 |
|
268 _LIT(KWSERVIniFileVarBlankScreen, "BLANKSCREENONROTATION"); |
|
269 if (WsIniFile->FindVar(iScreenNumber, KWSERVIniFileVarBlankScreen)) |
|
270 { |
|
271 iFlags|=EBlankScreenOnRotation; |
|
272 } |
|
273 |
|
274 SetShadowVector(TPoint(EDefaultShadowX,EDefaultShadowY)); |
|
275 |
|
276 iRedraw = CScreenRedraw::NewL(*this); |
|
277 |
|
278 iRootWindow = new (ELeave) CWsRootWindow(NULL, this); |
|
279 iRootWindow->ConstructL(); |
|
280 |
|
281 TInt refreshRate = 1000000; |
|
282 _LIT(KDebugBar, "DEBUGBAR"); |
|
283 if (WsIniFile->FindVar(refreshRate, KDebugBar)) |
|
284 { |
|
285 if (refreshRate < 100000) |
|
286 refreshRate = 50000; |
|
287 const TPoint origin = CurrentScreenModeOrigin(); |
|
288 iDebugBar = CDebugBar::NewL(this, TRect(origin.iX,origin.iY,origin.iX+CurrentScreenSize().iWidth,origin.iY+16), refreshRate); |
|
289 } |
|
290 // Default fading parameters |
|
291 iBlackMap=128; |
|
292 iWhiteMap=255; |
|
293 |
|
294 iSpriteManager = CWsSpriteManager::NewL(); |
|
295 //Look for fading plugins here. |
|
296 _LIT(KDefaultFaderPluginName, "wsfader"); |
|
297 _LIT(KFaderPluginIni,"FADER"); |
|
298 CWsPluginManager* mgr = CWsTop::WindowServer()->PluginManager(); |
|
299 if (mgr) |
|
300 { |
|
301 TPtrC faderName; |
|
302 if (WsIniFile->FindVar(iScreenNumber, KFaderPluginIni, faderName)) |
|
303 iFader = mgr->FindNamedImplementation<MWsFader>(faderName); |
|
304 else |
|
305 iFader = mgr->FindNamedImplementation<MWsFader>(KDefaultFaderPluginName); |
|
306 } |
|
307 |
|
308 _LIT(KBltOffScreenBitmap,"BLTOFFSCREENBITMAP"); |
|
309 if (WsIniFile->FindVar(iScreenNumber, KBltOffScreenBitmap)) |
|
310 { |
|
311 iFlags|=EBltOffScreenBitmap; |
|
312 } |
|
313 } |
|
314 |
|
315 void CScreen::CreateScreenDeviceL() |
|
316 { |
|
317 _LIT(KScreenMode,"SCREENMODE"); |
|
318 _LIT(KWindowMode,"WINDOWMODE"); |
|
319 TPtrC screenModeName; |
|
320 TDisplayMode screenMode = ENone; |
|
321 if (WsIniFile->FindVar(iScreenNumber, KScreenMode, screenModeName)) |
|
322 { |
|
323 screenMode = ParseDisplayMode(screenModeName); |
|
324 } |
|
325 else if (WsIniFile->FindVar(iScreenNumber, KWindowMode, screenModeName)) |
|
326 { |
|
327 screenMode = ParseDisplayMode(screenModeName); |
|
328 } |
|
329 |
|
330 if (screenMode != ENone) |
|
331 { |
|
332 if(DoCreateScreenDevice(screenMode)) |
|
333 return; |
|
334 } |
|
335 |
|
336 // No screen mode was specified, or we failed creating the specified screen |
|
337 // mode. Default to as high display mode as possible. |
|
338 |
|
339 // Check if the screen device supports 16M colors (it can only support one of |
|
340 // 16M, 16MU, 16MA, 16MAP, or none of them) |
|
341 screenMode = CFbsDevice::DisplayMode16M(); |
|
342 if(screenMode != ENone) |
|
343 { |
|
344 if(DoCreateScreenDevice(screenMode)) |
|
345 return; |
|
346 } |
|
347 |
|
348 // Try creating the screen device with all available display modes, going from best to worst |
|
349 __ASSERT_COMPILE(EColorLast == 14); // if any display mode is added to TDisplayMode we must update the list below |
|
350 // (the list below contains all enums in TDisplayMode except ENone, ERgb, EColorLast) |
|
351 if(DoCreateScreenDevice(EColor16MAP)) |
|
352 return; |
|
353 if(DoCreateScreenDevice(EColor16MA)) |
|
354 return; |
|
355 if(DoCreateScreenDevice(EColor16MU)) |
|
356 return; |
|
357 if(DoCreateScreenDevice(EColor16M)) |
|
358 return; |
|
359 if(DoCreateScreenDevice(EColor64K)) |
|
360 return; |
|
361 if(DoCreateScreenDevice(EColor4K)) |
|
362 return; |
|
363 if(DoCreateScreenDevice(EColor256)) |
|
364 return; |
|
365 if(DoCreateScreenDevice(EColor16)) |
|
366 return; |
|
367 if(DoCreateScreenDevice(EGray256)) |
|
368 return; |
|
369 if(DoCreateScreenDevice(EGray16)) |
|
370 return; |
|
371 if(DoCreateScreenDevice(EGray4)) |
|
372 return; |
|
373 if(DoCreateScreenDevice(EGray2)) |
|
374 return; |
|
375 |
|
376 User::Leave(KErrNotSupported); |
|
377 } |
|
378 |
|
379 TBool CScreen::DoCreateScreenDevice(TDisplayMode aScreenMode) |
|
380 { |
|
381 TRAPD(err, iScreenDevice = CFbsScreenDevice::NewL(iScreenNumber, aScreenMode)); |
|
382 return (err == KErrNone); |
|
383 } |
|
384 |
|
385 void CScreen::AbortDSAs(RDirectScreenAccess::TTerminationReasons aReason,TSglQue<CWsDirectScreenAccess>& aDirects) |
|
386 { |
|
387 if (aDirects.IsEmpty()) |
|
388 return; |
|
389 TInt nofDSAs = 0; |
|
390 TSglQueIter<CWsDirectScreenAccess> iter(aDirects); |
|
391 CWsDirectScreenAccess* direct; |
|
392 while (( direct=iter++)!=NULL ) |
|
393 { |
|
394 nofDSAs++; |
|
395 direct->SignalAbort( aReason ); |
|
396 } |
|
397 |
|
398 TRequestStatus timerStatus; |
|
399 RTimer& timer=CWsTop::Timer(); |
|
400 timer.Cancel(); |
|
401 |
|
402 TRequestStatus** cancelReqList = (TRequestStatus**) User::AllocZ( sizeof( TRequestStatus* ) * (nofDSAs + 1) ); |
|
403 if ( NULL != cancelReqList ) |
|
404 { |
|
405 TInt dsaNo = 1; |
|
406 |
|
407 timer.After( timerStatus, KDSAAbortingImmediateRespAwaitFrameMicrosec ); |
|
408 |
|
409 iter.SetToFirst(); |
|
410 while (( direct=iter++)!=NULL ) |
|
411 { |
|
412 cancelReqList[ dsaNo ] = &direct->AbortStatus(); |
|
413 dsaNo++; |
|
414 } |
|
415 cancelReqList[ 0 ] = &timerStatus; |
|
416 |
|
417 User::WaitForNRequest( cancelReqList, nofDSAs + 1 ); |
|
418 |
|
419 iter.SetToFirst(); |
|
420 while (( direct=iter++)!=NULL ) |
|
421 { |
|
422 if ( direct->AbortStatus() != KRequestPending ) |
|
423 direct->CancelAbortObject(); // responded |
|
424 else |
|
425 direct->Abort(); |
|
426 } |
|
427 |
|
428 if (timerStatus == KRequestPending) |
|
429 { |
|
430 timer.Cancel(); |
|
431 User::WaitForRequest( timerStatus ); |
|
432 } |
|
433 |
|
434 User::Free( cancelReqList ); |
|
435 } |
|
436 else |
|
437 { |
|
438 iter.SetToFirst(); |
|
439 while ((direct=iter++) != NULL) |
|
440 { |
|
441 |
|
442 TRequestStatus timerStatus; |
|
443 RTimer& timer=CWsTop::Timer(); |
|
444 timer.Cancel(); |
|
445 timer.After(timerStatus, KDSAAbortingImmediateRespAwaitFrameMicrosec); |
|
446 //wait for response or timeout |
|
447 User::WaitForRequest(direct->AbortStatus(), timerStatus); |
|
448 |
|
449 if (direct->AbortStatus() != KRequestPending) |
|
450 direct->CancelAbortObject(); //responded |
|
451 else |
|
452 direct->Abort(); //timed out |
|
453 |
|
454 if (timerStatus == KRequestPending) |
|
455 { |
|
456 timer.Cancel(); |
|
457 User::WaitForRequest(timerStatus); |
|
458 } |
|
459 } |
|
460 } |
|
461 } |
|
462 |
|
463 void CScreen::AbortAllDirectDrawing(RDirectScreenAccess::TTerminationReasons aReason) |
|
464 { |
|
465 AbortDSAs(aReason,iDirects); |
|
466 } |
|
467 |
|
468 void CScreen::AddDirect(CWsDirectScreenAccess& aDirect) |
|
469 { |
|
470 TBool emptyBefore = iDirects.IsEmpty(); |
|
471 iDirects.AddLast(aDirect); |
|
472 TBool emptyAfter = iDirects.IsEmpty(); |
|
473 if (emptyBefore && ! emptyAfter) |
|
474 { |
|
475 TWsEvent wsevent; |
|
476 wsevent.SetType(EEventDirectScreenAccessBegin); |
|
477 *(wsevent.Int()) = iScreenNumber; |
|
478 TWindowServerEvent::PublishNotification(wsevent); |
|
479 } |
|
480 |
|
481 if (iDsaDrawState==EDsaDrawStateIdle && aDirect.IsVisible()) |
|
482 { |
|
483 iDsaDrawState = EDsaDrawStateDrawing; |
|
484 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EDsaDrawingBegin, iScreenNumber)); |
|
485 } |
|
486 } |
|
487 |
|
488 void CScreen::RemoveDirect(CWsDirectScreenAccess& aDirect) |
|
489 { |
|
490 TBool emptyBefore = iDirects.IsEmpty(); |
|
491 iDirects.Remove(aDirect); |
|
492 TBool emptyAfter = iDirects.IsEmpty(); |
|
493 if (emptyAfter && ! emptyBefore) |
|
494 { |
|
495 TWsEvent wsevent; |
|
496 wsevent.SetType(EEventDirectScreenAccessEnd); |
|
497 *(wsevent.Int()) = iScreenNumber; |
|
498 TWindowServerEvent::PublishNotification(wsevent); |
|
499 } |
|
500 |
|
501 if (iDsaDrawState==EDsaDrawStateDrawing && aDirect.IsVisible() && !HasVisibleDirectOnQueue()) |
|
502 { |
|
503 iDsaDrawState = EDsaDrawStateIdle; |
|
504 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EDsaDrawingEnd, iScreenNumber)); |
|
505 } |
|
506 } |
|
507 |
|
508 TBool CScreen::HasVisibleDirectOnQueue() |
|
509 { |
|
510 if (iDirects.IsEmpty()) |
|
511 return EFalse; |
|
512 |
|
513 TSglQueIter<CWsDirectScreenAccess> iter(iDirects); |
|
514 CWsDirectScreenAccess* dsa; |
|
515 while ((dsa=iter++)!=NULL) |
|
516 { |
|
517 if (dsa->IsVisible()) |
|
518 return ETrue; |
|
519 } |
|
520 |
|
521 return EFalse; |
|
522 } |
|
523 |
|
524 #if defined(_DEBUG) |
|
525 TBool CScreen::IsDirectOnQueue(const CWsDirectScreenAccess* aDirect) |
|
526 { |
|
527 TSglQueIter<CWsDirectScreenAccess> iter(iDirects); |
|
528 CWsDirectScreenAccess* direct; |
|
529 while ((direct=iter++)!=NULL) |
|
530 { |
|
531 if (direct==aDirect) |
|
532 return ETrue; |
|
533 } |
|
534 return EFalse; |
|
535 } |
|
536 |
|
537 #if defined(__WINS__) |
|
538 void CScreen::UpdateOffScreenBitmap() |
|
539 { |
|
540 if (iOffScreenBitmap) |
|
541 iOffScreenBitmap->Update(); |
|
542 } |
|
543 #endif |
|
544 #endif |
|
545 |
|
546 void CScreen::KillForegroundSession() |
|
547 { |
|
548 if (iCurrentFocus) |
|
549 { |
|
550 _LIT(KWSERVKillWinGp,"Killing Session owning Window Group with Id=%d"); |
|
551 if (wsDebugLog) |
|
552 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVKillWinGp,iCurrentFocus->Identifier()); |
|
553 iCurrentFocus->WsOwner()->SessionTerminate(); |
|
554 } |
|
555 } |
|
556 |
|
557 CWsWindowGroup* CScreen::FindNewFocus(CWsRootWindow* aRootWindow) |
|
558 { |
|
559 CWsWindowGroup* newFocus; |
|
560 for(newFocus=aRootWindow->Child();newFocus && newFocus->CanReceiveFocus()==EFalse;newFocus=newFocus->NextSibling()) {} |
|
561 |
|
562 return newFocus; |
|
563 } |
|
564 |
|
565 void CScreen::ResetFocus(CWsWindowGroup* aClosingWindow) |
|
566 { |
|
567 CWsWindowGroup* oldFocus=iCurrentFocus; |
|
568 CWsWindowGroup* newFocus=NULL; |
|
569 CScreen* newFocusedScreen=NULL; |
|
570 iCurrentFocus=FindNewFocus(iRootWindow); |
|
571 TBool focusedScreen= EFalse; |
|
572 /*Focus policy is specified in the wsini.ini file using the keyword 'MULTIFOCUSPOLICY'. |
|
573 If the keyword is not specified, then the default policy is run. |
|
574 */ |
|
575 if(!CWsTop::MultiFocusPolicy()) |
|
576 { |
|
577 focusedScreen=(this==CWsTop::CurrentFocusScreen()); //check if this screen is the focus screen |
|
578 if (!iCurrentFocus && focusedScreen) |
|
579 { |
|
580 /*If this screen is the focused screen but does not have a focusable window group, then search for the |
|
581 next screen that has a focusable window group and set that screen as the focused screen. |
|
582 */ |
|
583 CScreen* screen=NULL; |
|
584 TInt screenNo; |
|
585 for (screenNo=0; screenNo<CWsTop::NumberOfScreens() && !newFocus; ++screenNo) |
|
586 { |
|
587 if (screenNo!=iScreenNumber) |
|
588 { |
|
589 screen=CWsTop::Screen(screenNo); |
|
590 newFocus=FindNewFocus(screen->RootWindow()); |
|
591 } |
|
592 } |
|
593 if (newFocus) |
|
594 newFocusedScreen=screen; |
|
595 } |
|
596 } |
|
597 /*Scenario A: multi-focus policy |
|
598 newFocusedScreen is NULL |
|
599 focusedScreen is EFalse |
|
600 CWsTop::MultiFocusPolicy() returns ETrue |
|
601 Check if the new focusable window group is not the same, send focus lost message to window group |
|
602 that has just lost focus and send focus gain message to window group that can receive focus. |
|
603 Scenario B: single-focus policy (default) |
|
604 CWsTop::MultiFocusPolicy() returns EFalse |
|
605 Check if the new focusable window group is not the same or if there is a new focused screen, send focus lost |
|
606 message to window group that has just lost focus and send focus gain message to window group that can receive focus. |
|
607 */ |
|
608 if (iCurrentFocus!=oldFocus || newFocusedScreen) |
|
609 { |
|
610 if (oldFocus && (focusedScreen||CWsTop::MultiFocusPolicy()) && oldFocus!=aClosingWindow) |
|
611 { |
|
612 oldFocus->LostFocus(); |
|
613 } |
|
614 if (newFocusedScreen) |
|
615 { |
|
616 CWsTop::SetCurrentFocusScreen(newFocusedScreen); |
|
617 newFocus->ReceivedFocus(); |
|
618 } |
|
619 else if (iCurrentFocus && (focusedScreen||CWsTop::MultiFocusPolicy())) |
|
620 { |
|
621 iCurrentFocus->ReceivedFocus(); |
|
622 } |
|
623 WsPointer::UpdatePointerCursor(); |
|
624 TWindowServerEvent::SendFocusChangedEvents(); |
|
625 } |
|
626 TWindowServerEvent::SendGroupListChangedEvents(); |
|
627 } |
|
628 |
|
629 void CScreen::SetShadowVector(const TPoint &aShadowShift) |
|
630 { |
|
631 iShadowShift=aShadowShift; |
|
632 } |
|
633 |
|
634 void CScreen::RemoveFromDefaultOwningList(CWsWindowGroup *aDestroyedGroup) |
|
635 { |
|
636 for (CWsWindowGroup **group=&iDefaultOwningWindow;*group;group=(*group)->NextDefaultOwningWindowPtr()) |
|
637 { |
|
638 if (*group==aDestroyedGroup) |
|
639 { |
|
640 *group=*aDestroyedGroup->NextDefaultOwningWindowPtr(); |
|
641 break; |
|
642 } |
|
643 } |
|
644 } |
|
645 |
|
646 void CScreen::SetDefaultOwningWindow(CWsWindowGroup *aGroup) |
|
647 { |
|
648 RemoveFromDefaultOwningList(aGroup); |
|
649 aGroup->SetNextDefaultOwningWindow(iDefaultOwningWindow); |
|
650 iDefaultOwningWindow=aGroup; |
|
651 } |
|
652 |
|
653 void CScreen::GetScanLine(const TWsSdCmdGetScanLine *aGetScanLine) |
|
654 { |
|
655 TRgb buf[EGetScanLineBufLen]; |
|
656 TPtr8 des((TUint8 *)&buf[0],EGetScanLineBufLen*sizeof(TRgb)); |
|
657 TPoint pos(aGetScanLine->pos); |
|
658 TInt read=0; |
|
659 TInt len=(des.MaxLength()*EGetScanLineBufLen)/CFbsBitmap::ScanLineLength(EGetScanLineBufLen,aGetScanLine->dispMode); |
|
660 if (aGetScanLine->len < 0 || (CFbsBitmap::ScanLineLength(aGetScanLine->len, aGetScanLine->dispMode) > |
|
661 CWsClient::CurrentClient()->ClientMessage().GetDesMaxLength(1))) |
|
662 { |
|
663 CWsClient::PanicCurrentClient(EWservPanicInvalidParameter); |
|
664 } |
|
665 FOREVER |
|
666 { |
|
667 if ((aGetScanLine->len-read)<len) |
|
668 len=aGetScanLine->len-read; |
|
669 iScreenDevice->GetScanLine(des,pos,len,aGetScanLine->dispMode); |
|
670 CWsClient::ReplyBuf(des); |
|
671 read+=len; |
|
672 if (read==aGetScanLine->len) |
|
673 break; |
|
674 pos.iX+=len; |
|
675 } |
|
676 } |
|
677 |
|
678 void CScreen::MaxNumColors(TInt& aColors,TInt& aGrays) |
|
679 { |
|
680 aGrays=0; |
|
681 aColors=TDisplayModeUtils::NumDisplayModeColors(DisplayMode()); |
|
682 if (!TDisplayModeUtils::IsDisplayModeColor(DisplayMode())) |
|
683 { |
|
684 aGrays=aColors; |
|
685 aColors=0; |
|
686 } |
|
687 } |
|
688 |
|
689 #define MODE_TO_FLAG(x) 1<<(x-1) |
|
690 #define ROTATION_TO_FLAG(x) 1<<x |
|
691 TInt CScreen::ColorModesFlag() |
|
692 { |
|
693 return MODE_TO_FLAG(DisplayMode()); |
|
694 } |
|
695 |
|
696 void CScreen::Update() |
|
697 { |
|
698 #if defined(__WINS__) && defined(_DEBUG) |
|
699 if (iOffScreenBitmap) |
|
700 iOffScreenBitmap->Update(); |
|
701 #endif |
|
702 |
|
703 if (iRedirectGc) |
|
704 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EScreenUpdated, iScreenNumber)); |
|
705 else |
|
706 iScreenDevice->Update(); |
|
707 } |
|
708 |
|
709 void CScreen::UpdateGcs() |
|
710 { |
|
711 iScreenGdi->Activate(iScreenDevice); |
|
712 } |
|
713 |
|
714 void CScreen::ChangeDisplayModeForAllOffScreenBitmap(TBool aSwapWidthAndHeight/*=EFalse*/) |
|
715 { |
|
716 TInt err; |
|
717 if (iOffScreenBitmap) |
|
718 { |
|
719 err=iOffScreenBitmap->DisplayModeChanged(aSwapWidthAndHeight); |
|
720 if(err!=KErrNone) |
|
721 { |
|
722 delete iOffScreenBitmap; |
|
723 iOffScreenBitmap=NULL; |
|
724 } |
|
725 } |
|
726 } |
|
727 |
|
728 CFbsScreenDevice *CScreen::ScreenDevice() |
|
729 { |
|
730 return(iScreenDevice); |
|
731 } |
|
732 |
|
733 void CScreen::UpdateOrientation() |
|
734 { |
|
735 CFbsBitGc::TGraphicsOrientation orientation=Orientation(); |
|
736 iScreenGdi->SetOrientation(orientation); |
|
737 TWservCrEvent crEvent(TWservCrEvent::EScreenOrientationChanged,iScreenNumber,&orientation); |
|
738 TWindowServerEvent::NotifyDrawer(crEvent); |
|
739 } |
|
740 |
|
741 void CScreen::SetPointerCursorArea(TInt aMode,const TRect& aRect) |
|
742 { |
|
743 (*iModes)[aMode]->iPointerCursorArea=aRect; |
|
744 WsPointer::SetPointerCursorPos(WsPointer::PointerCursorPos()); |
|
745 } |
|
746 |
|
747 CFbsBitGc::TGraphicsOrientation CScreen::Orientation() |
|
748 { |
|
749 WS_ASSERT_DEBUG(IsValidScreenSizeMode(iScreenSizeMode),EWsPanicInvalidScreenSizeMode); |
|
750 return (*iModes)[iScreenSizeMode]->iRotation; |
|
751 } |
|
752 |
|
753 TRect CScreen::DrawableArea() const |
|
754 { |
|
755 TRect drawRect; |
|
756 iScreenDevice->GetDrawRect(drawRect); |
|
757 return drawRect; |
|
758 } |
|
759 |
|
760 TClientPanic CScreen::SetModeRotation(TInt aMode,CFbsBitGc::TGraphicsOrientation aRotation) |
|
761 { |
|
762 if (!IsValidScreenSizeMode(aMode)) |
|
763 return EWservPanicScreenModeNumber; |
|
764 TSizeMode& mode=*(*iModes)[aMode]; |
|
765 if (!(ROTATION_TO_FLAG(aRotation)&mode.iAlternativeRotations)) |
|
766 return EWservPanicRotation; |
|
767 TInt oldRotation=mode.iRotation; |
|
768 mode.iRotation=aRotation; |
|
769 CWsWindowGroup::NewOrientation(aMode,aRotation, iRootWindow); |
|
770 if (aMode==ScreenSizeMode()) |
|
771 { |
|
772 UpdateOrientation(); |
|
773 TBool shouldSwapWidthAndHeight=ShouldSwapWidthAndHeightOffScBitmap(oldRotation); |
|
774 ChangeDisplayModeForAllOffScreenBitmap(shouldSwapWidthAndHeight); |
|
775 iRootWindow->OrientationChanged(); |
|
776 } |
|
777 return EWservNoPanic; |
|
778 } |
|
779 |
|
780 void CScreen::CycleDisplaySize() |
|
781 { |
|
782 TInt newMode = iScreenSizeMode; |
|
783 TSizeMode* sizeMode = NULL; |
|
784 do |
|
785 { |
|
786 newMode = (newMode+1)%iModes->Count(); |
|
787 sizeMode = (*iModes)[newMode]; |
|
788 } |
|
789 while (sizeMode==NULL); |
|
790 doSetScreenMode(newMode); |
|
791 } |
|
792 |
|
793 inline TBool CScreen::ShouldSwapWidthAndHeightOffScBitmap(TInt aOldRotation) |
|
794 { |
|
795 TInt rot=Abs((*iModes)[iScreenSizeMode]->iRotation-aOldRotation); |
|
796 return (rot==1||rot==3); |
|
797 } |
|
798 |
|
799 void CScreen::doSetScreenMode(TInt aMode) |
|
800 { |
|
801 WS_ASSERT_DEBUG(IsValidScreenSizeMode(aMode),EWsPanicInvalidScreenSizeMode); |
|
802 |
|
803 TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EScreenSizeModeAboutToChange, aMode)); |
|
804 |
|
805 TInt oldRotation=(*iModes)[iScreenSizeMode]->iRotation; |
|
806 iScreenSizeMode=aMode; |
|
807 TBool shouldSwapWidthAndHeight=ShouldSwapWidthAndHeightOffScBitmap(oldRotation); |
|
808 CWsWindowGroup::SetScreenDeviceValidStates(ETrue,shouldSwapWidthAndHeight,this); |
|
809 if (shouldSwapWidthAndHeight) |
|
810 { |
|
811 SetPhysicalScreenSize(); |
|
812 } |
|
813 TWindowServerEvent::SendScreenDeviceChangedEvents(this); |
|
814 ResetFocus(NULL); |
|
815 } |
|
816 |
|
817 void CScreen::UpdateOffScreenBitmapGc(const TBool aSwapWidthAndHeight) |
|
818 { |
|
819 if (iOffScreenBitmap) |
|
820 { |
|
821 iOffScreenBitmap->UpdateGc(aSwapWidthAndHeight); |
|
822 } |
|
823 } |
|
824 |
|
825 void CScreen::CycleOrientation() |
|
826 { |
|
827 WS_ASSERT_DEBUG(IsValidScreenSizeMode(iScreenSizeMode),EWsPanicInvalidScreenSizeMode); |
|
828 TSizeMode& currentSizeMode=*(*iModes)[iScreenSizeMode]; |
|
829 TUint rotations=currentSizeMode.iAlternativeRotations; |
|
830 TInt currentRotation=currentSizeMode.iRotation; |
|
831 TInt rotation=currentRotation+1; |
|
832 while (rotation!=currentRotation) |
|
833 { |
|
834 if (rotation>CFbsBitGc::EGraphicsOrientationRotated270) |
|
835 rotation=CFbsBitGc::EGraphicsOrientationNormal; |
|
836 if (ROTATION_TO_FLAG(rotation)&rotations) |
|
837 break; |
|
838 ++rotation; |
|
839 } |
|
840 if (rotation==currentRotation) |
|
841 { |
|
842 if (rotation>CFbsBitGc::EGraphicsOrientationRotated90) |
|
843 rotation-=2; |
|
844 else |
|
845 rotation+=2; |
|
846 } |
|
847 currentSizeMode.iRotation=REINTERPRET_CAST(CFbsBitGc::TGraphicsOrientation&,rotation); |
|
848 CWsWindowGroup::NewOrientation(iScreenSizeMode,currentSizeMode.iRotation, iRootWindow); |
|
849 |
|
850 UpdateOrientation(); |
|
851 TBool shouldSwapWidthAndHeight=ShouldSwapWidthAndHeightOffScBitmap(currentRotation); |
|
852 ChangeDisplayModeForAllOffScreenBitmap(shouldSwapWidthAndHeight); |
|
853 if (shouldSwapWidthAndHeight) |
|
854 { |
|
855 SetPhysicalScreenSize(); |
|
856 } |
|
857 iRootWindow->OrientationChanged(); |
|
858 } |
|
859 |
|
860 TPoint CScreen::PhysicalToLogical(TPoint aPhysicalPt) |
|
861 { |
|
862 const TSizeMode& mode=ScreenSizeModeData(); |
|
863 TPoint logicalPt; |
|
864 logicalPt=aPhysicalPt-mode.iOrigin; |
|
865 if (mode.iScreenScale.iWidth!=1) |
|
866 logicalPt.iX=(logicalPt.iX>=0 ? logicalPt.iX/mode.iScreenScale.iWidth : (logicalPt.iX-(mode.iScreenScale.iWidth-1))/mode.iScreenScale.iWidth); |
|
867 if (mode.iScreenScale.iHeight!=1) |
|
868 logicalPt.iY=(logicalPt.iY>=0 ? logicalPt.iY/mode.iScreenScale.iHeight : (logicalPt.iY-(mode.iScreenScale.iHeight-1))/mode.iScreenScale.iHeight); |
|
869 return logicalPt; |
|
870 } |
|
871 |
|
872 void CScreen::LoadScreenSizesL(TSize aScreenSize) |
|
873 { |
|
874 _LIT(KWSERVNumScrSizeMode, "NUMSCREENMODES"); |
|
875 TBool allowScrGap=WsIniFile->FindVar(iScreenNumber, KWSERVNumScrSizeMode, iNumScreenSizeModes); |
|
876 iModes=new(ELeave) RPointerArray<TSizeMode>(1); |
|
877 WS_ASSERT_DEBUG(!allowScrGap || (allowScrGap && iNumScreenSizeModes>0), EWsPanicInvalidScreenSizeMode); |
|
878 TInt screenNum=0; |
|
879 FOREVER |
|
880 { |
|
881 ++screenNum; |
|
882 TBuf<32> varNameWidth; |
|
883 TBuf<32> varNameHeight; |
|
884 _LIT(KWSERVScreenWidthPattern,"SCR_WIDTH%d"); |
|
885 varNameWidth.Format(KWSERVScreenWidthPattern,screenNum); |
|
886 _LIT(KWSERVScreenHeightPattern,"SCR_HEIGHT%d"); |
|
887 varNameHeight.Format(KWSERVScreenHeightPattern,screenNum); |
|
888 TSize screenSize; |
|
889 if (!WsIniFile->FindVar(iScreenNumber, varNameWidth, screenSize.iWidth) || |
|
890 !WsIniFile->FindVar(iScreenNumber, varNameHeight, screenSize.iHeight)) |
|
891 { |
|
892 if (allowScrGap && screenNum<=iNumScreenSizeModes) |
|
893 { |
|
894 iModes->AppendL(NULL); |
|
895 continue; |
|
896 } |
|
897 else |
|
898 break; |
|
899 } |
|
900 if (screenSize.iWidth==0 && screenSize.iHeight==0) |
|
901 screenSize=aScreenSize; |
|
902 TSizeMode* newSizeMode=new(ELeave) TSizeMode(screenSize); |
|
903 CleanupStack::PushL(newSizeMode); |
|
904 iModes->AppendL(newSizeMode); |
|
905 CleanupStack::Pop(newSizeMode); |
|
906 ++iNumSupportedScreenSizeModes; |
|
907 } |
|
908 // If sparse index is enabled and no screen size mode defined, all iModes entries will be NULL |
|
909 // Otherwise iModes will be empty |
|
910 if (iModes->Count()==0 || iNumSupportedScreenSizeModes==0) |
|
911 { |
|
912 TSizeMode* defaultSizeMode=new(ELeave) TSizeMode(aScreenSize); |
|
913 if (iModes->Count()>0) |
|
914 (*iModes)[0]=defaultSizeMode; |
|
915 else |
|
916 { |
|
917 CleanupStack::PushL(defaultSizeMode); |
|
918 iModes->AppendL(defaultSizeMode); |
|
919 CleanupStack::Pop(defaultSizeMode); |
|
920 } |
|
921 ++iNumSupportedScreenSizeModes; |
|
922 } |
|
923 if (!allowScrGap) |
|
924 iNumScreenSizeModes=iNumSupportedScreenSizeModes; |
|
925 } |
|
926 |
|
927 void CScreen::LoadScreenSizeProperties() |
|
928 { |
|
929 TBool orientations[4]; |
|
930 TUint allowableRotations=0; |
|
931 TInt ii; |
|
932 iScreenGdi->OrientationsAvailable(orientations); |
|
933 for (ii=0;ii<4;++ii) |
|
934 { |
|
935 if (orientations[ii]) |
|
936 allowableRotations|=ROTATION_TO_FLAG(ii); |
|
937 } |
|
938 TBuf<32> xScale; |
|
939 TBuf<32> yScale; |
|
940 _LIT(KWSERVScreenXScale,"SCR_XSCALE%d"); |
|
941 _LIT(KWSERVScreenYScale,"SCR_YSCALE%d"); |
|
942 for(TInt sizeLoop=0;sizeLoop<iModes->Count();sizeLoop++) |
|
943 { |
|
944 TSizeMode* modePtr=(*iModes)[sizeLoop]; |
|
945 if (!modePtr) |
|
946 continue; |
|
947 TSizeMode& mode=*modePtr; |
|
948 TBuf<32> varLeft; |
|
949 TBuf<32> varTop; |
|
950 TBuf<32> varRotation; |
|
951 TBuf<32> varNameWidth; |
|
952 TBuf<32> varNameHeight; |
|
953 TBuf<32> varDisplayMode; |
|
954 _LIT(KWSERVScreenLeftPattern,"SCR_LEFT%d"); |
|
955 varLeft.Format(KWSERVScreenLeftPattern,sizeLoop+1); |
|
956 _LIT(KWSERVScreenTopPattern,"SCR_TOP%d"); |
|
957 varTop.Format(KWSERVScreenTopPattern,sizeLoop+1); |
|
958 _LIT(KWSERVScreenRotationPattern,"SCR_ROTATION%d"); |
|
959 varRotation.Format(KWSERVScreenRotationPattern,sizeLoop+1); |
|
960 _LIT(KWSERVScreenTwipWidthPattern,"SCR_TWIP_WIDTH%d"); |
|
961 varNameWidth.Format(KWSERVScreenTwipWidthPattern,sizeLoop+1); |
|
962 _LIT(KWSERVScreenTwipHeightPattern,"SCR_TWIP_HEIGHT%d"); |
|
963 varNameHeight.Format(KWSERVScreenTwipHeightPattern,sizeLoop+1); |
|
964 _LIT(KWSERVScreenDisplayModePattern,"SCR_WINDOWMODE%d"); |
|
965 varDisplayMode.Format(KWSERVScreenDisplayModePattern,sizeLoop+1); |
|
966 xScale.Format(KWSERVScreenXScale,sizeLoop+1); |
|
967 yScale.Format(KWSERVScreenYScale,sizeLoop+1); |
|
968 if (!WsIniFile->FindVar(iScreenNumber,xScale,mode.iScreenScale.iWidth)) |
|
969 { |
|
970 mode.iScreenScale.iWidth=1; |
|
971 } |
|
972 if (!WsIniFile->FindVar(iScreenNumber,yScale,mode.iScreenScale.iHeight)) |
|
973 { |
|
974 mode.iScreenScale.iHeight=1; |
|
975 } |
|
976 if (!WsIniFile->FindVar( iScreenNumber, varLeft,mode.iOrigin.iX)) |
|
977 { |
|
978 mode.iOrigin.iX=0; |
|
979 } |
|
980 if (!WsIniFile->FindVar( iScreenNumber, varTop,mode.iOrigin.iY)) |
|
981 { |
|
982 mode.iOrigin.iY=0; |
|
983 } |
|
984 TPtrC displayModeName(NULL,0); |
|
985 mode.iDefaultDisplayMode = iScreenDevice->DisplayMode(); |
|
986 TInt rotation=CFbsBitGc::EGraphicsOrientationNormal; |
|
987 TUint allRotations=0; |
|
988 TPtrC rotList(NULL,0); |
|
989 if (WsIniFile->FindVar( iScreenNumber, varRotation,rotList)) |
|
990 { |
|
991 TLex lex(rotList); |
|
992 TBool foundOne=EFalse; |
|
993 TInt rot; |
|
994 |
|
995 while (!lex.Eos()) |
|
996 { |
|
997 if (!FindNextValue(lex, rot)) |
|
998 { |
|
999 break; |
|
1000 } |
|
1001 if (rot<0 || rot>360) |
|
1002 { |
|
1003 continue; |
|
1004 } |
|
1005 if (rot>4) |
|
1006 { |
|
1007 rot/=90; |
|
1008 } |
|
1009 if (!foundOne) |
|
1010 { |
|
1011 rotation=rot; |
|
1012 foundOne=ETrue; |
|
1013 } |
|
1014 if (rot<=CFbsBitGc::EGraphicsOrientationRotated270) |
|
1015 { |
|
1016 allRotations|=ROTATION_TO_FLAG(rot); |
|
1017 } |
|
1018 } |
|
1019 } |
|
1020 if (allRotations==0) |
|
1021 allRotations=ROTATION_TO_FLAG(rotation); |
|
1022 WS_ASSERT_ALWAYS((ROTATION_TO_FLAG(rotation)&allowableRotations)>0, EWsPanicFailedToInitialise); |
|
1023 mode.iRotation=(CFbsBitGc::TGraphicsOrientation&)rotation; |
|
1024 mode.iAlternativeRotations=allRotations & allowableRotations; |
|
1025 |
|
1026 TSize twipsSize; |
|
1027 TSize pixels(mode.iScreenSize); |
|
1028 |
|
1029 switch(mode.iRotation) |
|
1030 { |
|
1031 // CFbsBitGc::TGraphicsOrientation |
|
1032 case CFbsBitGc::EGraphicsOrientationRotated90: |
|
1033 case CFbsBitGc::EGraphicsOrientationRotated270: |
|
1034 { |
|
1035 //swap the axes in order to use the correct twips per pixel ratio, as CFbsScreenDevice |
|
1036 //does not take into consideration rotation, when converting pixels to twips |
|
1037 if (!WsIniFile->FindVar( iScreenNumber, varNameWidth,twipsSize.iWidth)) |
|
1038 twipsSize.iWidth=iScreenDevice->VerticalPixelsToTwips(pixels.iWidth); |
|
1039 if (!WsIniFile->FindVar( iScreenNumber, varNameHeight,twipsSize.iHeight)) |
|
1040 twipsSize.iHeight=iScreenDevice->HorizontalPixelsToTwips(pixels.iHeight); |
|
1041 break; |
|
1042 } |
|
1043 case CFbsBitGc::EGraphicsOrientationNormal: |
|
1044 case CFbsBitGc::EGraphicsOrientationRotated180: |
|
1045 { |
|
1046 if (!WsIniFile->FindVar( iScreenNumber, varNameWidth,twipsSize.iWidth)) |
|
1047 twipsSize.iWidth=iScreenDevice->HorizontalPixelsToTwips(pixels.iWidth); |
|
1048 if (!WsIniFile->FindVar( iScreenNumber, varNameHeight,twipsSize.iHeight)) |
|
1049 twipsSize.iHeight=iScreenDevice->VerticalPixelsToTwips(pixels.iHeight); |
|
1050 break; |
|
1051 } |
|
1052 default: |
|
1053 WS_PANIC_ALWAYS(EWsPanicFailedToInitialise); |
|
1054 break; |
|
1055 } |
|
1056 mode.iScreenTwipsSize=twipsSize; |
|
1057 } |
|
1058 // |
|
1059 TInt intForFindVar=0; |
|
1060 _LIT(KWSERVIniFileVarSizeMode,"SIZE_MODE"); |
|
1061 WsIniFile->FindVar( iScreenNumber, KWSERVIniFileVarSizeMode,intForFindVar); |
|
1062 iSizeEnforcementMode=(TScreenModeEnforcement)intForFindVar; |
|
1063 } |
|
1064 |
|
1065 void CScreen::SetDigitiserAreas(const TSize& aScreenSize,const TRect& aDigitiserArea) |
|
1066 { |
|
1067 for(TInt sizeLoop=0;sizeLoop<iModes->Count();sizeLoop++) |
|
1068 { |
|
1069 TSizeMode* modePtr=(*iModes)[sizeLoop]; |
|
1070 if (!modePtr) |
|
1071 continue; |
|
1072 TSizeMode& mode=*modePtr; |
|
1073 switch (mode.iRotation) |
|
1074 { |
|
1075 case CFbsBitGc::EGraphicsOrientationNormal: |
|
1076 mode.iPointerCursorArea=aDigitiserArea; |
|
1077 continue; |
|
1078 case CFbsBitGc::EGraphicsOrientationRotated90: |
|
1079 mode.iPointerCursorArea.SetRect(aDigitiserArea.iTl.iY,aScreenSize.iWidth-aDigitiserArea.iBr.iX, |
|
1080 aDigitiserArea.iBr.iY,aScreenSize.iWidth-aDigitiserArea.iTl.iX); |
|
1081 break; |
|
1082 case CFbsBitGc::EGraphicsOrientationRotated180: |
|
1083 mode.iPointerCursorArea.SetRect(-(aDigitiserArea.iBr-aScreenSize),-(aDigitiserArea.iTl-aScreenSize)); |
|
1084 break; |
|
1085 case CFbsBitGc::EGraphicsOrientationRotated270: |
|
1086 mode.iPointerCursorArea.SetRect(aScreenSize.iHeight-aDigitiserArea.iBr.iY,aDigitiserArea.iTl.iX, |
|
1087 aScreenSize.iHeight-aDigitiserArea.iTl.iY,aDigitiserArea.iBr.iX); |
|
1088 break; |
|
1089 } |
|
1090 } |
|
1091 } |
|
1092 |
|
1093 void CScreen::GetScreenSizeAndRotation(TPixelsTwipsAndRotation &aSar, TInt aScreenMode) |
|
1094 { |
|
1095 TSizeMode& mode=*(*iModes)[aScreenMode]; |
|
1096 aSar.iRotation=mode.iRotation; |
|
1097 aSar.iPixelSize=mode.iScreenSize; |
|
1098 aSar.iTwipsSize=mode.iScreenTwipsSize; |
|
1099 if (aSar.iTwipsSize.iWidth==0) |
|
1100 { |
|
1101 aSar.iTwipsSize.iWidth=iScreenDevice->HorizontalPixelsToTwips(aSar.iPixelSize.iWidth); |
|
1102 aSar.iTwipsSize.iHeight=iScreenDevice->VerticalPixelsToTwips(aSar.iPixelSize.iHeight); |
|
1103 } |
|
1104 } |
|
1105 |
|
1106 void CScreen::GetScreenSizeAndRotation(TPixelsAndRotation &aSar, TInt aScreenMode) |
|
1107 { |
|
1108 TSizeMode& mode=*(*iModes)[aScreenMode]; |
|
1109 aSar.iRotation=mode.iRotation; |
|
1110 aSar.iPixelSize=mode.iScreenSize; |
|
1111 } |
|
1112 |
|
1113 TBool CScreen::SetScreenModeEnforcement(TInt aMode) |
|
1114 { |
|
1115 if (aMode<0 || aMode>ESizeEnforcementPixelsTwipsAndRotation) |
|
1116 return EFalse; |
|
1117 TScreenModeEnforcement newMode=(TScreenModeEnforcement)aMode; |
|
1118 if (newMode!=iSizeEnforcementMode) |
|
1119 { |
|
1120 iSizeEnforcementMode=newMode; |
|
1121 CWsWindowGroup::SetScreenDeviceValidStates(EFalse,EFalse,this); |
|
1122 ResetFocus(NULL); |
|
1123 } |
|
1124 return ETrue; |
|
1125 } |
|
1126 |
|
1127 CWsOffScreenBitmap* CScreen::OffScreenBitmap() |
|
1128 { |
|
1129 return iOffScreenBitmap; |
|
1130 } |
|
1131 |
|
1132 CFbsDevice * CScreen::DrawDevice() |
|
1133 { |
|
1134 if (iOffScreenBitmap) |
|
1135 return iOffScreenBitmap->BitmapDevice(); |
|
1136 else |
|
1137 return ScreenDevice(); |
|
1138 } |
|
1139 |
|
1140 void CScreen::FreeOffScreenBitmap() |
|
1141 { |
|
1142 // for Flicker Free test |
|
1143 /** Andy - this either needs to talk to render stages or simply be removed. |
|
1144 Deleting the OSB when CRPs already know it exists is one thing - we dont do it while |
|
1145 testing ones that can't cope - deleting it when render stages use it is something else. |
|
1146 Fortunately we never actually use it. |
|
1147 if (iOffScreenBitmap) |
|
1148 { |
|
1149 delete iOffScreenBitmap; |
|
1150 iOffScreenBitmap = NULL; |
|
1151 } |
|
1152 */ |
|
1153 } |
|
1154 |
|
1155 void CScreen::IncContrast() |
|
1156 { |
|
1157 TInt contrast; |
|
1158 if (iMaxContrast<0) //If failed to get it sofar get it again |
|
1159 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrastMax,iMaxContrast)); |
|
1160 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrast,contrast))) |
|
1161 return; |
|
1162 if (contrast==iMaxContrast) |
|
1163 contrast=-1; |
|
1164 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Set(iScreenNumber,HALData::EDisplayContrast,++contrast)); |
|
1165 } |
|
1166 |
|
1167 void CScreen::DecContrast() |
|
1168 { |
|
1169 TInt contrast; |
|
1170 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrast,contrast))) |
|
1171 return; |
|
1172 if (contrast==0) |
|
1173 { |
|
1174 if (iMaxContrast<0 && TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, |
|
1175 HAL::Get(iScreenNumber,HALData::EDisplayContrastMax,iMaxContrast))) |
|
1176 return; |
|
1177 contrast=iMaxContrast+1; |
|
1178 } |
|
1179 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Set(iScreenNumber,HALData::EDisplayContrast,--contrast)); |
|
1180 } |
|
1181 |
|
1182 void CScreen::IncBrightness() |
|
1183 { |
|
1184 TInt brightness; |
|
1185 if (iMaxBrightness<0) //If failed to get it sofar get it again |
|
1186 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightnessMax,iMaxBrightness)); |
|
1187 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightness,brightness))) |
|
1188 return; |
|
1189 if (brightness==iMaxBrightness) |
|
1190 brightness=-1; |
|
1191 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(iScreenNumber,HALData::EDisplayBrightness,++brightness)); |
|
1192 } |
|
1193 |
|
1194 void CScreen::DecBrightness() |
|
1195 { |
|
1196 TInt brightness; |
|
1197 if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightness,brightness))) |
|
1198 return; |
|
1199 if (brightness==0) |
|
1200 { |
|
1201 if (iMaxBrightness<0 && TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, |
|
1202 HAL::Get(iScreenNumber,HALData::EDisplayBrightnessMax,iMaxBrightness))) |
|
1203 return; |
|
1204 brightness=iMaxBrightness+1; |
|
1205 } |
|
1206 TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(iScreenNumber,HALData::EDisplayBrightness,--brightness)); |
|
1207 } |
|
1208 |
|
1209 TInt CScreen::GetScreenSizeModeListL() |
|
1210 { |
|
1211 RArray<TInt> list(iNumScreenSizeModes); |
|
1212 CleanupClosePushL(list); |
|
1213 TInt index; |
|
1214 for (index=0; index<iModes->Count(); ++index) |
|
1215 { |
|
1216 TSizeMode* modePtr=(*iModes)[index]; |
|
1217 if (modePtr) |
|
1218 list.AppendL(index); |
|
1219 } |
|
1220 TInt count=list.Count(); |
|
1221 CWsClient::ReplyBuf(&list[0], count*sizeof(TInt)); |
|
1222 CleanupStack::PopAndDestroy(&list); |
|
1223 return count; |
|
1224 } |
|
1225 |
|
1226 void CScreen::SetInitialScreenSizeMode() |
|
1227 { |
|
1228 // get first/lowest valid screen size mode, if mode 0 not available |
|
1229 TInt index; |
|
1230 for (index=0; index<iModes->Count(); ++index) |
|
1231 { |
|
1232 TSizeMode* modePtr=(*iModes)[index]; |
|
1233 if (modePtr) |
|
1234 { |
|
1235 iScreenSizeMode=index; |
|
1236 break; |
|
1237 } |
|
1238 } |
|
1239 } |
|
1240 |
|
1241 TDisplayMode CScreen::FirstDefaultDisplayMode() const |
|
1242 { |
|
1243 TInt mode=-1; |
|
1244 while ((*iModes)[++mode]==NULL) |
|
1245 { |
|
1246 WS_ASSERT_DEBUG(mode<iModes->Count()-1,EWsPanicInvalidScreenSizeMode); |
|
1247 } |
|
1248 return((*iModes)[mode]->iDefaultDisplayMode); |
|
1249 } |
|
1250 |
|
1251 CFbsDevice* CScreen::GetFbsDevice() |
|
1252 { |
|
1253 if (iRedirectGc) |
|
1254 { |
|
1255 WS_ASSERT_DEBUG(iRedirectGc->Device(), EWsPanicNullDeviceHandle); |
|
1256 return static_cast<CFbsDevice*>(iRedirectGc->Device()); |
|
1257 } |
|
1258 else |
|
1259 { |
|
1260 return iScreenDevice; |
|
1261 } |
|
1262 } |
|
1263 |
|
1264 void CScreen::AddRedrawRegion(const TRegion& aRegion, TBool aSchedule, TRedrawDepth aDepth) |
|
1265 { |
|
1266 iRedraw->AddRedrawRegion(aRegion, aSchedule, aDepth); |
|
1267 } |
|
1268 |
|
1269 void CScreen::DoRedrawNow() |
|
1270 { |
|
1271 iRedraw->DoRedrawNow(); |
|
1272 } |
|
1273 |
|
1274 // implementing MWsScreen |
|
1275 |
|
1276 const TTime& CScreen::Now() const |
|
1277 { |
|
1278 return iRedraw->Now(); |
|
1279 } |
|
1280 |
|
1281 void CScreen::ScheduleAnimation(const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow,const TTimeIntervalMicroSeconds& aFreq,const TTimeIntervalMicroSeconds& aStop) |
|
1282 { |
|
1283 iRedraw->ScheduleAnimation(aRect,aFromNow,aFreq,aStop); |
|
1284 } |
|
1285 |
|
1286 void CScreen::OnAnimation() |
|
1287 { |
|
1288 iRedraw->OnAnimation(); |
|
1289 } |
|
1290 |
|
1291 void CScreen::Redraw() |
|
1292 { |
|
1293 STACK_REGION bounds; |
|
1294 bounds.AddRect(DrawableArea()); |
|
1295 AddRedrawRegion(bounds); |
|
1296 bounds.Close(); |
|
1297 } |
|
1298 |
|
1299 TBool CScreen::RedrawInvalid(const TArray<TGraphicDrawerId>& aInvalid) |
|
1300 { |
|
1301 TBool wasDirty = EFalse; |
|
1302 STACK_REGION bounds; |
|
1303 bounds.AddRect(DrawableArea()); |
|
1304 STACK_REGION dirty; |
|
1305 TWalkWindowTreeCalcInvalidGraphics calc(&bounds,dirty,aInvalid); |
|
1306 if(calc.CreateSubRegion()) |
|
1307 { |
|
1308 calc.CalcInvalid(*this); |
|
1309 if(dirty.CheckError() || dirty.Count()) |
|
1310 { |
|
1311 Redraw(); |
|
1312 wasDirty = ETrue; |
|
1313 } |
|
1314 calc.DestroyRegions(); |
|
1315 } |
|
1316 dirty.Close(); |
|
1317 bounds.Close(); |
|
1318 return wasDirty; |
|
1319 } |
|
1320 |
|
1321 /** |
|
1322 Overidding MWsObjectProvider |
|
1323 */ |
|
1324 TAny* CScreen::ResolveObjectInterface(TUint aTypeId) |
|
1325 { |
|
1326 TAny* interface = NULL; |
|
1327 |
|
1328 switch (aTypeId) |
|
1329 { |
|
1330 case MWsScreenConfig::EWsObjectInterfaceId: |
|
1331 interface = static_cast<MWsScreenConfig*>(this); |
|
1332 break; |
|
1333 case MWsFrontBuffer::EWsObjectInterfaceId: |
|
1334 interface = static_cast<MWsFrontBuffer*>(this); |
|
1335 break; |
|
1336 case MWsWindow::EWsObjectInterfaceId: |
|
1337 interface = static_cast<MWsWindow*>(RootWindow()); |
|
1338 break; |
|
1339 } |
|
1340 |
|
1341 if (!interface && iOffScreenBitmap) |
|
1342 interface = iOffScreenBitmap->ResolveObjectInterface(aTypeId); |
|
1343 |
|
1344 if (!interface) |
|
1345 interface = iRedraw->ResolveObjectInterface(aTypeId); |
|
1346 |
|
1347 return interface; |
|
1348 } |
|
1349 |
|
1350 /** |
|
1351 Implementing MWsScreenConfig |
|
1352 */ |
|
1353 TDisplayMode CScreen::DisplayMode() const |
|
1354 { |
|
1355 return iScreenDevice->DisplayMode(); |
|
1356 } |
|
1357 |
|
1358 TSize CScreen::SizeInPixels() const |
|
1359 { |
|
1360 return iScreenDevice->SizeInPixels(); |
|
1361 } |
|
1362 |
|
1363 TSize CScreen::ScreenModeSizeInPixels() const |
|
1364 { |
|
1365 return (*iModes)[iScreenSizeMode]->iScreenSize; |
|
1366 } |
|
1367 |
|
1368 TInt CScreen::Stride() const |
|
1369 { |
|
1370 return iScreenDevice->Stride(); |
|
1371 } |
|
1372 |
|
1373 CFbsBitGc::TGraphicsOrientation CScreen::Orientation() const |
|
1374 { |
|
1375 return iScreenDevice->Orientation(); |
|
1376 } |
|
1377 |
|
1378 TInt CScreen::SizeMode() const |
|
1379 { |
|
1380 return iScreenSizeMode; |
|
1381 } |
|
1382 |
|
1383 TSize CScreen::ScalingFactor() const |
|
1384 { |
|
1385 return (*iModes)[iScreenSizeMode]->iScreenScale; |
|
1386 } |
|
1387 |
|
1388 TPoint CScreen::Origin() const |
|
1389 { |
|
1390 return (*iModes)[iScreenSizeMode]->iOrigin; |
|
1391 } |
|
1392 |
|
1393 TPoint CScreen::ScaledOrigin() const |
|
1394 { |
|
1395 return (*iModes)[iScreenSizeMode]->ScaledOrigin(); |
|
1396 } |
|
1397 |
|
1398 /** |
|
1399 Implementing MWsFrontBuffer |
|
1400 */ |
|
1401 const TAny* CScreen::GetBits() |
|
1402 { |
|
1403 return iScreenDevice->Bits(); |
|
1404 } |
|
1405 |
|
1406 CFbsBitGc* CScreen::GetBitGc() |
|
1407 { |
|
1408 return iScreenGdi; |
|
1409 } |
|
1410 |
|
1411 CFbsBitGc* CScreen::GetBitGcCurrent() |
|
1412 { |
|
1413 if (iRedirectGc) |
|
1414 return iRedirectGc; |
|
1415 else |
|
1416 return iScreenGdi; |
|
1417 } |
|
1418 |
|
1419 /** |
|
1420 Redirect screen drawing to specified gc. Passing NULL will stop redirection. |
|
1421 */ |
|
1422 TInt CScreen::SetBitGc(CFbsBitGc* aBitGc) |
|
1423 { |
|
1424 if (aBitGc && (aBitGc==iScreenGdi || aBitGc==iRedirectGc)) |
|
1425 return KErrAlreadyExists; |
|
1426 |
|
1427 if (aBitGc && !aBitGc->Device()) |
|
1428 return KErrArgument; |
|
1429 |
|
1430 // screen shall not be redirected when there is at least one DSA client is actively drawing |
|
1431 if (aBitGc && iDsaDrawState==EDsaDrawStateDrawing) |
|
1432 return KErrInUse; |
|
1433 |
|
1434 iRedirectGc = aBitGc; |
|
1435 |
|
1436 // Redraw window CWindowGC objects have CFbsBitGcs active on the screen device and need reactivating: |
|
1437 TWalkWindowTreeReactivateGcs wwt; |
|
1438 RootWindow()->WalkWindowTree(wwt, EWalkChildren); |
|
1439 |
|
1440 // Andy - should we do something with the CPlaybackGc here? Can they be active at this point? |
|
1441 // if so, do they care, or should it already be handled for them? |
|
1442 |
|
1443 return KErrNone; |
|
1444 } |
|
1445 |
|
1446 TInt CScreen::SetBitGc(CFbsBitGc* aBitGc, TBool aInvalidateScreen) |
|
1447 { |
|
1448 const TInt err = SetBitGc(aBitGc); |
|
1449 |
|
1450 if (err==KErrNone && aInvalidateScreen) |
|
1451 iRootWindow->InvalidateWholeScreen(); |
|
1452 |
|
1453 return err; |
|
1454 } |
|
1455 |
|
1456 void CScreen::DiscardAllSchedules() |
|
1457 { |
|
1458 iRedraw->DiscardAllSchedules(); |
|
1459 } |
|
1460 |
|
1461 void CScreen::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty) |
|
1462 { |
|
1463 iRedraw->ScheduleRegionUpdate(aDefinitelyDirty); |
|
1464 } |
|
1465 void CScreen::DSARegionSyncStart( CWsDirectScreenAccess& aDSA ) |
|
1466 { |
|
1467 iRedraw->BanThisRegionUpdate( aDSA.RegionUnderSync() ); |
|
1468 } |
|
1469 |
|
1470 void CScreen::DSARegionSyncOver( CWsDirectScreenAccess& aDSA ) |
|
1471 { |
|
1472 iRedraw->LiftRegionUpdateBan( aDSA.RegionUnderSync() ); |
|
1473 } |
|
1474 |
|
1475 TBool CScreen::IsUpdatePending() |
|
1476 { |
|
1477 return iRedraw->IsUpdatePending(); |
|
1478 } |
|
1479 |
|
1480 TBool CScreen::IsDSAClientWindow( const CWsClientWindow* aWin ) const |
|
1481 { |
|
1482 TBool res = EFalse; |
|
1483 if ( ! iDirects.IsEmpty() ) |
|
1484 { |
|
1485 TSglQueIter<CWsDirectScreenAccess> iter( (TSglQueBase&)iDirects ); |
|
1486 iter.SetToFirst(); |
|
1487 CWsDirectScreenAccess* dsa; |
|
1488 while ( (dsa = iter++) != NULL && !res ) |
|
1489 { |
|
1490 res = (dsa->ClientWindow() == aWin ) && ( dsa->IsVisible() || dsa->IsSyncTimeoutPending() ); |
|
1491 } |
|
1492 } |
|
1493 return res; |
|
1494 } |
|
1495 |
|
1496 void CScreen::AcceptFadeRequest( CWsWindow* aWin, TBool aIsFaded, TBool aIsBehind, TBool aIncludeChildren ) |
|
1497 { |
|
1498 iRedraw->AcceptFadeRequest( aWin, aIsFaded, aIsBehind, aIncludeChildren ); |
|
1499 } |