windowing/windowserver/nga/SERVER/openwfc/screen.cpp
changeset 0 5d03bc08d59c
child 69 3365349494cc
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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     }