os/graphics/windowing/windowserverplugins/openwfc/src/elementwrapper.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // 
    15 //
    16 
    17 #include "openwfcpanics.h"
    18 #include "elementwrapper.h"
    19 #include <WF/wfc.h>
    20 #include <graphics/surfacetypes.h>
    21 #include <hal.h>
    22 
    23 CElementWrapper* CElementWrapper::NewL(COpenWfcWrapper& aCOpenWfcWrapper, CElementWrapper*& aCleanupPrevRef)
    24     {
    25     CElementWrapper* wrapper = new (ELeave) CElementWrapper(aCOpenWfcWrapper);
    26     CleanupStack::PushL(wrapper);
    27     wrapper->ConstructL(aCleanupPrevRef);
    28     CleanupStack::Pop(wrapper);
    29     return wrapper;
    30     }
    31 
    32 CElementWrapper::CElementWrapper(COpenWfcWrapper& aOpenWfcWrapper):
    33     iUpdateFlags(EUpdate_ALL_ATTRIBS),iOpenWfcWrapper(aOpenWfcWrapper),iGlobalAlpha(0xff),
    34     iFlipped(EFalse),iRotation(MWsElement::EElementAntiClockwise0)
    35     {
    36     }
    37 CElementWrapper::~CElementWrapper()
    38     {
    39     wfcDestroyElement(iOpenWfcWrapper.Device(),iElement);
    40 
    41     UnsetSurface(iSurfaceId);
    42     iUpdateFlags = EUpdate_None;
    43 
    44     if (iCleanupNext)
    45         {
    46         iCleanupNext->iCleanupPrevRef=iCleanupPrevRef;
    47         }
    48     *iCleanupPrevRef=iCleanupNext;
    49     }
    50 
    51 void CElementWrapper::ConstructL(CElementWrapper*& aCleanupPrevRef)
    52     {
    53     if (aCleanupPrevRef)
    54         {
    55         iCleanupNext=aCleanupPrevRef;
    56         iCleanupNext->iCleanupPrevRef=&iCleanupNext;
    57         }
    58     aCleanupPrevRef=this;
    59     iCleanupPrevRef=&aCleanupPrevRef;
    60 
    61     iElement=wfcCreateElement(iOpenWfcWrapper.Device(),iOpenWfcWrapper.OnScreenContext(),NULL);
    62     if (iElement==WFC_INVALID_HANDLE)
    63         {   //if context and device are good then only explanation is memory
    64         #ifdef _DEBUG
    65             WFCErrorCode wfcErr = 
    66         #endif
    67         wfcGetError(iOpenWfcWrapper.Device());
    68         OPENWFC_ASSERT_DEBUG(wfcErr==WFC_ERROR_OUT_OF_MEMORY,EPanicUnexpectedErrorElementConstruct);
    69         User::Leave(KErrNoMemory);
    70         }
    71     }
    72 
    73 TInt CElementWrapper::SetSourceRectangle(const TRect& aSrc)
    74     {
    75     if(iSurfaceId.IsNull())
    76         return KErrGeneral;
    77 
    78     //Check aSrc rect is within the bounds of the source image
    79     TInt32 width,height;
    80     HelpStreamGetHeader(&width,&height);
    81     if(aSrc.iTl.iX < 0 || aSrc.iTl.iY < 0 || aSrc.iBr.iX > width || aSrc.iBr.iY > height)
    82         {
    83         return KErrArgument;
    84         }
    85 
    86     iSourcRect = aSrc;
    87     iUpdateFlags |= EUpdate_SettingValid|EUpdate_SOURCE_RECTANGLE;
    88     iOpenWfcWrapper.SetCompositionModified();
    89     
    90     return KErrNone;
    91     }
    92 
    93 TInt CElementWrapper::GetSourceRectangle(TRect& aSrc)
    94     {
    95     if(iSurfaceId.IsNull())
    96         return KErrGeneral;
    97 
    98     if (iSourcRect.IsEmpty())
    99         {        
   100         //get true source rectangle from surface
   101         TInt32 width,height;
   102         HelpStreamGetHeader(&width,&height);
   103         aSrc.iTl.iX = 0;
   104         aSrc.iTl.iY = 0;
   105         aSrc.iBr.iX = width;
   106         aSrc.iBr.iY = height;
   107         }
   108     else
   109         {
   110         aSrc=iSourcRect;
   111         }
   112     
   113     return KErrNone;
   114     }
   115 
   116 TInt CElementWrapper::SetSourceFlipping(const TBool aFlip)
   117     {
   118     if(iSurfaceId.IsNull())
   119         return KErrGeneral;
   120 
   121     iFlipped = aFlip;
   122     iUpdateFlags |= EUpdate_SettingValid|EUpdate_SOURCE_FLIP;
   123     
   124     return KErrNone;
   125     }
   126 
   127 TBool CElementWrapper::SourceFlipping() const
   128     {
   129     if(iSurfaceId.IsNull())
   130         return EFalse; //default is not flipped
   131     
   132     return iFlipped;
   133     }
   134 
   135 TInt CElementWrapper::SetGlobalAlpha(const TInt aAlpha)
   136     {
   137     if (aAlpha!=iGlobalAlpha)
   138         {
   139         if ((aAlpha>=0xff)!=(iGlobalAlpha==0xff))
   140             {
   141             iUpdateFlags |= EUpdate_SettingValid|EUpdate_TRANSPARENCY_TYPES;
   142             }
   143         if (aAlpha < 0)
   144             {
   145             iGlobalAlpha = 0;
   146             }
   147         else
   148             {
   149             iGlobalAlpha = aAlpha > 0xff ? 0xff : aAlpha;
   150             }
   151         iUpdateFlags |= EUpdate_SettingValid|EUpdate_GLOBAL_ALPHA;
   152         }
   153     iOpenWfcWrapper.SetCompositionModified();
   154     
   155     return KErrNone;
   156     }
   157 
   158 void CElementWrapper::GlobalAlpha(TInt& aAlpha) const
   159     {
   160     aAlpha = iGlobalAlpha;
   161     }
   162 
   163 TInt CElementWrapper::SetDestinationRectangle(const TRect& aDest)
   164     {
   165     if(iSurfaceId.IsNull())
   166         return KErrGeneral;
   167 
   168     //Check aDest is not out of bounds
   169     if(aDest.iBr.iX < aDest.iTl.iX || aDest.iBr.iY < aDest.iTl.iY)
   170         {
   171         return KErrArgument;
   172         }
   173 
   174     TRect compositionDestRect;
   175     TRect lastCompositionDestRect;
   176     GetDestinationRectangle(lastCompositionDestRect);
   177     TInt err = KErrNone;
   178     //always do the translate
   179     err = iOpenWfcWrapper.DisplayPolicy()->MapCoordinates(EApplicationSpace, aDest, ECompositionSpace, compositionDestRect);
   180 
   181     if(compositionDestRect != lastCompositionDestRect)
   182         {
   183         iDestinationRect=aDest;
   184         iUpdateFlags |= EUpdate_SettingValid|EUpdate_DESTINATION_RECTANGLE;
   185 
   186         iOpenWfcWrapper.SetCompositionModified();
   187         }
   188     
   189     return err;
   190     }
   191 
   192 TInt CElementWrapper::GetDestinationRectangle(TRect& aDest) const
   193     {
   194     if(iSurfaceId.IsNull())
   195         return KErrGeneral;
   196 
   197     aDest=iDestinationRect;
   198     
   199     return KErrNone;
   200     }
   201 
   202 TInt CElementWrapper::SetDestinationClippingRect(const TRect& aDestClipRect)
   203 	{
   204 	if(iSurfaceId.IsNull())
   205         return KErrGeneral;
   206 
   207     TRect compositionDestClipRect;
   208     TRect lastCompositionDestClipRect;
   209     GetDestinationClippingRect(lastCompositionDestClipRect);
   210     TInt err = KErrNone;
   211     //always do the translate
   212     err = iOpenWfcWrapper.DisplayPolicy()->MapCoordinates(EApplicationSpace, aDestClipRect, ECompositionSpace, compositionDestClipRect);
   213     
   214     if(compositionDestClipRect != lastCompositionDestClipRect)
   215     	{
   216     	TRect destClipRect(aDestClipRect);
   217 		//Check if the destination clip rectangle is not empty
   218 		if (!destClipRect.IsEmpty())
   219 			{
   220 			//Calculate the intersection of the destination clipped rectangle
   221 			destClipRect.Intersection(iDestinationRect);
   222 			if (!destClipRect.IsEmpty())
   223 				{
   224 				// Check if the clipped rectangle is valid,it doesn't have coordinates
   225 				if (destClipRect.iTl.iX < 0 || destClipRect.iTl.iY < 0)
   226 					{
   227 					return KErrArgument;
   228 					}
   229 				}
   230 			}
   231 		if (iDestinationClippingRect != aDestClipRect)
   232 			{
   233 			iDestinationClippingRect = aDestClipRect;
   234 			iUpdateFlags |= EUpdate_SettingValid | EUpdate_DESTINATION_CLIP_RECTANGLE;
   235 
   236 			iOpenWfcWrapper.SetCompositionModified();
   237 			}
   238 		err = KErrNone;
   239 		}
   240 	return err;
   241 	}
   242 
   243 TInt CElementWrapper::GetDestinationClippingRect(TRect& aDestClipRect) const
   244     {
   245 	if(iSurfaceId.IsNull())
   246         return KErrGeneral;
   247 
   248     aDestClipRect = iDestinationClippingRect;
   249 
   250     return KErrNone;
   251     }
   252     
   253 
   254 /*
   255 Fast swap of two 32-bit TInt type integers.
   256 @param aA Argument one. 
   257 @param aB Argument two.
   258 */
   259 inline void SwapInt(TInt& aA, TInt& aB)
   260    {
   261    aA ^= aB;
   262    aB ^= aA;
   263    aA ^= aB;
   264    }
   265 
   266 /*
   267  Rectangle corner point enumeration.
   268  Consider TopLeft     point as 0
   269  Consider TopRight    point as 1
   270  Consider BottomRight point as 2
   271  Consider BottomLeft  point as 3
   272 */
   273 enum TRectangleCornerPoint
   274     {
   275     ETopLeft,
   276     ETopRight,
   277     EBottomRight,
   278     EBottomLeft
   279     };
   280 
   281 /**
   282  Get Bottom right corner of the rectangle. 
   283  @param aRect input rectangle.
   284  @return Bottom right corner point coordinates of rectangle.
   285  */
   286 inline TPoint BottomRight(const TRect& aRect)
   287     {
   288     return aRect.iBr;
   289     }
   290 
   291 /**
   292  Get Top left corner of the rectangle. 
   293  @param aRect input rectangle.
   294  @return Top left corner point coordinates of rectangle.
   295  */
   296 inline TPoint TopLeft(const TRect& aRect)
   297     {
   298     return aRect.iTl;
   299     }
   300 
   301 /**
   302  Get Top right corner of the rectangle. 
   303  @param aRect input rectangle.
   304  @return Top right corner point coordinates of rectangle.
   305  */
   306 inline TPoint TopRight(const TRect& aRect)
   307     {
   308     return TPoint(aRect.iBr.iX, aRect.iTl.iY);
   309     }
   310 
   311 /**
   312  Get Bottom left corner of the rectangle. 
   313  @param aRect input rectangle.
   314  @return Bottom left corner point coordinates of rectangle.
   315  */
   316 inline TPoint BottomLeft(const TRect& aRect)
   317     {
   318     return TPoint(aRect.iTl.iX, aRect.iBr.iY);
   319     }
   320 
   321 /*
   322  Make horizontal flip of the corner point.
   323  */
   324 inline TRectangleCornerPoint FlipRectangleCorner(TRectangleCornerPoint aSourceRectCorner)
   325     {
   326     return static_cast<TRectangleCornerPoint> (static_cast<TInt> (aSourceRectCorner ^ 0x00000003));
   327     }
   328 
   329 /*
   330  Make clockwise rotation of corner point. 
   331  */
   332 inline TRectangleCornerPoint RotateRectangleCorner(TRectangleCornerPoint aSourceRectCorner,const MWsElement::TElementRotation& aElementRotation)
   333     {
   334     return static_cast<TRectangleCornerPoint> ((static_cast<TInt> (aSourceRectCorner) + static_cast<TInt> (aElementRotation)) & 0x00000003);
   335     }
   336 
   337 /*
   338  Check if there is an inverted aspect ratio. 
   339  */
   340 inline TBool CheckInvertedAspectRatio(const MWsElement::TElementRotation& aElementRotation)
   341     {
   342     return  (aElementRotation & 0x00000001);
   343     }
   344 /**
   345  Compare the dedicated rectangle corner coordinates of two rectangles.
   346  @param aCorner rectangle corner point.
   347  @param aRect1 the first rectangle to compare.
   348  @param aRect2 the second rectangle to compare.
   349  @return ETrue if the checked corner coordinates are the same. 
   350  */
   351 TBool CheckTwoRectangleCorners(TRectangleCornerPoint aCorner,const TRect& aRect1,const TRect& aRect2)
   352     {
   353     aCorner = static_cast<TRectangleCornerPoint> (static_cast<TInt> (aCorner) & 0x00000003); // Normalize rectangle corner value
   354     switch (aCorner)
   355         {
   356         case ETopLeft:
   357             return (TopLeft(aRect1) == TopLeft(aRect2));
   358         case ETopRight:
   359             return (TopRight(aRect1) == TopRight(aRect2));
   360         case EBottomRight:
   361             return (BottomRight(aRect1) == BottomRight(aRect2));
   362         case EBottomLeft:
   363             return (BottomLeft(aRect1) == BottomLeft(aRect2));
   364         default:
   365             return EFalse;
   366         }
   367     }
   368 
   369 /**
   370  Calculate the new source rectangle extent when a window is clipped by it parent window. 
   371  Destination clipped rectangle should match to the source rectangle with taking into account 
   372  flip, scaling and rotation.
   373  @param aDestElementRect destination element rectangle without parent window clipping   
   374  @param aDestElementClippedRect destination element rectangle clipped by the parent window.
   375  @param aSrcOriginalElementRect  source element rectangle without any clipping changes.
   376  @param aElementFlip horizontal flip flag.
   377  @param aElementRotation target anti clockwise rotation factor.
   378  @return clipped source rectangle.
   379  */  
   380 TRect CElementWrapper::SetSourceDestRect(const TRect& aDestElementRect,const TRect& aDestElementClippedRect,const TRect& aSrcOriginalElementRect,const TBool& aElementFlip,const MWsElement::TElementRotation& aElementRotation) const
   381     {
   382 	if ((aSrcOriginalElementRect.Width() == 0) || (aSrcOriginalElementRect.Height() == 0))
   383 		{
   384 		// There are either width or height equal zero.
   385 		return TRect();
   386 		}
   387 
   388 	TRectangleCornerPoint sourceRectangleCorner = ETopLeft;
   389 	TRect destElementMovedClippedRect(aDestElementClippedRect);
   390 	destElementMovedClippedRect.Intersection(aDestElementRect);
   391 	TBool fullFlipRotationScale = EFalse;
   392 	// Compare four corner points of Destination moved and Destination moved clipped rectangles.
   393 	// Find the first equal corner coordinates for Destination moved and Destination moved clipped rectangles.
   394 	// It is the Fixed or non changeable point/corner of the source rectangle.
   395 	if (destElementMovedClippedRect.IsEmpty())
   396 		{
   397 		return TRect();
   398 		}
   399 	for (sourceRectangleCorner = ETopLeft; ((TInt) sourceRectangleCorner) <= ((TInt) EBottomLeft);)
   400 		{
   401 		if (CheckTwoRectangleCorners(sourceRectangleCorner, aDestElementRect, destElementMovedClippedRect))
   402 			{
   403 			break;
   404 			}
   405 		sourceRectangleCorner = static_cast<TRectangleCornerPoint> ((TInt) sourceRectangleCorner + 1);
   406 		}
   407 	// There are no equals coordinates, hence, it must be calculated with different  by different way
   408 	if ((TInt) sourceRectangleCorner > (TInt) EBottomLeft)
   409 		{
   410 		sourceRectangleCorner = ETopLeft;
   411 		fullFlipRotationScale = ETrue;
   412 		}
   413 
   414 	// Clockwise rotate of the detected Fixed point/corner.  
   415 	sourceRectangleCorner = RotateRectangleCorner(sourceRectangleCorner, aElementRotation);
   416 
   417 	// If flip flag set, then make horizontal flip of the Fixed point.
   418 	if (aElementFlip)
   419 		{
   420 		sourceRectangleCorner = FlipRectangleCorner(sourceRectangleCorner);
   421 		}
   422 
   423 	// Make scale calculation for the source clipping
   424 	TInt dX = 0;
   425 	TInt dY = 0;
   426 	if (fullFlipRotationScale)
   427 		{
   428 		dX = ((aDestElementRect.iTl.iX - aDestElementClippedRect.iTl.iX) * aSrcOriginalElementRect.Width()) / aDestElementRect.Width();
   429 		dY = ((aDestElementRect.iTl.iY - aDestElementClippedRect.iTl.iY) * aSrcOriginalElementRect.Height()) / aDestElementRect.Height();
   430 		}
   431 	TInt clipSrcWidth = (destElementMovedClippedRect.Width() * aSrcOriginalElementRect.Width()) / aDestElementRect.Width();
   432 	TInt clipSrcHeight = (destElementMovedClippedRect.Height() * aSrcOriginalElementRect.Height()) / aDestElementRect.Height();
   433 	TRect resultSourceRect = aSrcOriginalElementRect;
   434 
   435 	// Swap the clipping width and height if the target was rotated on 90 or 270 degrees.
   436 	if (CheckInvertedAspectRatio(aElementRotation))
   437 		{
   438 		SwapInt(clipSrcWidth, clipSrcHeight);
   439 		SwapInt(dX, dY);
   440 		}
   441 
   442 	// Assuming that coordinates of the source Fixed corner/point was not changed due to clipping,
   443 	// calculate coordinates of an opposite point to the Fixed corner/point.
   444 	// This point must be differ from original source  for providing proper clipping visual result.
   445 	switch (sourceRectangleCorner)
   446 		{
   447 		case ETopLeft:
   448 			{
   449 			// If TopRight of aDestElementRect is not the same as TopRight of aDestElementClippedRect 
   450 			if (!CheckTwoRectangleCorners(ETopRight, aDestElementRect, destElementMovedClippedRect))
   451 				{// calculate point ETopRight
   452 				resultSourceRect.iBr.iX = resultSourceRect.iTl.iX + clipSrcWidth;
   453 				}
   454 			// If BottomLeft of aDestElementRect is not the same as BottomLeft of aDestElementClippedRect
   455 			if (!CheckTwoRectangleCorners(EBottomLeft, aDestElementRect, destElementMovedClippedRect))
   456 				{// calculate point EBottomLeft
   457 				resultSourceRect.iBr.iY = resultSourceRect.iTl.iY + clipSrcHeight;
   458 				}
   459 			if (fullFlipRotationScale)
   460 				{
   461 				resultSourceRect.iTl.iX += dX;
   462 				resultSourceRect.iTl.iY += dY;
   463 				}
   464 			}
   465 			break;
   466 		case ETopRight:
   467 			{
   468 			// if TopLeft of aDestElementRect is not the same as TopLeft of aDestElementClippedRect
   469 			if (!CheckTwoRectangleCorners(ETopLeft, aDestElementRect, destElementMovedClippedRect))
   470 				{// calculate point ETopLeft
   471 				resultSourceRect.iTl.iX = resultSourceRect.iBr.iX - clipSrcWidth;
   472 				}
   473 			// if BottomRight of aDestElementRect is not the same as BottomRight of aDestElementClippedRect
   474 			if (!CheckTwoRectangleCorners(EBottomRight, aDestElementRect, destElementMovedClippedRect))
   475 				{// calculate point EBottomRight
   476 				resultSourceRect.iBr.iY = resultSourceRect.iTl.iY + clipSrcHeight;
   477 				}
   478 			if (fullFlipRotationScale)
   479 				{
   480 				resultSourceRect.iBr.iX -= dX;
   481 				resultSourceRect.iTl.iY += dY;
   482 				}
   483 			}
   484 			break;
   485 		case EBottomRight:
   486 			{
   487 			// if BottomLeft of aDestElementRect is not the same as BottomLeft of aDestElementClippedRect
   488 			if (!CheckTwoRectangleCorners(EBottomLeft, aDestElementRect, destElementMovedClippedRect))
   489 				{// calculate point EBottomLeft
   490 				resultSourceRect.iTl.iX = resultSourceRect.iBr.iX - clipSrcWidth;
   491 				}
   492 			// if TopRight of aDestElementRect is not the same as TopRight of aDestElementClippedRect
   493 			if (!CheckTwoRectangleCorners(ETopRight, aDestElementRect, destElementMovedClippedRect))
   494 				{// calculate point ETopRight
   495 				resultSourceRect.iTl.iY = resultSourceRect.iBr.iY - clipSrcHeight;
   496 				}
   497 			if (fullFlipRotationScale)
   498 				{
   499 				resultSourceRect.iBr.iX -= dX;
   500 				resultSourceRect.iBr.iY -= dY;
   501 				}
   502 			}
   503 			break;
   504 		case EBottomLeft:
   505 			{
   506 			// if BottomRight of aDestElementRect is not the same as BottomRight of aDestElementClippedRect don't change width
   507 			if (CheckTwoRectangleCorners(EBottomRight, aDestElementRect, destElementMovedClippedRect))
   508 				{// calculate point EBottomRight
   509 				resultSourceRect.iBr.iX = resultSourceRect.iTl.iX + clipSrcWidth;
   510 				}
   511 			// if TopLeft of aDestElementRect is not the same as TopLeft of aDestElementClippedRect
   512 			if (CheckTwoRectangleCorners(ETopLeft, aDestElementRect, destElementMovedClippedRect))
   513 				{// calculate point ETopLeft
   514 				resultSourceRect.iTl.iY = resultSourceRect.iBr.iY - clipSrcHeight;
   515 				}
   516 			if (fullFlipRotationScale)
   517 				{
   518 				resultSourceRect.iTl.iX += dX;
   519 				resultSourceRect.iBr.iY -= dY;
   520 				}
   521 			}
   522 			break;
   523 		}
   524 	return resultSourceRect;
   525 	}
   526 
   527 
   528 
   529 TInt CElementWrapper::SetSourceRotation(const TElementRotation aElementRotation)
   530     {
   531     if(iSurfaceId.IsNull())
   532         return KErrGeneral;
   533     
   534     if(aElementRotation < 0 || aElementRotation > 3)
   535         return KErrArgument;
   536     
   537     iRotation = aElementRotation;
   538     iUpdateFlags |= EUpdate_SettingValid|EUpdate_SOURCE_ROTATION;
   539 
   540     iOpenWfcWrapper.SetCompositionModified();
   541     
   542     return KErrNone;
   543     }
   544 
   545 MWsElement::TElementRotation CElementWrapper::SourceRotation() const
   546     {
   547     if(iSurfaceId.IsNull())
   548         return EElementAntiClockwise0; //default rotation
   549 
   550     return iRotation;
   551     }
   552 
   553 TInt CElementWrapper::SetTargetRendererFlags(const TUint32& aTargetRendererFlags)
   554     {
   555     iTargetRendererFlags = aTargetRendererFlags;
   556     if (iTargetRendererFlags & EElementTransparencyGlobalAlpha)
   557         {
   558         iUpdateFlags |= EUpdate_SettingValid|EUpdate_GLOBAL_ALPHA;
   559         }
   560     
   561     if (iTargetRendererFlags & EElementTransparencySource)
   562         {
   563         iUpdateFlags |= EUpdate_SettingValid|EUpdate_TRANSPARENCY_TYPES;
   564         }
   565     
   566     return KErrNone;
   567     }
   568 
   569 TInt CElementWrapper::SetRenderStageFlags(const TUint32& aRenderStageFlags)
   570     {
   571     iRenderStageFlags = aRenderStageFlags;
   572     
   573     return KErrNone;
   574     }
   575 
   576 void CElementWrapper::GetTargetRendererFlags(TUint32& aTargetRendererFlags) const
   577     {
   578     aTargetRendererFlags = iTargetRendererFlags;
   579     }
   580 
   581 void CElementWrapper::GetRenderStageFlags(TUint32& aRenderStageFlags) const
   582     {
   583     aRenderStageFlags = iRenderStageFlags;
   584     }
   585 
   586 MWsElement* CElementWrapper::ElementAbove()
   587     {
   588     //Check this element has not already been reequsted to be removed
   589     if (iUpdateFlags&EUpdate_Remove)
   590         {
   591         return NULL;
   592         }
   593     else
   594         {
   595         return iElementAbove;
   596         }
   597     }
   598 
   599 MWsElement* CElementWrapper::ElementBelow()
   600     {
   601     //Check this element has not already been reequsted to be removed
   602     if (iUpdateFlags&EUpdate_Remove)
   603         {
   604         return NULL;
   605         }
   606     else
   607         {
   608         return iElementBelow;
   609         }
   610     }
   611 
   612 TInt CElementWrapper::ConnectSurface(const TSurfaceId& aSurface)
   613     {
   614     TInt err = KErrNone;
   615      if (aSurface!=iSurfaceId)
   616         {
   617         if (!aSurface.IsNull())
   618             {
   619             if(!iOpenWfcWrapper.IncEltRefRegSource(aSurface))
   620                 {
   621                 return KErrNotFound;
   622                 }
   623             else
   624                 {
   625                 RSurfaceManager::TInfoBuf buff;
   626                 err = err = SurfaceInfo(aSurface, buff);
   627                 if (err != KErrNone)
   628                     {
   629                     return iOpenWfcWrapper.DecEltRefRegSource(aSurface);
   630                     }
   631                 else
   632                     {
   633                     iSurfaceSize=buff().iSize;
   634                     }
   635                 }
   636             }
   637         else
   638             {
   639             iSurfaceSize.SetSize(0,0);
   640             }
   641         UnsetSurface(iSurfaceId);
   642         iSurfaceId=aSurface;
   643         iUpdateFlags |= EUpdate_SettingValid|EUpdate_SOURCE;
   644         if (iSourcRect.IsEmpty())
   645             {
   646             iUpdateFlags |= EUpdate_SettingValid|EUpdate_SOURCE_RECTANGLE;
   647             }
   648         }
   649     else
   650         {   //Note this code is simply here to return the error!
   651         if (!iSurfaceId.IsNull())
   652             {
   653             if (iOpenWfcWrapper.IncEltRefRegSource(iSurfaceId))
   654                 {
   655                 iOpenWfcWrapper.DecEltRefRegSource(iSurfaceId);
   656                 }
   657             else
   658                 {
   659                 return KErrNotFound;
   660                 }
   661             }
   662         }
   663     
   664     iOpenWfcWrapper.SetCompositionModified();
   665     
   666     return err;
   667     }
   668 
   669 const TSurfaceId& CElementWrapper::ConnectedSurface() const
   670     {
   671     return iSurfaceId;
   672     }
   673 
   674 /** 
   675  * Sets the element source to match the surface ID and optionally locks the reference count until next composition.
   676  **/
   677 void CElementWrapper::SetEltSourceComposed()
   678     {
   679     iUpdateFlags |= EUpdate_SceneCommited;
   680     }
   681 
   682 /** 
   683  * Sets the element source to match the surface ID and optionally locks the reference count until next composition.
   684  **/
   685 void CElementWrapper::SetEltSource(WFCElement aElement)const
   686     {
   687     WFCSource source = WFC_INVALID_HANDLE;
   688     if (!iSurfaceId.IsNull())
   689         {
   690         source=iOpenWfcWrapper.IncEltRefRegSource(iSurfaceId);
   691         if(source)
   692             {
   693             TInt remains=iOpenWfcWrapper.DecEltRefRegSource(iSurfaceId);
   694             OPENWFC_ASSERT_DEBUG(remains>0,EPanicWfcNoStreamSurface);
   695             }
   696         }
   697     wfcSetElementAttribi(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_SOURCE,source);
   698     }
   699 
   700 /** 
   701  * Internal method releases the previous registered surface, and clears the caller's member var.
   702  * @return true if any resources released
   703  **/
   704 TBool CElementWrapper::UnsetSurface(TSurfaceId& aSurface)
   705     {
   706     if (!aSurface.IsNull())
   707         {
   708         TInt err = iOpenWfcWrapper.DecEltRefRegSource(aSurface);
   709         OPENWFC_ASSERT_DEBUG(err >= 0,EPanicWfcSourceLookupOnElementRemoval);
   710         aSurface = aSurface.CreateNullId();
   711         return (err == KErrNone); //>0 indicates object count non-zero
   712         }
   713     return EFalse;
   714     }
   715 
   716 void CElementWrapper::SetEltTransparencyTypes(WFCElement aElement)const
   717     {
   718     TInt transType = WFC_TRANSPARENCY_NONE;
   719     if (iTargetRendererFlags & EElementTransparencySource)
   720         {
   721         transType |= WFC_TRANSPARENCY_SOURCE;
   722         }
   723     if (iTargetRendererFlags & EElementTransparencyGlobalAlpha)
   724         {
   725         transType |= WFC_TRANSPARENCY_ELEMENT_GLOBAL_ALPHA;
   726         }
   727     wfcSetElementAttribi(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_TRANSPARENCY_TYPES,transType);
   728     }
   729 
   730 void CElementWrapper::HelpStreamGetHeader(khronos_int32_t* aWidth, khronos_int32_t* aHeight)const
   731     {
   732     if (aWidth)
   733         {
   734         *aWidth=iSurfaceSize.iWidth;
   735         }
   736     if (aHeight)
   737         {
   738         *aHeight=iSurfaceSize.iHeight;
   739         }
   740     }
   741 
   742 /**
   743  *  Maps the source rectangle to fp values matching the region and destination rectangle data over a element object.
   744  *  This is when the source rectangle changes.
   745  *  Only repositions existing elements
   746  **/
   747 void CElementWrapper::SetEltSourceRectangle(WFCElement aElement)
   748     {
   749     TRect srcRect;
   750     GetSourceRectangle(srcRect);
   751     if (!iDestinationClippingRect.IsEmpty())
   752     	{
   753     	 TRect destinationRect=iDestinationRect;
   754     	 destinationRect.Intersection(iDestinationClippingRect);
   755     	 if(!destinationRect.IsEmpty())
   756     		 {
   757     		 srcRect = SetSourceDestRect(iDestinationRect,destinationRect,srcRect,iFlipped,iRotation);
   758     		 }
   759     	}
   760     float rect[4]={srcRect.iTl.iX,srcRect.iTl.iY,srcRect.Width(),srcRect.Height()};
   761     wfcSetElementAttribfv(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_SOURCE_RECTANGLE,4,rect);
   762     }
   763 
   764 void CElementWrapper::SetEltSourceFlip(WFCElement aElement)const
   765     {
   766     wfcSetElementAttribi(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_SOURCE_FLIP, iFlipped);
   767     }
   768 
   769 /**
   770  *  Maps the region and destination rectangle data into a element object
   771  *  taking into account the source rectangle mapping and region data
   772  *  @return KErrNone or KErrMemory
   773  **/
   774 void CElementWrapper::SetEltDestinationRectangle(WFCElement aElement)const
   775     {
   776     TRect destinationRect=iDestinationRect;
   777     if (!iDestinationClippingRect.IsEmpty())
   778     	{
   779     	destinationRect.Intersection(iDestinationClippingRect);
   780     	}
   781     float destRect[4]={destinationRect.iTl.iX,destinationRect.iTl.iY,destinationRect.Width()<0?0:destinationRect.Width(),destinationRect.Height()<0?0:destinationRect.Height()};
   782     wfcSetElementAttribfv(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_DESTINATION_RECTANGLE,4,destRect);
   783 
   784     LILOG(("### EXIT SetEltDestinationRectangle()"));
   785     }
   786 
   787 /**
   788  *  Maps the region and destination rectangle data into a element object.
   789  *  taking in to account the source rectangle mapping and region data
   790  *  @param aOffset  an offset ADDED to every destination rectangle
   791  *  @return KErrNone or KErrMemory
   792  **/
   793 void CElementWrapper::SetEltDestinationRectangle(WFCElement aElement, const TPoint& aOffset)const
   794     {
   795     TRect destinationRect=iDestinationRect;
   796     if (!iDestinationClippingRect.IsEmpty())
   797         {
   798         destinationRect.Intersection(iDestinationClippingRect);
   799         }
   800     float rect[4]={destinationRect.iTl.iX+aOffset.iX,destinationRect.iTl.iY+aOffset.iY,destinationRect.Width(),destinationRect.Height()};
   801     wfcSetElementAttribfv(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_DESTINATION_RECTANGLE,4,rect);
   802     }
   803 
   804 void CElementWrapper::RemoveAfter(CElementWrapper** apElementBelow)
   805     {
   806     iUpdateFlags&=~(EUpdate_Insert|EUpdate_Remove);
   807     if(apElementBelow)
   808         {
   809         *apElementBelow = iElementAbove;
   810         if (iElementAbove)
   811             {
   812             iElementAbove->iElementBelow = iElementBelow;
   813             }
   814         }
   815     iElementBelow = NULL;
   816     iElementAbove = NULL;
   817     }
   818 
   819 void CElementWrapper::InsertAfter(CElementWrapper*& aRefElementBelow, CElementWrapper* aElementBelow, TOwfUpdates aUpdateFlag)
   820     {
   821     OPENWFC_ASSERT_DEBUG(aUpdateFlag&(EUpdate_Insert|aUpdateFlag&EUpdate_Remove|aUpdateFlag&EUpdate_Destroy), EPanicUnexpectedErrorElementScene);
   822     iUpdateFlags |= EUpdate_SettingValid|aUpdateFlag;
   823     iElementAbove = aRefElementBelow;
   824     iElementBelow = aElementBelow;
   825     aRefElementBelow = this;
   826     if (iElementAbove)
   827         {
   828         iElementAbove->iElementBelow = this;
   829         }
   830     }
   831 
   832 /* Returns a pointer referencing this object from below.
   833  * @return the pointer or null if there is no "below" object
   834  */
   835 CElementWrapper** CElementWrapper::RefsMyElementBelow()
   836     {
   837     if (iElementBelow)
   838         {
   839         return &iElementBelow->iElementAbove;
   840         }
   841 
   842     return NULL;
   843     }
   844 
   845 CElementWrapper*& CElementWrapper::MyElementAbove()
   846     {
   847     return iElementAbove;
   848     }
   849 
   850 TInt CElementWrapper::WfcRotation(MWsElement::TElementRotation aRotation)
   851     {
   852     switch (aRotation)
   853         {
   854     case EElementAntiClockwise0:
   855         return WFC_ROTATION_0;
   856     case EElementAntiClockwise90:
   857         return WFC_ROTATION_270;
   858     case EElementAntiClockwise180:
   859         return WFC_ROTATION_180;
   860     default: // EElementAntiClockwise270
   861         return WFC_ROTATION_90;
   862         }
   863     }
   864 
   865 TBool CElementWrapper::IsNewElementLegal()const
   866     {
   867     //OWF SI will fail if certain illegal element attributes are passed to it.
   868     //Various members must be non-zero:
   869         //destination rectangle
   870         //source
   871         //global alpha
   872     if (iDestinationRect.IsEmpty() || iSurfaceId.IsNull()||iGlobalAlpha==0)
   873         {
   874         return EFalse;
   875         }
   876     //If the source rectangle is set it must be inside the surface size
   877     if (!iSourcRect.IsEmpty())
   878         {
   879         if (iSourcRect.iTl.iX<0 || iSourcRect.iTl.iY<0)
   880             {
   881             return EFalse;
   882             }
   883         TInt32 width;
   884         TInt32 height;
   885         HelpStreamGetHeader(&width,&height);
   886         if (iSourcRect.iBr.iX>width || iSourcRect.iBr.iY>height)
   887             {
   888             return EFalse;
   889             }
   890         }
   891     //If mask is defined and enabled, Mask size must match destination rectangle size
   892         //masks are currently not implemented
   893     //If mask is enabled then source alpha must not be enabled
   894         //masks are currently not implemented
   895     return ETrue;
   896     }
   897 /** 
   898  * Flushes any flagged scene or attribute changes into the element objects
   899  * @return  EFalse if no flushing occurred - for any reason
   900  **/
   901 TBool CElementWrapper::FlushSceneChanges()
   902     {
   903     TInt updateFlags=iUpdateFlags;
   904     if  ((updateFlags&EUpdate_AttributesIllegal) && !(updateFlags&EUpdate_SettingValid))
   905         {
   906         return EFalse;
   907         }
   908     
   909     if (updateFlags==EUpdate_None)
   910         {
   911         return EFalse;
   912         }
   913 
   914     if (updateFlags&(EUpdate_Remove|EUpdate_Destroy) && (updateFlags&EUpdate_SceneCommited))
   915         {
   916         wfcRemoveElement(iOpenWfcWrapper.Device(),iElement);
   917         }
   918     
   919     if (updateFlags&EUpdate_Destroy)
   920         {
   921         return EFalse;
   922         }
   923     
   924     if (updateFlags&(EUpdate_Remove|EUpdate_Destroy))
   925         {
   926         iUpdateFlags&=~(EUpdate_Insert|EUpdate_Remove|EUpdate_SceneCommited);
   927         return EFalse;
   928         }
   929     
   930     TBool isElementLegal=IsNewElementLegal();
   931     if (!isElementLegal)
   932         {   //If the element would not be legal then it must not be inserted
   933             //It may even need to be removed.
   934         if (updateFlags&EUpdate_SceneCommited)
   935             {   //it is in the scene, remove it
   936             wfcRemoveElement(iOpenWfcWrapper.Device(),iElement);
   937             updateFlags &= ~EUpdate_SceneCommited;
   938             }
   939 
   940         //Re-flag the update but also set a flag
   941         //so that we don't bother to check legality again until another attribute change.
   942         updateFlags&=~EUpdate_SettingValid;
   943         updateFlags|=EUpdate_AttributesIllegal;
   944         iUpdateFlags=updateFlags;
   945 
   946         LILOG(("### EXIT CElementWrapper::FlushSceneChanges() FALSE"));
   947         return EFalse;
   948         }
   949 
   950     WFCElement elementBelow=WFC_INVALID_HANDLE;
   951     if ((updateFlags&(EUpdate_Insert|EUpdate_AttributesIllegal)))
   952         {
   953         if (CElementWrapper* elementWrapperBelow=iElementBelow)
   954             {
   955             while (elementWrapperBelow && elementWrapperBelow->iUpdateFlags&EUpdate_AttributesIllegal)
   956                 {
   957                 elementWrapperBelow=elementWrapperBelow->iElementBelow;
   958                 }
   959             if (elementWrapperBelow)
   960                 {
   961                 elementBelow=elementWrapperBelow->iElement;
   962                 }
   963             }
   964         }
   965     
   966     iUpdateFlags = EUpdate_SceneCommited;
   967     
   968     if ((updateFlags&~EUpdate_Remove))
   969         {
   970         FlushAttributeChanges(iElement, updateFlags);
   971         if (updateFlags&(EUpdate_Insert|EUpdate_AttributesIllegal))
   972             {
   973             wfcInsertElement(iOpenWfcWrapper.Device(),iElement,elementBelow);
   974             }
   975         }
   976 
   977     LILOG(("### EXIT CElementWrapper::FlushSceneChanges() FALSE"));
   978     return ETrue;
   979     }
   980 
   981 void CElementWrapper::FlushAttributeChanges(WFCElement aElement, TInt aUpdateFlags)
   982     {
   983     LILOG(("### ENTER FlushAttributeChanges() aStart(%d), aPastMax(%d), uFl(0x%x)", aStart, aPastMax, aUpdateFlags));
   984 
   985     //At present all attribute changes are flushed immediately... assert that behaviour.
   986     if (aUpdateFlags&EUpdate_SOURCE_GEOMETRY_SET)
   987         {
   988         SetEltSourceRectangle(aElement);
   989         }
   990     if (aUpdateFlags&(EUpdate_SOURCE|EUpdate_SettingValid))
   991         {
   992         SetEltSource(aElement);
   993         }
   994     if (aUpdateFlags&EUpdate_SOURCE_FLIP)
   995         {
   996         SetEltSourceFlip(aElement);
   997         }
   998     if (aUpdateFlags&EUpdate_SOURCE_ROTATION)
   999         {
  1000         TInt wfcRot=WfcRotation(iRotation);
  1001         wfcSetElementAttribi(iOpenWfcWrapper.Device(),iElement,WFC_ELEMENT_SOURCE_ROTATION,wfcRot);
  1002         }
  1003     if (aUpdateFlags&EUpdate_TRANSPARENCY_TYPES)
  1004         {
  1005         SetEltTransparencyTypes(aElement);
  1006         }
  1007     if (aUpdateFlags&EUpdate_GLOBAL_ALPHA)
  1008         {
  1009         wfcSetElementAttribi(iOpenWfcWrapper.Device(),aElement,WFC_ELEMENT_GLOBAL_ALPHA,iGlobalAlpha);
  1010         }
  1011     if (aUpdateFlags&EUpdate_DESTINATION_RECTANGLE)
  1012         {
  1013         SetEltDestinationRectangle(aElement);
  1014         }
  1015     LILOG(("### EXIT FlushAttributeChanges()"));
  1016     }
  1017 
  1018 TInt CElementWrapper::ReplicateElements(WFCContext aContext, WFCElement& aPreviousTargetElement,const TPoint& aOffset)
  1019     {
  1020     if (aContext == WFC_INVALID_HANDLE)
  1021         {
  1022         return KErrArgument;
  1023         }
  1024     
  1025     if (!IsNewElementLegal())
  1026         {
  1027         return KErrNone;
  1028         }
  1029 
  1030     WFCDevice device = iOpenWfcWrapper.Device();
  1031     WFCContext onScreenContext = iOpenWfcWrapper.OnScreenContext();
  1032     // clean the existing system errors and look for new ones
  1033     wfcGetError(device);
  1034     WFCSource targetImageSource = wfcCreateSourceFromStream(device, aContext, reinterpret_cast<WFCNativeStreamType>(&iSurfaceId), NULL);
  1035     if (targetImageSource == WFC_INVALID_HANDLE)
  1036         {
  1037         return COpenWfcWrapper::TranslateOpenWfcError(wfcGetError(device));
  1038         }
  1039      
  1040     WFCElement targetElement = WFC_INVALID_HANDLE;
  1041 
  1042     // the elements are created but we don't get hold of them for longer than we need
  1043     // all elements created now are to be destroyed when composition is completed
  1044     targetElement = wfcCreateElement(device, aContext, NULL);
  1045     if (targetElement == WFC_INVALID_HANDLE)
  1046         {
  1047         return COpenWfcWrapper::TranslateOpenWfcError(wfcGetError(device));
  1048         }
  1049 
  1050     // we can just flush the attributes to the new elements because the off-screen context attributes
  1051     // share the same device with the on-screen context. If this changes make device a parameter!
  1052     wfcSetElementAttribi(device,targetElement,WFC_ELEMENT_SOURCE,targetImageSource);
  1053     FlushAttributeChanges(targetElement, (EUpdate_ALL_ATTRIBS&~(EUpdate_SOURCE|EUpdate_DESTINATION_RECTANGLE)));
  1054     SetEltDestinationRectangle(targetElement, aOffset);
  1055     wfcInsertElement(iOpenWfcWrapper.Device(),targetElement,aPreviousTargetElement);
  1056     aPreviousTargetElement = targetElement;
  1057 
  1058     return COpenWfcWrapper::TranslateOpenWfcError(wfcGetError(device));
  1059     }
  1060 
  1061 TInt CElementWrapper::SurfaceInfo(const TSurfaceId& aSurface, RSurfaceManager::TInfoBuf& aInfo)
  1062     {
  1063     TInt err = KErrNone;
  1064     switch(aSurface.Type())
  1065         {
  1066         case TSurfaceTypes::ESurfaceManagerSurface:
  1067             {
  1068             err = Owner().SurfaceManager().SurfaceInfo(aSurface, aInfo);                   
  1069             break;
  1070             }
  1071         case TSurfaceId::EScreenSurface:      
  1072             {
  1073             TInt screenId = aSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
  1074             TInt width = 0;
  1075             err = HAL::Get(screenId, HALData::EDisplayXPixels, width);
  1076             if (err != KErrNone)
  1077                 {
  1078                 iOpenWfcWrapper.DecEltRefRegSource(aSurface);
  1079                 return err;
  1080                 }
  1081             
  1082             TInt height = 0;
  1083             err = HAL::Get(screenId, HALData::EDisplayYPixels, height);
  1084             if (err != KErrNone)
  1085                 {
  1086                 iOpenWfcWrapper.DecEltRefRegSource(aSurface);
  1087                 return err;
  1088                 }
  1089             
  1090             aInfo().iSize = TSize(width, height);      
  1091             
  1092 #ifdef  SYMBIAN_ROTATION_MODE_CHANGES
  1093             TInt displayMode = aSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
  1094 #else
  1095             TInt displayMode = 0;
  1096             err = HAL::Get(screenId, HALData::EDisplayMode, displayMode);
  1097             if (err != KErrNone)
  1098                 {
  1099                 iOpenWfcWrapper.DecEltRefRegSource(aSurface);
  1100                 return err;
  1101                 }                       
  1102 #endif                      
  1103 
  1104 #if defined(SYMBIAN_ROTATION_MODE_CHANGES)
  1105             if (displayMode & TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag) // 90 | 270 degree rotation
  1106                 {
  1107                 // Swap dimensions and recalculate stride. Assume no padding for now.
  1108                 aInfo().iSize.iWidth = height;
  1109                 aInfo().iSize.iHeight = width;
  1110                 //"vertical" stride has already been fetched
  1111                 }
  1112 #elif defined(SYMBIAN_ROTATION_CHANGES)
  1113             if (aSurface.iInternal[1] & (2 | 8))    // 90 | 270 degree rotation
  1114                 {
  1115                 // Swap dimensions and recalculate stride. Assume no padding for now.
  1116                 aInfo().iSize.iWidth = height;
  1117                 aInfo().iSize.iHeight = width;
  1118                 }
  1119 #endif                          
  1120             
  1121             break;
  1122             }
  1123         default:
  1124             err = KErrNotSupported;
  1125         }    
  1126     
  1127     return err;
  1128     }