graphicsdeviceinterface/screendriver/sgeneric/scnew.cpp
changeset 0 5d03bc08d59c
child 18 5e30ef2e26cb
child 36 01a6848ebfd7
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 // This module implements the functions that create the screen class depending
       
    15 // on the screen type.
       
    16 // Include files                                                   
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file
       
    22 */
       
    23 /********************************************************************/
       
    24 #include "BITDRAW.H"
       
    25 #include <hal.h>
       
    26 #include "ScreenInfo.h"
       
    27 #include "scdraw.h"
       
    28 #include "scdraw.inl"
       
    29 #include <graphics/gdi/gdiconsts.h>
       
    30 
       
    31 
       
    32 /**
       
    33 Creates an instance of CFbsDrawDevice class.
       
    34 @param aScreenNo Screen number
       
    35 @param aDispMode Display mode
       
    36 @param aScreenInfo Screen parameters: video memory address and screen size
       
    37 @return A pointer to the created CFbsDrawDevice object
       
    38 @leave System-wide error code including KErrNoMemory
       
    39 @internalComponent
       
    40 */
       
    41 static CFbsDrawDevice* CreateInstanceL(TInt aScreenNo,
       
    42 									   TDisplayMode aDispMode,
       
    43 									   const TScreenInfo& aScreenInfo)
       
    44 	{
       
    45 	CFbsDrawDevice* drawDevice = NULL;
       
    46 
       
    47 	TInt modeCount;
       
    48 	TInt matchedMode=-1;
       
    49 	//there is some "ambiguity" about 24 and 32 bit modes... 
       
    50 	//They are both byte per color component, and both actually have 32 bits per pixel memory use.
       
    51 	//This ambiguity does not exist between 12 and 16 bit modes,
       
    52 	//because they are distinct color component patterns (x444, 565)
       
    53 	//but for now 24 and 32 bit modes are considered equivalent here.
       
    54 
       
    55 	if (HAL::Get(aScreenNo, HALData::EDisplayNumModes,modeCount)== KErrNone && modeCount>=1)
       
    56 		{	//If multiple modes are supported then the highest bpp must be found
       
    57 		
       
    58 		TInt reqBpp= TDisplayModeUtils::NumDisplayModeBitsPerPixel(aDispMode);
       
    59 		TInt reqBpp2=reqBpp;
       
    60 		if ( reqBpp==24 || reqBpp==32 ) //Best to be specific here. Who knows how likely is 30 or 64 bpp support?
       
    61 			{
       
    62 			reqBpp2=32+24 - reqBpp;   //reflect 24<==>32
       
    63 			//Important compile-time decision embedded here: Only one 32-bit mode is supported
       
    64 			if(CFbsDrawDevice::DisplayMode16M() != aDispMode)
       
    65 				{
       
    66 				User::Leave(KErrNotSupported);
       
    67 				}
       
    68 			}
       
    69 		for (TInt mode=0; mode<modeCount; mode++)
       
    70 			{
       
    71 			TInt modeBpp=mode;
       
    72 			if(HAL::Get(aScreenNo, HALData::EDisplayBitsPerPixel, modeBpp) == KErrNone)
       
    73 				{
       
    74 				if (modeBpp==reqBpp || modeBpp==reqBpp2)
       
    75 					{
       
    76 					matchedMode=mode;
       
    77 					break;
       
    78 					}
       
    79 				}
       
    80 			}
       
    81 		}
       
    82 	if (matchedMode==-1)
       
    83 		{	//This is the expected error code
       
    84 		User::Leave(KErrNotSupported);
       
    85 		}
       
    86 	//Switch the display mode, call the constructor of the class defined
       
    87 	switch(aDispMode)
       
    88 		{
       
    89 	/** Monochrome display mode (1 bpp) */
       
    90 	case EGray2:
       
    91 		{
       
    92 		CDrawOneBppScreenBitmap* drawDeviceX = new (ELeave) CDrawOneBppScreenBitmap;
       
    93 		drawDevice=drawDeviceX;
       
    94 		CleanupStack::PushL(drawDevice) ;
       
    95 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
    96 	                                                    aScreenNo,
       
    97 														aScreenInfo.iAddress, 
       
    98 														aScreenInfo.iSize,matchedMode));
       
    99 		}
       
   100 		break;
       
   101 	/** Four grayscales display mode (2 bpp) */
       
   102 	case EGray4:
       
   103 		{
       
   104 		CDrawTwoBppScreenBitmap* drawDeviceX = new (ELeave) CDrawTwoBppScreenBitmap;
       
   105 		drawDevice=drawDeviceX;
       
   106 		CleanupStack::PushL(drawDevice) ;
       
   107 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   108 	                                                    aScreenNo,
       
   109 														aScreenInfo.iAddress, 
       
   110 														aScreenInfo.iSize,matchedMode));
       
   111 		}
       
   112 		break;
       
   113 	/** 16 grayscales display mode (4 bpp) */
       
   114 	case EGray16:
       
   115 		{
       
   116 		CDrawFourBppScreenBitmapGray* drawDeviceX = new (ELeave) CDrawFourBppScreenBitmapGray;
       
   117 		drawDevice=drawDeviceX;
       
   118 		CleanupStack::PushL(drawDevice) ;
       
   119 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   120 	                                                    aScreenNo,
       
   121 														aScreenInfo.iAddress, 
       
   122 														aScreenInfo.iSize,matchedMode));
       
   123 		}
       
   124 		break;
       
   125 	/** 256 grayscales display mode (8 bpp) */
       
   126 	case EGray256:
       
   127 		{
       
   128 		CDrawEightBppScreenBitmapGray* drawDeviceX = new (ELeave) CDrawEightBppScreenBitmapGray;
       
   129 		drawDevice=drawDeviceX;
       
   130 		CleanupStack::PushL(drawDevice) ;
       
   131 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   132 	                                                    aScreenNo,
       
   133 														aScreenInfo.iAddress, 
       
   134 														aScreenInfo.iSize,matchedMode));
       
   135 		}
       
   136 		break;
       
   137 	/** Low colour EGA 16 colour display mode (4 bpp) */
       
   138 	case EColor16:
       
   139 		{
       
   140 		CDrawFourBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawFourBppScreenBitmapColor;
       
   141 		drawDevice=drawDeviceX;
       
   142 		CleanupStack::PushL(drawDevice) ;
       
   143 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   144 	                                                    aScreenNo,
       
   145 														aScreenInfo.iAddress, 
       
   146 														aScreenInfo.iSize,matchedMode));
       
   147 		}
       
   148 		break;
       
   149 	/** 256 colour display mode (8 bpp) */
       
   150 	case EColor256:
       
   151 		{
       
   152 		CDrawEightBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawEightBppScreenBitmapColor;
       
   153 		drawDevice=drawDeviceX;
       
   154 		CleanupStack::PushL(drawDevice) ;
       
   155 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   156 	                                                    aScreenNo,
       
   157 														aScreenInfo.iAddress, 
       
   158 														aScreenInfo.iSize,matchedMode));
       
   159 		}
       
   160 		break;
       
   161 	/** 4,000 colour display mode (16 bpp) */
       
   162 	case EColor4K: // 12 Bpp color mode
       
   163 		{
       
   164 		CDrawTwelveBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawTwelveBppScreenBitmapColor;
       
   165 		drawDevice=drawDeviceX;
       
   166 		CleanupStack::PushL(drawDevice) ;
       
   167 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   168 	                                                    aScreenNo,
       
   169 														aScreenInfo.iAddress, 
       
   170 														aScreenInfo.iSize,matchedMode));
       
   171 		}
       
   172 		break;
       
   173 
       
   174 	case EColor64K: // 16 Bpp color mode
       
   175 		{
       
   176 		CDrawSixteenBppScreenBitmap* drawDeviceX = new (ELeave) CDrawSixteenBppScreenBitmap;
       
   177 		drawDevice=drawDeviceX;
       
   178 		CleanupStack::PushL(drawDevice) ;
       
   179 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   180 	                                                    aScreenNo,
       
   181 														aScreenInfo.iAddress, 
       
   182 														aScreenInfo.iSize,matchedMode));
       
   183 		}
       
   184 		break;
       
   185 	case EColor16MU:
       
   186 		{
       
   187 		CDrawUTwentyFourBppScreenBitmap* drawDeviceX = new (ELeave) CDrawUTwentyFourBppScreenBitmap;
       
   188 		drawDevice=drawDeviceX;
       
   189 		CleanupStack::PushL(drawDevice) ;
       
   190 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   191 	                                                    aScreenNo,
       
   192 														aScreenInfo.iAddress, 
       
   193 														aScreenInfo.iSize,matchedMode));
       
   194 		}
       
   195 		break;
       
   196 	case EColor16MA:
       
   197 		{
       
   198 		CDrawThirtyTwoBppScreenBitmapAlpha* drawDeviceX = new (ELeave) CDrawThirtyTwoBppScreenBitmapAlpha;
       
   199 		drawDevice=drawDeviceX;
       
   200 		CleanupStack::PushL(drawDevice) ;
       
   201 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   202 	                                                    aScreenNo,
       
   203 														aScreenInfo.iAddress, 
       
   204 														aScreenInfo.iSize,matchedMode));
       
   205 		}
       
   206 		break;
       
   207 	case EColor16MAP:
       
   208 		{
       
   209 		CDrawThirtyTwoBppScreenBitmapAlphaPM* drawDeviceX = new (ELeave) CDrawThirtyTwoBppScreenBitmapAlphaPM;
       
   210 		drawDevice=drawDeviceX;
       
   211 		CleanupStack::PushL(drawDevice) ;
       
   212 		User::LeaveIfError(drawDeviceX->ConstructScreen(
       
   213 	                                                    aScreenNo,
       
   214 														aScreenInfo.iAddress, 
       
   215 														aScreenInfo.iSize,matchedMode));
       
   216 		}
       
   217 		break;
       
   218 	default:
       
   219 		User::Leave(KErrNotSupported);
       
   220 		}
       
   221 
       
   222 	CleanupStack::Pop(drawDevice);
       
   223 	return drawDevice;
       
   224 	}
       
   225 
       
   226 
       
   227 /********************************************************************/
       
   228 /*  Implementation of CFbsDrawDevice class                          */
       
   229 /********************************************************************/
       
   230 
       
   231 /**
       
   232 This function calls the correct constructor in function of the display mode.
       
   233 @param aInfo, Structure of the LCD info
       
   234 @param aDispMode, display mode   
       
   235 @return A pointer to just created screen device, which implements CFbsDrawDevice interface
       
   236 @deprecated Use CFbsDrawDevice::NewScreenDeviceL(TInt aScreenNo, TDisplayMode aDispMode)
       
   237 */
       
   238 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewScreenDeviceL(TScreenInfoV01 aInfo, TDisplayMode aDispMode)
       
   239 	{
       
   240 	__ASSERT_ALWAYS(aInfo.iScreenAddressValid, Panic(EScreenDriverPanicInvalidWindowHandle));
       
   241 	TScreenInfo screenInfo(aInfo.iScreenAddress, aInfo.iScreenSize);
       
   242 	return ::CreateInstanceL(KDefaultScreenNo, aDispMode, screenInfo);
       
   243 	}
       
   244 	
       
   245 	
       
   246 
       
   247 /**
       
   248 Creates a new screen device instance, which implements CFbsDrawDevice interface.
       
   249 The method has to be implemented for each type of supported video hardware.
       
   250 @param aScreenNo Screen number
       
   251 @param aDispMode Requested display mode
       
   252 @return A pointer to just created screen device, which implements CFbsDrawDevice interface
       
   253 @leave KErrNoMemory Not enough memory
       
   254 	   KErrNotSupported The requested screen device type is not supported
       
   255 */
       
   256 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewScreenDeviceL(TInt aScreenNo,
       
   257 														  TDisplayMode aDispMode)
       
   258 	{
       
   259 	TInt width = 0, height = 0;
       
   260 	User::LeaveIfError(HAL::Get(aScreenNo, HALData::EDisplayXPixels, width));
       
   261 	User::LeaveIfError(HAL::Get(aScreenNo, HALData::EDisplayYPixels, height));
       
   262 	__ASSERT_ALWAYS(width > 0 && height > 0, Panic(EScreenDriverPanicInvalidHalValue));
       
   263 	
       
   264 	TUint8* address = 0;
       
   265 	
       
   266 	TScreenInfo screenInfo(address, TSize(width, height));
       
   267 	return ::CreateInstanceL(aScreenNo, aDispMode, screenInfo);
       
   268 	}
       
   269 
       
   270 /**
       
   271  Depending on the current graphics hardware this 
       
   272  will return one of the 16M video modes defined in
       
   273  TDisplayMode, or ENone if a 16M video mode is not supported.
       
   274  The method has to be implemented on all hardware platforms.
       
   275  @return a 16M display mode or ENone.
       
   276  ENone - it means that current hardware doesn't have 16M color mode.
       
   277 */
       
   278 EXPORT_C TDisplayMode CFbsDrawDevice::DisplayMode16M()
       
   279 	{
       
   280 	return EColor16MAP;
       
   281 	}
       
   282 
       
   283 
       
   284 /**
       
   285 Complete construction of the helper object.
       
   286 @param aScreenNo	The screen number, starting from 0.
       
   287 @param aPixelFormat	Pixel format UID or 0 for default based on bpp
       
   288 @return KErrNone or a system wide error value.
       
   289 */
       
   290 TInt CScreenDeviceHelper::Construct(TInt aScreenNo, TUidPixelFormat aPixelFormat, TUint aHalMode)
       
   291 	{
       
   292 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField] = aScreenNo;		// Screen number
       
   293 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] = aHalMode;			// Rotation and hal mode index
       
   294 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeGuidField] = aPixelFormat;	//May be zero for non-GCE modes
       
   295 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeClassField] 
       
   296 			= ((TUint32)(TSurfaceId::EScreenSurface) << TSurfaceId::TScreenSurfaceUsage::ETypeClassShift);	// Type
       
   297 	iAssignedOrientation = EDeviceOrientationNormal; // Actual rotation is held seperately from surface ID
       
   298 
       
   299 	TInt val = 0;
       
   300 	iHasChunk = EFalse;
       
   301 	TInt ret = HAL::Get(aScreenNo,HALData::EDisplayMemoryHandle,val);
       
   302 	if (ret == KErrNone)
       
   303 		{
       
   304 		__ASSERT_DEBUG(val != 0, Panic(EScreenDriverPanicInvalidHalValue));
       
   305 		RChunk chunk;
       
   306 		ret = chunk.SetReturnedHandle(val);
       
   307 		if (ret != KErrNone)
       
   308 			{
       
   309 			return ret;
       
   310 			}
       
   311 		iChunk = chunk;
       
   312 		ret = iChunk.Duplicate(RThread(), EOwnerProcess);
       
   313 		// Close before checking for errors, as we don't want to leave the
       
   314 		// temporary chunk handle floating about. 
       
   315 		chunk.Close();
       
   316 		if (ret != KErrNone)
       
   317 			{
       
   318 			return ret;
       
   319 			}
       
   320 		iHasChunk = ETrue;
       
   321 		}
       
   322 	// KErrNotSupported is returned if we can't get the Handle because it's not a driver
       
   323 	// that supports the concept. We don't return that error, since it's perfectly valid
       
   324 	// to not support this. 
       
   325 	else if (ret != KErrNotSupported)   
       
   326 		{
       
   327 		return ret;
       
   328 		}
       
   329 	return iSurfaceUpdateSession.Connect();
       
   330 	}
       
   331 
       
   332 CScreenDeviceHelper::~CScreenDeviceHelper()
       
   333 	{
       
   334 	
       
   335 	iSurfaceUpdateSession.Close();
       
   336 	iChunk.Close();
       
   337 	}
       
   338 
       
   339 void CScreenDeviceHelper::NotifyWhenAvailable(TRequestStatus& aStatus)
       
   340 	{
       
   341 	iSurfaceUpdateSession.NotifyWhenAvailable(aStatus);
       
   342 	}
       
   343 
       
   344 /**
       
   345 Implementation of corresponding function in CDrawDevice, utilizing a tracked
       
   346 update region. Updates the screen from the surface, if the update region is
       
   347 not empty.
       
   348 */
       
   349 void CScreenDeviceHelper::Update()
       
   350 	{
       
   351 	if (iUpdateRegion.IsEmpty())
       
   352 		return;
       
   353 
       
   354 	iSurfaceUpdateSession.SubmitUpdate(ScreenNumber(), iSurface, 0, &iUpdateRegion);
       
   355 	iUpdateRegion.Clear();
       
   356 	}
       
   357 
       
   358 /**
       
   359 Implementation of corresponding function in CDrawDevice, utilizing a tracked
       
   360 update region. Adds the given region to the update region and updates the
       
   361 screen.
       
   362 @param aRegion	Additional region to be updated.
       
   363 */
       
   364 void CScreenDeviceHelper::Update(const TRegion& aRegion)
       
   365 	{
       
   366 	if(!aRegion.IsEmpty() && !aRegion.CheckError())
       
   367 		{
       
   368 		TInt rcCnt = aRegion.Count();
       
   369 		for (TInt ii=0; ii < rcCnt; ++ii)
       
   370 			{
       
   371 			UpdateRegion(aRegion[ii]);
       
   372 			}
       
   373 		}
       
   374 	Update();
       
   375 	}
       
   376 
       
   377 /**
       
   378 Implementation of corresponding function in CDrawDevice, utilizing a tracked
       
   379 update region. Adds the given rectangle to the update region.
       
   380 @param aRect	Rectangle to be added to the update region.
       
   381 */
       
   382 void CScreenDeviceHelper::UpdateRegion(const TRect& aRect)
       
   383 	{
       
   384 	if (aRect.IsEmpty())
       
   385 		{
       
   386 		// Adding an empty rectangle should have no effect.
       
   387 		return;
       
   388 		}
       
   389 
       
   390 	if (iUpdateRegion.CheckError())
       
   391 		{
       
   392 		// Try to ensure the region doesn't keep an error forever.
       
   393 		iUpdateRegion.Clear();
       
   394 		}
       
   395 
       
   396 	TRect bounds(iUpdateRegion.BoundingRect());
       
   397 	iUpdateRegion.AddRect(aRect);
       
   398 
       
   399 	// If the region fills up, start again with the old bounding box plus this
       
   400 	// rectangle.
       
   401 	if (iUpdateRegion.CheckError())
       
   402 		{
       
   403 		iUpdateRegion.Clear();
       
   404 		iUpdateRegion.AddRect(bounds);
       
   405 		iUpdateRegion.AddRect(aRect);
       
   406 		}
       
   407 	}
       
   408 
       
   409 /**
       
   410 Reset the update region to be empty without submitting any outstanding updates.
       
   411 */
       
   412 void CScreenDeviceHelper::ResetUpdateRegion()
       
   413 	{
       
   414 	iUpdateRegion.Clear();
       
   415 	}
       
   416 
       
   417 /**
       
   418 This function returns the current surface in use for this screen.
       
   419 @param aSurface	The identifier to be updated with the current screen surface.
       
   420 */
       
   421 void CScreenDeviceHelper::GetSurface(TSurfaceId& aSid) const
       
   422 	{
       
   423 	aSid = iSurface;
       
   424 	}
       
   425 
       
   426 /**
       
   427 This function is used to request the device orientations supported by the
       
   428 screen device.
       
   429 @return A bitwise combination of one or more TDeviceOrientation enumerated
       
   430 values indicating the device orientations that are supported by this device.
       
   431 */
       
   432 TUint CScreenDeviceHelper::DeviceOrientationsAvailable(const TSize& aScreenSize) const
       
   433 	{
       
   434 	//All that can be reported here is what the CScreenDevice can support via HAL
       
   435 	//With generic driver, the runtime can be further restricted by the GCE
       
   436 	if (	aScreenSize.iWidth	&&	aScreenSize.iWidth==aScreenSize.iHeight	)
       
   437 		{
       
   438 		return EDeviceOrientationNormal | EDeviceOrientation90CW |
       
   439 			EDeviceOrientation180 | EDeviceOrientation270CW;
       
   440 		}
       
   441 	//Query base HAL for rotated view support
       
   442 	TInt	offset1=iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField]|TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
       
   443 	if (	HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, offset1)==KErrNone
       
   444 		&&	offset1!=0)
       
   445 		{
       
   446 		return EDeviceOrientationNormal | EDeviceOrientation90CW |
       
   447 			EDeviceOrientation180 | EDeviceOrientation270CW;
       
   448 		}
       
   449 	else
       
   450 		return EDeviceOrientationNormal | EDeviceOrientation180;
       
   451 	}
       
   452 
       
   453 /**
       
   454 This function selects the surface and device buffer to use in the screen
       
   455 driver for this screen. Normal and 180° rotations will generally use the same
       
   456 surface, while 90° and 270° will use another. The surfaces may have different
       
   457 width, height, stride and surface ID, so functions that make use of any of
       
   458 these may be affected after a change in surface orientation, and the return
       
   459 value should be checked for this reason.
       
   460 
       
   461 This call does not change the way rendering is performed, but may operate on
       
   462 the underlying memory using a new shape. The call does not change the display
       
   463 controller's settings, as this is handled via the GCE. All this changes are the
       
   464 internal attributes of the screen device and driver objects. A CFbsBitGc object
       
   465 activated on the device should be reactivated, to update its own attributes, or
       
   466 drawing may be corrupted.
       
   467 
       
   468 Note: while TDeviceOrientation values do not directly correspond to 
       
   469 CFbsBitGc::TGraphicsOrientation values, and cannot be used interchangeably, it
       
   470 is simple to generate the former from the latter using the left-shift operator
       
   471 (i.e. device == (1 &lt;&lt; graphics)). In particular a device orientation of
       
   472 90 degrees clockwise is equivalent to a content orientation of 90 degrees anti-
       
   473 clockwise, which is what TGraphicsOrientation refers to for the equivalent
       
   474 setting. The letters &quot;CW&quot; in the TDeviceOrientation enumeration refer
       
   475 to a clockwise device rotation, so EDeviceOrientation90CW is a 90 degree
       
   476 clockwise rotation of the device.
       
   477 
       
   478 @param aOrientation	The new device orientation, relative to the normal physical
       
   479 screen orientation.
       
   480 @param aNewSize The new pixel dimensions of the surface to be used.
       
   481 @return ETrue is returned if any of the surface, width, height or stride
       
   482 attributes of the screen device have changed as a result of the call or EFalse
       
   483 if none of the attributes have changed.
       
   484 */
       
   485 TBool CScreenDeviceHelper::SetDeviceOrientation(TDeviceOrientation aOrientation, TSize& aNewSize)
       
   486 	{
       
   487 	// Check only one orientation bit is set
       
   488 	if (((TInt)aOrientation - 1) & aOrientation)
       
   489 		{
       
   490 		Panic(EScreenDriverPanicInvalidParameter);
       
   491 		}
       
   492 
       
   493 	// Check the orientation is supported
       
   494 	if ((DeviceOrientationsAvailable(aNewSize) & aOrientation) == 0)
       
   495 		{
       
   496 		Panic(EScreenDriverPanicInvalidParameter);
       
   497 		}
       
   498 
       
   499 	iAssignedOrientation=aOrientation;
       
   500 	
       
   501 	return SetDeviceFlipMode(ConvertFlip(aOrientation),aNewSize);
       
   502 	}
       
   503 /** Sets or clears the flipped flag indicating that the width and height have been swapped for a +/-90 deg rotation
       
   504  *  Rotation is not required for square displays unless the Hal wants one.
       
   505  **/
       
   506 TBool CScreenDeviceHelper::SetDeviceFlipMode(TBool aFlip, TSize& aNewSize)
       
   507 	{
       
   508 	//This is now a private method that doesn't validate aFlip
       
   509 	TInt newFlipMode= iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
       
   510 	if (aFlip)
       
   511 		{
       
   512 		newFlipMode|=TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
       
   513 		}
       
   514 	else
       
   515 		{
       
   516 		newFlipMode&=~TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
       
   517 		}
       
   518 	if (newFlipMode == iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField])
       
   519 		{
       
   520 		// No change to mode requested.
       
   521 		return EFalse;
       
   522 		}
       
   523 	TInt err=0;
       
   524 	err|=HAL::Get(ScreenNumber(), HALData::EDisplayXPixels, aNewSize.iWidth);
       
   525 	err|=HAL::Get(ScreenNumber(), HALData::EDisplayYPixels, aNewSize.iHeight);
       
   526 	__ASSERT_ALWAYS(err==KErrNone,Panic(EScreenDriverPanicInvalidHalValue));
       
   527 	 if (aNewSize.iWidth==aNewSize.iHeight)
       
   528 		{	//Attempt optimisation to not flip if the screen is square, so avoid recomposition.
       
   529 		TInt	stride1=iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
       
   530 		TInt	stride2=stride1^TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
       
   531 		TInt	offset1=stride1;
       
   532 		TInt	offset2=stride2;
       
   533 		//Does the rotated mode have any other attributes that differ?
       
   534 		//It is just about possible to imagine that the rotated display 
       
   535 		//wants to use a different setting for the flipped legacy buffer for optimisation purposes.
       
   536 		err|=HAL::Get(ScreenNumber(), HALData::EDisplayOffsetToFirstPixel, offset1);
       
   537 		err|=HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, stride1);
       
   538 		//The existing mode settings should not fail... we are already in this mode!
       
   539 		__ASSERT_ALWAYS(err==KErrNone,Panic(EScreenDriverPanicInvalidHalValue));
       
   540 		
       
   541 		TInt rotatedErr =	HAL::Get(ScreenNumber(), HALData::EDisplayOffsetToFirstPixel, offset2);
       
   542 		rotatedErr |=		HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, stride2);
       
   543 		//The HAL may indicate rotation is not required by failing to return data or returning the same data
       
   544 		if ( rotatedErr!=KErrNone || stride2==0 ) //Offset can legitimately be zero.
       
   545 			{	
       
   546 			// No change to mode supported.
       
   547 			return EFalse;
       
   548 			}
       
   549 		if ( stride1==stride2 && offset1==offset2 )
       
   550 			{
       
   551 			// No change to mode needed.
       
   552 			return EFalse;
       
   553 			}
       
   554 		}
       
   555 
       
   556 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] = newFlipMode;
       
   557 	if (aFlip)
       
   558 		{
       
   559 		// Swap width and height in the alternate orientation.
       
   560 		aNewSize.SetSize(aNewSize.iHeight, aNewSize.iWidth);
       
   561 		}
       
   562 	return ETrue;
       
   563 	}
       
   564 /**	Returns the stride for the given mode.
       
   565  *  This method must not panic if it should fail!
       
   566  **/
       
   567 TUint CScreenDeviceHelper::BytesPerScanline() const
       
   568 	{
       
   569 	TInt linepitchInBytes = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
       
   570 	TInt ret = HAL::Get(ScreenNumber(),HALData::EDisplayOffsetBetweenLines,linepitchInBytes);
       
   571 	if (ret!=KErrNone)
       
   572 		{
       
   573 		return 0;
       
   574 		}
       
   575 	return linepitchInBytes ;
       
   576 	}
       
   577 /** Returns the address for the image data
       
   578  *  This method must not panic if it should fail!
       
   579  **/
       
   580 void* CScreenDeviceHelper::AddressFirstPixel() const
       
   581 	{
       
   582 	TInt bufferStartAddress = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
       
   583 	TInt ret = KErrNone;
       
   584 	if (iHasChunk)
       
   585 		{
       
   586 		// The "chunk" way to do this is to get the handle of the chunk, and then the base address of the 
       
   587 		// chunk itself. 
       
   588 		bufferStartAddress = (TInt)iChunk.Base();
       
   589 		}	 
       
   590 	else 
       
   591 		{
       
   592 		// Chunk not supported, use older HAL call to get the buffer address. 
       
   593 		ret = HAL::Get(ScreenNumber(),HALData::EDisplayMemoryAddress,bufferStartAddress);	
       
   594 		if (ret!=KErrNone)
       
   595 			{
       
   596 			return 0;
       
   597 			}
       
   598 		}
       
   599 	TInt bufferOffsetFirstPixel = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
       
   600 	ret = HAL::Get(ScreenNumber(),HALData::EDisplayOffsetToFirstPixel,bufferOffsetFirstPixel);
       
   601 	if (ret!=KErrNone)
       
   602 		{
       
   603 		return 0;
       
   604 		}
       
   605 	return (void*)(bufferStartAddress+bufferOffsetFirstPixel);
       
   606 	}
       
   607 
       
   608 /**
       
   609 Returns the current device width/height flip state of this surface, representing a +/-90 deg rotation.
       
   610 **/
       
   611 TBool	CScreenDeviceHelper::DeviceFlipped() const
       
   612 	{
       
   613 	return  (iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] & TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag) != 0;	//!=0 forces true --> 1
       
   614 	}
       
   615 
       
   616 
       
   617 /**
       
   618 Returns the current device orientation.
       
   619 */
       
   620 TDeviceOrientation CScreenDeviceHelper::DeviceOrientation() const
       
   621 	{
       
   622 	return iAssignedOrientation;
       
   623 	}
       
   624 /**	Returns an accurate scaling factor between twips and pixels in width.
       
   625 
       
   626  **/
       
   627 TInt	CScreenDeviceHelper::HorzTwipsPerThousandPixels(const TSize& aPixels)const
       
   628 	{
       
   629 	__ASSERT_DEBUG(aPixels.iWidth, Panic(EScreenDriverPanicInvalidSize));
       
   630 	
       
   631 	TInt width = 0;
       
   632 	TInt r = HAL::Get(ScreenNumber(), SecondIfFlipped(HAL::EDisplayXTwips,HAL::EDisplayYTwips), width);
       
   633 	__ASSERT_DEBUG(r==KErrNone && width!=0, Panic(EScreenDriverPanicInvalidHalValue));
       
   634    
       
   635 	return (width * 1000) / aPixels.iWidth;
       
   636 	}
       
   637 /**	Returns an accurate scaling factor between twips and pixels in height.
       
   638  **/
       
   639 TInt	CScreenDeviceHelper::VertTwipsPerThousandPixels(const TSize& aPixels)const
       
   640 	{
       
   641 	__ASSERT_DEBUG(aPixels.iHeight, Panic(EScreenDriverPanicInvalidSize));
       
   642 
       
   643 	TInt height = 0;
       
   644 	TInt r = HAL::Get(ScreenNumber(), SecondIfFlipped(HAL::EDisplayYTwips,HAL::EDisplayXTwips), height);
       
   645 	__ASSERT_DEBUG(r==KErrNone && height!=0, Panic(EScreenDriverPanicInvalidHalValue));
       
   646 
       
   647 	return (height * 1000) / aPixels.iHeight;
       
   648 	} 
       
   649 
       
   650