mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp
changeset 0 b8ed18f6c07b
child 4 9d4397b300d1
equal deleted inserted replaced
-1:000000000000 0:b8ed18f6c07b
       
     1 // Copyright (c) 2002-2010 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 "mediaclientvideodisplaybody.h"
       
    17 #include "mediaclientvideotrace.h"
       
    18 #include "mediaclientpolicyserverclient.h"
       
    19 #include <surfaceeventhandler.h>
       
    20 #include <mmf/plugin/mmfmediaclientextdisplayinterface.hrh>
       
    21 #include <e32cmn.h>
       
    22 #include <ecom/ecom.h>
       
    23 #include <centralrepository.h>
       
    24 
       
    25 const TUid KCRUidTvoutSettings = {0x1020730B};
       
    26 const TUint32 KSettingsTvAspectRatio = 0x00000001;
       
    27 
       
    28 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
    29 // make sure that off screen is bottom right and not top left. This makes it more efficient for GCE backend
       
    30 // to render
       
    31 const TInt KHiddenExtentA = 2000; // rect Ax and Ay co-ordinate used to set extent off screen
       
    32 const TInt KHiddenExtentB = 2001; // rect Bx and By co-ordinate used to set extent off screen
       
    33 #endif
       
    34 
       
    35 CMediaClientVideoDisplayBody* CMediaClientVideoDisplayBody::NewL(TInt aDisplayId, TBool aExtDisplaySwitchingControl)
       
    36 	{
       
    37 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL +++");
       
    38     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aDisplayId %d", aDisplayId);
       
    39     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aExtDisplaySwitchingControl %d", aExtDisplaySwitchingControl);
       
    40     
       
    41     CMediaClientVideoDisplayBody* self = new (ELeave) CMediaClientVideoDisplayBody(aDisplayId);
       
    42 	CleanupStack::PushL(self);
       
    43 	self->ConstructL(aExtDisplaySwitchingControl);
       
    44 	CleanupStack::Pop(self);
       
    45 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL ---");
       
    46 	return self;
       
    47 	}
       
    48 
       
    49 CMediaClientVideoDisplayBody* CMediaClientVideoDisplayBody::NewL(TInt aDisplayId, const TSurfaceId& aSurfaceId,
       
    50 		const TRect& aCropRect, TVideoAspectRatio aAspectRatio, TBool aExtDisplaySwitchingControl)
       
    51 	{
       
    52 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL +++");
       
    53 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aDisplayId %d", aDisplayId);
       
    54     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::NewL - aSurfaceId %08x:%08x:%08x:%08x", aSurfaceId.iInternal[3], aSurfaceId.iInternal[2], aSurfaceId.iInternal[1], aSurfaceId.iInternal[0]);
       
    55     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::NewL - aCropRect %d,%d - %d,%d", aCropRect.iTl.iX, aCropRect.iTl.iY, aCropRect.iBr.iX, aCropRect.iBr.iY);
       
    56     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::NewL - aAspectRatio %d/%d", aAspectRatio.iNumerator, aAspectRatio.iDenominator);
       
    57     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aExtDisplaySwitchingControl %d", aExtDisplaySwitchingControl);
       
    58 
       
    59 	if(aSurfaceId.IsNull())
       
    60 		{
       
    61 		User::Leave(KErrArgument);
       
    62 		}
       
    63 	CMediaClientVideoDisplayBody* self = new(ELeave) CMediaClientVideoDisplayBody(aDisplayId, aSurfaceId, aCropRect, aAspectRatio);
       
    64 	CleanupStack::PushL(self);
       
    65 	self->ConstructL(aExtDisplaySwitchingControl);
       
    66 	CleanupStack::Pop();
       
    67 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL ---");
       
    68 	return self;
       
    69 	}
       
    70 
       
    71 void CMediaClientVideoDisplayBody::ConstructL(TBool aExtDisplaySwitchingControl)
       
    72 	{
       
    73 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL +++");
       
    74 
       
    75 	SetWindowArrayPtr2Client();
       
    76 
       
    77 	// External display switching and wserv events are only possible if there is
       
    78 	// an active scheduler in client thread
       
    79 	if(CActiveScheduler::Current())
       
    80 	    {
       
    81         CreateExtDisplayPluginL();
       
    82         iWsEventObserver = CMediaClientWsEventObserver::NewL(*this);
       
    83 
       
    84         iServerClient = CMediaClientPolicyServerClient::NewL();
       
    85         if(iServerClient->Connect() != KErrNone)
       
    86             {
       
    87             delete iServerClient;
       
    88             iServerClient = NULL;
       
    89             }
       
    90         
       
    91         if(IsSurfaceCreated() && iServerClient)
       
    92             {
       
    93             iServerClient->SetSurface(iSurfaceId);
       
    94             }
       
    95         
       
    96         // Try and enable display switching by default. If this leaves then do so quietly.
       
    97         // Either the client has no scheduler installed or the device does not support external
       
    98         // switching (i.e. no plugin was found) 
       
    99         TRAPD(err, SetExternalDisplaySwitchingL(aExtDisplaySwitchingControl));
       
   100         err = err; // remove compile warning
       
   101         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConstructL SetExternalDisplaySwitchingL returned with %d", err);
       
   102 	    }
       
   103 	else
       
   104 	    {
       
   105 	    DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL No CActiveScheduler - ext display and focus features disabled ");
       
   106 	    }
       
   107 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL ---");
       
   108 	}
       
   109 
       
   110 CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody(TInt aDisplayId, const TSurfaceId& aSurfaceId,
       
   111 		const TRect& aCropRect, TVideoAspectRatio aAspectRatio) :
       
   112 	iDisplayId(aDisplayId),
       
   113 	iSurfaceId(aSurfaceId),
       
   114 	iCropRect(aCropRect),
       
   115 	iAspectRatio(aAspectRatio)
       
   116 	{	
       
   117 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody +++");
       
   118 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody ---");
       
   119 	}
       
   120 
       
   121 CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody(TInt aDisplayId) :
       
   122 	iDisplayId(aDisplayId)
       
   123 	{	
       
   124 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody +++");
       
   125 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody ---");
       
   126 	}
       
   127 
       
   128 CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody()
       
   129 	{
       
   130 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody +++");
       
   131 
       
   132 	// remove for whichever array is current
       
   133 	RemoveBackgroundSurface(ETrue);
       
   134 
       
   135 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
   136     if(iSwitchedToExternalDisplay)
       
   137         {
       
   138         SetWindowArrayPtr2Client();
       
   139         RemoveBackgroundSurface(ETrue);
       
   140         }
       
   141 #endif
       
   142 
       
   143 	iClientWindows.Close();	
       
   144     iExtDisplayWindows.Close(); 
       
   145 
       
   146 	delete iExtDisplayHandler;
       
   147 	RemoveExtDisplayPlugin();
       
   148 	REComSession::FinalClose();
       
   149 	
       
   150     delete iWsEventObserver;
       
   151 
       
   152     delete iServerClient;
       
   153     
       
   154 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody ---");
       
   155 	}
       
   156 
       
   157 void CMediaClientVideoDisplayBody::AddDisplayL(MMMFSurfaceEventHandler& aEventHandler)
       
   158 	{
       
   159 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayL +++");
       
   160 	if (iEventHandler)
       
   161 		{
       
   162 		User::Leave(KErrInUse);
       
   163 		}
       
   164 		
       
   165 	iEventHandler = &aEventHandler;
       
   166 	
       
   167 	if (IsSurfaceCreated())
       
   168 		{
       
   169 		iEventHandler->MmsehSurfaceCreated(iDisplayId, iSurfaceId, iCropRect, iAspectRatio);
       
   170 		}
       
   171 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayL ---");
       
   172 	}
       
   173 	
       
   174 void CMediaClientVideoDisplayBody::AddDisplayWindowL(const RWindowBase* aWindow, const TRect& aClipRect, const TRect& aCropRegion, const TRect& aVideoExtent, 
       
   175 															TReal32 aScaleWidth, TReal32 aScaleHeight, TVideoRotation aRotation, 
       
   176 															TAutoScaleType aAutoScaleType, TInt aHorizPos, TInt aVertPos, RWindow* aWindow2)
       
   177 	{	
       
   178 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayWindowL +++");
       
   179     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aWindow WsHandle 0x%X", aWindow->WsHandle());
       
   180     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aClipRect %d,%d - %d,%d", aClipRect.iTl.iX, aClipRect.iTl.iY, aClipRect.iBr.iX, aClipRect.iBr.iY);
       
   181     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   182     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
       
   183     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::AddDisplayWindowL - aScaleWidth %f, aScaleHeight %f", aScaleWidth, aScaleHeight);
       
   184     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aRotation %d", aRotation);
       
   185     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aAutoScaleType %d", aAutoScaleType);
       
   186     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::AddDisplayWindowL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
       
   187 
       
   188 	if (!IsRotationValid(aRotation))
       
   189 		{
       
   190 		User::Leave(KErrArgument);
       
   191 		}
       
   192 
       
   193 	if (!IsAutoScaleTypeValid(aAutoScaleType))
       
   194 		{
       
   195 		User::Leave(KErrArgument);
       
   196 		}
       
   197 
       
   198 	TInt pos = iClientWindows.Find(aWindow->WsHandle(), TWindowData::CompareByWsHandle);
       
   199 	
       
   200 	if (pos != KErrNotFound)
       
   201 		{
       
   202 		User::Leave(KErrInUse);
       
   203 		}
       
   204 	
       
   205 	TWindowData winData(aWindow, aClipRect, aVideoExtent, aScaleWidth, aScaleHeight, aRotation, aAutoScaleType, aHorizPos, aVertPos, aWindow2);
       
   206 	iClientWindows.AppendL(winData);
       
   207 	
       
   208 	iCropRegion = aCropRegion;
       
   209 	
       
   210 	TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
       
   211     UpdateFocus();
       
   212 	
       
   213 	if (IsSurfaceCreated())
       
   214 		{
       
   215         // if first window was just added OR the new window has moved us from out of focus to in focus
       
   216         if(((iClientWindows.Count() == 1) || !prevClientWindowIsInFocus) && iClientRequestedExtDisplaySwitching &&
       
   217                 iClientWindowIsInFocus && iExtDisplayConnected)
       
   218             {
       
   219             TRAPD(err, CreateExtDisplayHandlerL());
       
   220             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL CreateExtDisplayHandlerL error %d", err);
       
   221             if(err == KErrNone)
       
   222                 {
       
   223 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
   224                 // attach surface to client window and hide
       
   225                 // ignore error - no handling required
       
   226                 SetHiddenBackgroundSurfaceOnClientWindow(winData);
       
   227 #endif                
       
   228                 // handle external display
       
   229                 SetWindowArrayPtr2Ext();
       
   230                 User::LeaveIfError(RedrawWindows(aCropRegion));
       
   231                 }
       
   232             }
       
   233         
       
   234         if(!iSwitchedToExternalDisplay)
       
   235             {
       
   236             User::LeaveIfError(SetBackgroundSurface(winData, aCropRegion));
       
   237             }
       
   238 		}
       
   239 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayWindowL ---");
       
   240 	}
       
   241 
       
   242 void CMediaClientVideoDisplayBody::UpdateDisplayWindowL(const RWindowBase* aWindow, const TRect& aClipRect, const TRect& aCropRegion, const TRect& aVideoExtent, 
       
   243                                                             TReal32 aScaleWidth, TReal32 aScaleHeight, TVideoRotation aRotation, 
       
   244                                                             TAutoScaleType aAutoScaleType, TInt aHorizPos, TInt aVertPos, RWindow* aWindow2)
       
   245     {   
       
   246     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDisplayWindowL +++");
       
   247     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aWindow WsHandle 0x%X", aWindow->WsHandle());
       
   248     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aClipRect %d,%d - %d,%d", aClipRect.iTl.iX, aClipRect.iTl.iY, aClipRect.iBr.iX, aClipRect.iBr.iY);
       
   249     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   250     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
       
   251     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aScaleWidth %f, aScaleHeight %f", aScaleWidth, aScaleHeight);
       
   252     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aRotation %d", aRotation);
       
   253     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aAutoScaleType %d", aAutoScaleType);
       
   254     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
       
   255 
       
   256     if (!IsRotationValid(aRotation))
       
   257         {
       
   258         User::Leave(KErrArgument);
       
   259         }
       
   260 
       
   261     if (!IsAutoScaleTypeValid(aAutoScaleType))
       
   262         {
       
   263         User::Leave(KErrArgument);
       
   264         }
       
   265 
       
   266     TInt pos = iClientWindows.Find(aWindow->WsHandle(), TWindowData::CompareByWsHandle);
       
   267     User::LeaveIfError(pos);
       
   268     iClientWindows.Remove(pos);
       
   269     
       
   270     TWindowData winData(aWindow, aClipRect, aVideoExtent, aScaleWidth, aScaleHeight, aRotation, aAutoScaleType, aHorizPos, aVertPos, aWindow2);
       
   271     iClientWindows.AppendL(winData);
       
   272     
       
   273     TRect prevCropRegion = iCropRegion;
       
   274     iCropRegion = aCropRegion;
       
   275     
       
   276     if (IsSurfaceCreated())
       
   277         {
       
   278         if(ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
       
   279             {
       
   280             // all windows need to be redrawn
       
   281             User::LeaveIfError(RedrawWindows(aCropRegion));
       
   282             }
       
   283         else
       
   284             {
       
   285             // only redraw affected window as other window data may have changed
       
   286             if(!iSwitchedToExternalDisplay)
       
   287                 {
       
   288                 User::LeaveIfError(SetBackgroundSurface(winData, aCropRegion));
       
   289                 }
       
   290             }
       
   291         }
       
   292 
       
   293     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDisplayWindowL ---");
       
   294     }
       
   295 
       
   296 void CMediaClientVideoDisplayBody::RemoveDisplay()
       
   297 	{
       
   298 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplay +++");
       
   299 	iEventHandler = NULL;
       
   300 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplay ---");
       
   301 	}	
       
   302 
       
   303 TInt CMediaClientVideoDisplayBody::RemoveDisplayWindow(const RWindowBase& aWindow)
       
   304 	{
       
   305 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplayWindow +++");
       
   306 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   307 	
       
   308 	if (pos >= 0)
       
   309 	    {
       
   310 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
   311         if(IsSurfaceCreated())
       
   312 #else
       
   313 	    if(IsSurfaceCreated() && !iSwitchedToExternalDisplay)
       
   314 #endif
       
   315 	        {
       
   316             iClientWindows[pos].iWindow->RemoveBackgroundSurface(ETrue);
       
   317             // Make sure all window rendering has completed before proceeding
       
   318             RWsSession* ws = iClientWindows[pos].iWindow->Session();
       
   319             if (ws)
       
   320                 {
       
   321                 ws->Finish();
       
   322                 }
       
   323             }
       
   324 
       
   325 	    iClientWindows.Remove(pos);
       
   326 	    
       
   327 	    TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
       
   328         UpdateFocus();
       
   329 
       
   330         // if only window was just removed OR removal has moved us from in focus to out of focus
       
   331         if((iClientWindows.Count() == 0 || prevClientWindowIsInFocus) && iSwitchedToExternalDisplay &&
       
   332                 !iClientWindowIsInFocus)
       
   333             {
       
   334             RemoveBackgroundSurface(ETrue);
       
   335             SetWindowArrayPtr2Client();
       
   336             RemoveExtDisplayHandler();
       
   337             RedrawWindows(iCropRegion);
       
   338             }
       
   339 		}
       
   340 	
       
   341 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplayWindow ---");
       
   342 	return pos;
       
   343 	}
       
   344 
       
   345 
       
   346 TInt CMediaClientVideoDisplayBody::SurfaceCreated(const TSurfaceId& aSurfaceId, const TRect& aCropRect, TVideoAspectRatio aAspectRatio, const TRect& aCropRegion)
       
   347 	{
       
   348 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCreated +++");
       
   349     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aSurfaceId %08x:%08x:%08x:%08x", aSurfaceId.iInternal[3], aSurfaceId.iInternal[2], aSurfaceId.iInternal[1], aSurfaceId.iInternal[0]);
       
   350     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aCropRect %d,%d - %d,%d", aCropRect.iTl.iX, aCropRect.iTl.iY, aCropRect.iBr.iX, aCropRect.iBr.iY);
       
   351     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SurfaceCreated - aAspectRatio %d/%d", aAspectRatio.iNumerator, aAspectRatio.iDenominator);
       
   352     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   353 
       
   354     TBool emitEvent = EFalse;
       
   355 	if((iSurfaceId != aSurfaceId) && (!aSurfaceId.IsNull()))
       
   356 		{
       
   357 		emitEvent = ETrue;
       
   358 		}
       
   359 
       
   360 	iSurfaceId = aSurfaceId;
       
   361 	iCropRect = aCropRect;
       
   362 	iAspectRatio = aAspectRatio;
       
   363 	iCropRegion = aCropRegion;
       
   364 	
       
   365 	if(iServerClient)
       
   366 	    {
       
   367         iServerClient->SetSurface(iSurfaceId);
       
   368 	    }
       
   369 	
       
   370 	if (emitEvent && iEventHandler)
       
   371 		{
       
   372 		iEventHandler->MmsehSurfaceCreated(iDisplayId, iSurfaceId, iCropRect, iAspectRatio);
       
   373 		}
       
   374 
       
   375 	TInt err = KErrNone;
       
   376     if((iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching && iClientWindowIsInFocus)
       
   377         {
       
   378         if(iExtDisplayConnected && !iExtDisplayHandler)
       
   379             {
       
   380             TRAP(err, CreateExtDisplayHandlerL());
       
   381             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCreated CreateExtDisplayHandlerL error %d", err);
       
   382             if(err == KErrNone)
       
   383                 {
       
   384 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
   385                 SetHiddenBackgroundSurfaceOnAllClientWindows();
       
   386 #endif          
       
   387                 SetWindowArrayPtr2Ext();
       
   388                 }
       
   389             }
       
   390         }
       
   391     
       
   392     err = RedrawWindows(aCropRegion);
       
   393     
       
   394     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCreated --- Return error %d", err);
       
   395 	return err;
       
   396 	}
       
   397 
       
   398 void CMediaClientVideoDisplayBody::RemoveBackgroundSurface(TBool aTriggerRedraw)
       
   399 	{
       
   400 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveBackgroundSurface +++");
       
   401     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::RemoveBackgroundSurface - iSurfaceId %08x:%08x:%08x:%08x", iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
       
   402 
       
   403 	if (IsSurfaceCreated())
       
   404 		{
       
   405 		RWsSession* ws = NULL;
       
   406 		TInt count = iWindowsArrayPtr->Count();
       
   407 	
       
   408 		for (TInt i = 0; i < count; ++i)
       
   409 			{
       
   410 			(*iWindowsArrayPtr)[i].iWindow->RemoveBackgroundSurface(aTriggerRedraw);
       
   411             // Make sure all window rendering has completed before proceeding
       
   412             ws = (*iWindowsArrayPtr)[i].iWindow->Session();
       
   413             if (ws)
       
   414                 {
       
   415                 ws->Finish();
       
   416                 }
       
   417 			}
       
   418 		}
       
   419 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveBackgroundSurface ---");
       
   420 	}
       
   421 
       
   422 void CMediaClientVideoDisplayBody::RemoveSurface(TBool aControllerEvent)
       
   423     {
       
   424     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveSurface +++");
       
   425     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::RemoveSurface - iSurfaceId %08x:%08x:%08x:%08x", iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
       
   426 
       
   427     if (IsSurfaceCreated())
       
   428         {
       
   429         RemoveBackgroundSurface(ETrue);
       
   430 
       
   431         if (iEventHandler  && aControllerEvent)
       
   432             {
       
   433             iEventHandler->MmsehRemoveSurface(iSurfaceId);
       
   434             }
       
   435 
       
   436         if(iSwitchedToExternalDisplay)
       
   437             {
       
   438             SetWindowArrayPtr2Client();
       
   439 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
   440             RemoveBackgroundSurface(ETrue);
       
   441 #endif
       
   442             RemoveExtDisplayHandler();
       
   443             }
       
   444         iSurfaceId = TSurfaceId::CreateNullId();
       
   445         }
       
   446     
       
   447     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveSurface ---");
       
   448     }
       
   449 
       
   450 TInt CMediaClientVideoDisplayBody::SurfaceParametersChanged(const TSurfaceId& aSurfaceId, const TRect& aCropRect, TVideoAspectRatio aAspectRatio)
       
   451 	{
       
   452 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged +++");
       
   453     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aSurfaceId %08x:%08x:%08x:%08x", aSurfaceId.iInternal[3], aSurfaceId.iInternal[2], aSurfaceId.iInternal[1], aSurfaceId.iInternal[0]);
       
   454     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aCropRect %d,%d - %d,%d", aCropRect.iTl.iX, aCropRect.iTl.iY, aCropRect.iBr.iX, aCropRect.iBr.iY);
       
   455     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SurfaceCreated - aAspectRatio %d/%d", aAspectRatio.iNumerator, aAspectRatio.iDenominator);
       
   456 
       
   457     if (!IsSurfaceCreated())
       
   458 		{
       
   459 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrNotSupproted");
       
   460 		return KErrNotSupported;
       
   461 		}
       
   462 
       
   463 	if (iSurfaceId != aSurfaceId)
       
   464 		{
       
   465 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrInUse");
       
   466 		return KErrInUse;
       
   467 		}
       
   468 
       
   469 	if (iEventHandler)
       
   470 		{
       
   471 		iEventHandler->MmsehSurfaceParametersChanged(iSurfaceId, aCropRect, aAspectRatio);
       
   472 		}
       
   473 
       
   474 	TInt error = KErrNone;
       
   475 	if (iCropRect != aCropRect || iAspectRatio != aAspectRatio)
       
   476 		{
       
   477 		// We only need to redraw if the aspect ratio has changed, or the area of the video to
       
   478 		// display (i.e the intersection of client crop region and surface crop rectangle) has changed.
       
   479 		TBool redraw = EFalse;
       
   480 		if (iAspectRatio != aAspectRatio || SurfaceCropRectChangeRequiresRedraw(iCropRect, aCropRect, iCropRegion))
       
   481 			{
       
   482 			redraw = ETrue;
       
   483 			}
       
   484 
       
   485 		iCropRect = aCropRect;
       
   486 		iAspectRatio = aAspectRatio;
       
   487 
       
   488 		if (redraw)
       
   489 			{
       
   490 			error = RedrawWindows(iCropRegion);
       
   491 			}
       
   492 		}
       
   493 	else
       
   494 		{
       
   495 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged - Surface parameters have not changed");
       
   496 		}
       
   497 
       
   498 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error %d", error);
       
   499 	return error;
       
   500 	}
       
   501 	
       
   502 TInt CMediaClientVideoDisplayBody::RedrawWindows(const TRect& aCropRegion)
       
   503 	{
       
   504 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RedrawWindows +++");
       
   505 	TInt err = KErrNone;	
       
   506 
       
   507 	iCropRegion = aCropRegion;
       
   508 	
       
   509 	if(IsSurfaceCreated())
       
   510 		{
       
   511 		TInt count = iWindowsArrayPtr->Count();
       
   512 	
       
   513 		for (TInt i = 0; i < count; ++i)
       
   514 			{
       
   515 			err = SetBackgroundSurface((*iWindowsArrayPtr)[i], aCropRegion);
       
   516 		
       
   517 			if (err != KErrNone)
       
   518 				{
       
   519 				break;
       
   520 				}
       
   521 			}
       
   522 		}
       
   523 		
       
   524 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::RedrawWindows --- return with %d", err);
       
   525 	return err;
       
   526 	}
       
   527 
       
   528 void CMediaClientVideoDisplayBody::UpdateCropRegionL(const TRect& aCropRegion, TInt aPos, TBool aRedrawIndividualWindow)
       
   529     {
       
   530     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL +++");
       
   531 
       
   532     TRect prevCropRegion(iCropRegion);
       
   533     iCropRegion = aCropRegion;
       
   534     
       
   535     if (IsSurfaceCreated())
       
   536         {
       
   537         if(prevCropRegion == aCropRegion)
       
   538             {
       
   539             if(!iSwitchedToExternalDisplay && aRedrawIndividualWindow)
       
   540                 {
       
   541                 User::LeaveIfError(SetBackgroundSurface(iClientWindows[aPos], aCropRegion));
       
   542                 }
       
   543             }
       
   544         else
       
   545             {
       
   546 			// We only need to redraw if the area of the video to display (i.e the
       
   547 			// intersection of client crop region and surface crop rectangle) has changed.
       
   548 			if (ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
       
   549 				{
       
   550 				User::LeaveIfError(RedrawWindows(aCropRegion));
       
   551 				}
       
   552             }
       
   553         }
       
   554     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL ---");    
       
   555     }
       
   556 
       
   557 void CMediaClientVideoDisplayBody::SetAutoScaleL(const RWindowBase& aWindow, TAutoScaleType aScaleType, TInt aHorizPos, TInt aVertPos, const TRect& aCropRegion)
       
   558 	{
       
   559 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL +++");
       
   560     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aWindow WsHandle 0x%X", aWindow.WsHandle());
       
   561     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aScaleType %d", aScaleType);
       
   562     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
       
   563     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   564 
       
   565 	if (!IsAutoScaleTypeValid(aScaleType))
       
   566 		{
       
   567 		User::Leave(KErrArgument);
       
   568 		}
       
   569 
       
   570     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   571 	User::LeaveIfError(pos);
       
   572 
       
   573 	TBool parameterChanged = EFalse;
       
   574 	if (aScaleType != iClientWindows[pos].iAutoScaleType || aHorizPos != iClientWindows[pos].iHorizPos || aVertPos != iClientWindows[pos].iVertPos)
       
   575 		{
       
   576 		iClientWindows[pos].iAutoScaleType = aScaleType;
       
   577 		iClientWindows[pos].iHorizPos = aHorizPos;
       
   578 		iClientWindows[pos].iVertPos = aVertPos;
       
   579 		parameterChanged = ETrue;
       
   580 		}
       
   581 	else
       
   582 		{
       
   583 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters have not changed");
       
   584 		}
       
   585 
       
   586 	UpdateCropRegionL(aCropRegion, pos, parameterChanged);
       
   587 
       
   588 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL ---");
       
   589 	}
       
   590 	
       
   591 
       
   592 void CMediaClientVideoDisplayBody::SetRotationL(const RWindowBase& aWindow, TVideoRotation aRotation, const TRect& aCropRegion)
       
   593 	{
       
   594 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL +++");
       
   595     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aWindow WsHandle 0x%X", aWindow.WsHandle());
       
   596     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation);
       
   597     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   598 
       
   599 	if (!IsRotationValid(aRotation))
       
   600 		{
       
   601 		User::Leave(KErrArgument);
       
   602 		}
       
   603 
       
   604     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   605 	User::LeaveIfError(pos);
       
   606 
       
   607 	TBool parameterChanged = EFalse;
       
   608 	if (aRotation != iClientWindows[pos].iRotation)
       
   609 		{
       
   610 		iClientWindows[pos].iRotation = aRotation;
       
   611 		parameterChanged = ETrue;
       
   612 		}
       
   613 	else
       
   614 		{
       
   615 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL - Rotation has not changed");
       
   616 		}
       
   617 
       
   618     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
       
   619 
       
   620 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL ---");
       
   621 	}
       
   622 
       
   623 TVideoRotation CMediaClientVideoDisplayBody::RotationL(const RWindowBase& aWindow)
       
   624 	{
       
   625 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RotationL +++");
       
   626 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   627 	User::LeaveIfError(pos);
       
   628 	
       
   629 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RotationL ---");
       
   630 	return iClientWindows[pos].iRotation;
       
   631 	}
       
   632 
       
   633 void CMediaClientVideoDisplayBody::SetScaleFactorL(const RWindowBase& aWindow, TReal32 aWidthPercentage, TReal32 aHeightPercentage, const TRect& aCropRegion)
       
   634 	{
       
   635 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL +++");
       
   636     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetScaleFactorL - aWindow WsHandle 0x%X", aWindow.WsHandle());
       
   637     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetScaleFactorL - aWidthPercentage %f, aHeightPercentage %f", aWidthPercentage, aHeightPercentage);
       
   638     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetScaleFactorL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   639 
       
   640     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   641 	User::LeaveIfError(pos);
       
   642 	
       
   643 	if (aWidthPercentage <= 0.0 || aHeightPercentage <= 0.0)
       
   644 		{
       
   645 		User::Leave(KErrArgument);
       
   646 		}
       
   647 
       
   648 	TBool parameterChanged = EFalse;
       
   649 	if (aWidthPercentage != iClientWindows[pos].iScaleWidth ||
       
   650 	    aHeightPercentage != iClientWindows[pos].iScaleHeight ||
       
   651 		EAutoScaleNone != iClientWindows[pos].iAutoScaleType)
       
   652 		{
       
   653 		iClientWindows[pos].iScaleWidth = aWidthPercentage;
       
   654 		iClientWindows[pos].iScaleHeight = aHeightPercentage;
       
   655 		iClientWindows[pos].iAutoScaleType = EAutoScaleNone;
       
   656 		parameterChanged = ETrue;
       
   657 		}
       
   658 	else
       
   659 		{
       
   660 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters have not changed");
       
   661 		}
       
   662 
       
   663     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
       
   664 	
       
   665     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL ---");
       
   666 	}
       
   667 	
       
   668 void CMediaClientVideoDisplayBody::GetScaleFactorL(const RWindowBase& aWindow, TReal32& aWidthPercentage, TReal32& aHeightPercentage)
       
   669 	{
       
   670 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::GetScaleFactorL +++");
       
   671 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   672 	User::LeaveIfError(pos);
       
   673 	
       
   674 	aWidthPercentage = iClientWindows[pos].iScaleWidth;
       
   675 	aHeightPercentage = iClientWindows[pos].iScaleHeight;
       
   676 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::GetScaleFactorL ---");
       
   677 	}
       
   678 
       
   679 void CMediaClientVideoDisplayBody::SetAutoScaleL(TAutoScaleType aScaleType, TInt aHorizPos, TInt aVertPos, const TRect& aCropRegion)
       
   680 	{
       
   681 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL +++");
       
   682     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aScaleType %d", aScaleType);
       
   683     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
       
   684     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   685 
       
   686 	if (!IsAutoScaleTypeValid(aScaleType))
       
   687 		{
       
   688 		User::Leave(KErrArgument);
       
   689 		}
       
   690 
       
   691     TRect prevCropRegion(iCropRegion);
       
   692 	iCropRegion = aCropRegion;
       
   693 	
       
   694 	TBool parameterChanged;
       
   695 	TInt count = iClientWindows.Count();
       
   696 
       
   697 	for (TInt i = 0; i < count; ++i)
       
   698 		{
       
   699 		parameterChanged = EFalse;
       
   700 		if (aScaleType != iClientWindows[i].iAutoScaleType || aHorizPos != iClientWindows[i].iHorizPos || aVertPos != iClientWindows[i].iVertPos)
       
   701 			{
       
   702 			iClientWindows[i].iAutoScaleType = aScaleType;
       
   703 			iClientWindows[i].iHorizPos = aHorizPos;
       
   704 			iClientWindows[i].iVertPos = aVertPos;
       
   705 			parameterChanged = ETrue;
       
   706 			}
       
   707 		else
       
   708 			{
       
   709 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters for window pos %d have not changed", i);
       
   710 			}
       
   711 
       
   712 		// We only need to redraw if the scale parameters have changed, or the area of the video
       
   713 		// to display (i.e the intersection of client crop region and surface crop rectangle) has changed.
       
   714 		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
       
   715 			{
       
   716 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
       
   717 			}
       
   718 		}
       
   719 
       
   720 	// We only need to redraw if the area of the video to display (i.e the
       
   721 	// intersection of client crop region and surface crop rectangle) has changed.
       
   722 	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
       
   723         {
       
   724         User::LeaveIfError(RedrawWindows(aCropRegion));
       
   725         }
       
   726 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL ---");
       
   727 	}
       
   728 
       
   729 
       
   730 void CMediaClientVideoDisplayBody::SetRotationL(TVideoRotation aRotation, const TRect& aCropRegion)
       
   731 	{
       
   732 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL +++");
       
   733     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation);
       
   734     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   735 
       
   736 	if (!IsRotationValid(aRotation))
       
   737 		{
       
   738 		User::Leave(KErrArgument);
       
   739 		}
       
   740 
       
   741     TRect prevCropRegion(iCropRegion);
       
   742     iCropRegion = aCropRegion;
       
   743 
       
   744 	TBool parameterChanged;
       
   745 	TInt count = iClientWindows.Count();
       
   746 	
       
   747 	for (TInt i = 0; i < count; ++i)
       
   748 		{
       
   749 		parameterChanged = EFalse;
       
   750 		if (aRotation != iClientWindows[i].iRotation)
       
   751 			{
       
   752 			iClientWindows[i].iRotation = aRotation;
       
   753 			parameterChanged = ETrue;
       
   754 			}
       
   755 		else
       
   756 			{
       
   757 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - Rotation for window pos %d has not changed", i);
       
   758 			}
       
   759 
       
   760 		// We only need to redraw if the scale parameters have changed, or the area of the video
       
   761 		// to display (i.e the intersection of client crop region and surface crop rectangle) has changed.
       
   762 		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
       
   763 			{
       
   764 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
       
   765 			}
       
   766 		}
       
   767 	
       
   768 	// We only need to redraw if the area of the video to display (i.e the
       
   769 	// intersection of client crop region and surface crop rectangle) has changed.
       
   770 	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
       
   771         {
       
   772         User::LeaveIfError(RedrawWindows(aCropRegion));
       
   773         }
       
   774 	   
       
   775 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL ---");
       
   776 	}
       
   777 		
       
   778 void CMediaClientVideoDisplayBody::SetScaleFactorL(TReal32 aWidthPercentage, TReal32 aHeightPercentage, const TRect& aCropRegion)
       
   779 	{
       
   780 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL +++");
       
   781     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetScaleFactorL - aWidthPercentage %f, aHeightPercentage %f", aWidthPercentage, aHeightPercentage);
       
   782     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetScaleFactorL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   783 
       
   784     if (aWidthPercentage <= 0.0 || aHeightPercentage <= 0.0)
       
   785 		{
       
   786 		User::Leave(KErrArgument);
       
   787 		}
       
   788 	
       
   789     TRect prevCropRegion(iCropRegion);
       
   790 	iCropRegion = aCropRegion;
       
   791 
       
   792 	TBool parameterChanged;
       
   793 	TInt count = iClientWindows.Count();
       
   794 	
       
   795 	for (TInt i = 0; i < count; ++i)
       
   796 		{
       
   797 		parameterChanged = EFalse;
       
   798 		
       
   799 		if (aWidthPercentage != iClientWindows[i].iScaleWidth ||
       
   800 		    aHeightPercentage != iClientWindows[i].iScaleHeight ||
       
   801 			EAutoScaleNone != iClientWindows[i].iAutoScaleType)
       
   802 			{
       
   803 			iClientWindows[i].iScaleWidth = aWidthPercentage;
       
   804 			iClientWindows[i].iScaleHeight = aHeightPercentage;
       
   805 			iClientWindows[i].iAutoScaleType = EAutoScaleNone;
       
   806 			parameterChanged = ETrue;
       
   807 			}
       
   808 		else
       
   809 			{
       
   810 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters for window pos %d have not changed", i);
       
   811 			}
       
   812 
       
   813 		// We only need to redraw if the scale parameters have changed, or the area of the video to
       
   814 		// display (i.e the intersection of client crop region and surface crop rectangle) has changed.
       
   815 		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
       
   816 			{
       
   817 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
       
   818 			}
       
   819 		}
       
   820 
       
   821 	// We only need to redraw if the area of the video to display (i.e the
       
   822 	// intersection of client crop region and surface crop rectangle) has changed.
       
   823 	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
       
   824         {
       
   825         User::LeaveIfError(RedrawWindows(aCropRegion));
       
   826         }
       
   827 	   
       
   828 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL ---");
       
   829 	}
       
   830 
       
   831 void CMediaClientVideoDisplayBody::SetWindowClipRectL(const RWindowBase& aWindow, const TRect& aWindowClipRect, const TRect& aCropRegion)
       
   832 	{
       
   833 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL +++");
       
   834     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetWindowClipRectL - aWindow WsHandle 0x%X", aWindow.WsHandle());
       
   835     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetWindowClipRectL - aWindowClipRect %d,%d - %d,%d", aWindowClipRect.iTl.iX, aWindowClipRect.iTl.iY, aWindowClipRect.iBr.iX, aWindowClipRect.iBr.iY);
       
   836     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetWindowClipRectL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   837 	
       
   838 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   839 	User::LeaveIfError(pos);
       
   840 
       
   841 	TBool parameterChanged = EFalse;
       
   842 	if (aWindowClipRect != iClientWindows[pos].iClipRect)
       
   843 		{
       
   844 		// We only want to redraw if the change in the clipping rectangle would result
       
   845 		// in a change to the area of the display used for the video.
       
   846 		// The video is always displayed in the intersection of the clipping rectangle
       
   847 		// and the video extent, so check if this has changed.
       
   848 		parameterChanged = IntersectionAreaChanged(iClientWindows[pos].iClipRect, aWindowClipRect, iClientWindows[pos].iVideoExtent);
       
   849 
       
   850 		iClientWindows[pos].iClipRect = aWindowClipRect;
       
   851 		}
       
   852 	else
       
   853 		{
       
   854 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL - Clip rect parameter has not changed");
       
   855 		}
       
   856 
       
   857     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
       
   858 
       
   859     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL ---");
       
   860 	}
       
   861 	
       
   862 void CMediaClientVideoDisplayBody::SetVideoExtentL(const RWindowBase& aWindow, const TRect& aVideoExtent, const TRect& aCropRegion)
       
   863 	{
       
   864 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL +++");
       
   865     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetVideoExtentL - aWindow WsHandle 0x%X", aWindow.WsHandle());
       
   866     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetVideoExtentL - aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
       
   867     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetVideoExtentL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   868 
       
   869     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
       
   870 	User::LeaveIfError(pos);
       
   871 
       
   872 	TBool parameterChanged = EFalse;
       
   873 	if (aVideoExtent != iClientWindows[pos].iVideoExtent)
       
   874 		{
       
   875 		iClientWindows[pos].iVideoExtent = aVideoExtent;
       
   876 		parameterChanged = ETrue;
       
   877 		}
       
   878 	else
       
   879 		{
       
   880 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL - Video extent parameter has not changed");
       
   881 		}
       
   882 
       
   883     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
       
   884     
       
   885 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL ---");
       
   886 	}
       
   887 	
       
   888 TBool CMediaClientVideoDisplayBody::HasWindows() const
       
   889 	{
       
   890 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::HasWindows +++");
       
   891 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::HasWindows --- return %d", (iClientWindows.Count() > 0));
       
   892 	return (iClientWindows.Count() > 0);
       
   893 	}
       
   894 	
       
   895 TInt CMediaClientVideoDisplayBody::SetBackgroundSurface(TWindowData& aWindowData,  
       
   896 									const TRect& aCropRegion)
       
   897 	{
       
   898 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetBackgroundSurface +++");
       
   899     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface - iWindow WsHandle 0x%X", aWindowData.iWindow->WsHandle());
       
   900     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - iWindow abs pos %d,%d - width %d, height %d", aWindowData.iWindow->AbsPosition().iX, aWindowData.iWindow->AbsPosition().iY, aWindowData.iWindow->Size().iWidth, aWindowData.iWindow->Size().iHeight);
       
   901     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - iClipRect %d,%d - %d,%d", aWindowData.iClipRect.iTl.iX, aWindowData.iClipRect.iTl.iY, aWindowData.iClipRect.iBr.iX, aWindowData.iClipRect.iBr.iY);
       
   902     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - iVideoExtent %d,%d - %d,%d", aWindowData.iVideoExtent.iTl.iX, aWindowData.iVideoExtent.iTl.iY, aWindowData.iVideoExtent.iBr.iX, aWindowData.iVideoExtent.iBr.iY);
       
   903     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - iScaleWidth %f, iScaleHeight %f", aWindowData.iScaleWidth, aWindowData.iScaleHeight);
       
   904     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface - iRotation %d", aWindowData.iRotation);
       
   905     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface - iAutoScaleType %d", aWindowData.iAutoScaleType);
       
   906     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - iHorizPos %d, iVertPos %d", aWindowData.iHorizPos, aWindowData.iVertPos);
       
   907     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
       
   908 	
       
   909 	// required as this private function is called directly from external friend class
       
   910 	iCropRegion = aCropRegion;
       
   911 
       
   912     // viewport is the viewable area of surface
       
   913     TRect viewport(iCropRect);
       
   914     if (aCropRegion.Width() > 0 || aCropRegion.Height() > 0)
       
   915         {
       
   916         viewport.Intersection(aCropRegion);
       
   917         }
       
   918     
       
   919     // Viewport is 0 size, don't show any video
       
   920     if (viewport.Width() <= 0 || viewport.Height() <= 0)
       
   921         {
       
   922         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
       
   923         return KErrArgument;
       
   924         }
       
   925 
       
   926     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewport1 %d,%d - %d,%d", viewport.iTl.iX, viewport.iTl.iY, viewport.iBr.iX, viewport.iBr.iY);
       
   927 
       
   928     TRect videoExtent(aWindowData.iVideoExtent);
       
   929 
       
   930     TReal32 inputWidth = 0.0f;
       
   931     TReal32 inputHeight = 0.0f;
       
   932     TReal32 pixelAspectRatio = 0.0f;
       
   933     switch (aWindowData.iRotation)
       
   934         {
       
   935         case EVideoRotationNone:
       
   936         case EVideoRotationClockwise180:
       
   937             inputWidth = static_cast<TReal32>(viewport.Width());
       
   938             inputHeight = static_cast<TReal32>(viewport.Height());
       
   939             pixelAspectRatio = static_cast<TReal32>(iAspectRatio.iNumerator) / iAspectRatio.iDenominator;
       
   940             break;
       
   941         case EVideoRotationClockwise90:
       
   942         case EVideoRotationClockwise270:
       
   943             inputWidth = static_cast<TReal32>(viewport.Height());
       
   944             inputHeight = static_cast<TReal32>(viewport.Width());
       
   945             pixelAspectRatio = static_cast<TReal32>(iAspectRatio.iDenominator) / iAspectRatio.iNumerator;
       
   946             break;
       
   947         default:
       
   948             // Should never get to default unless there's been some programming error.
       
   949 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
       
   950 			return KErrArgument;
       
   951         }
       
   952     
       
   953     TReal32 viewportAspect = pixelAspectRatio * inputWidth / inputHeight;
       
   954     TReal32 vidextAspect = static_cast<TReal32>(videoExtent.Width()) / static_cast<TReal32>(videoExtent.Height());
       
   955     
       
   956     DEBUG_PRINTF4("CMediaClientVideoDisplayBody::SetBackgroundSurface - inputWidth %f, inputHeight %f, PAR %f", inputWidth, inputHeight, pixelAspectRatio);
       
   957     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewportAspect %f, vidextAspect %f", viewportAspect, vidextAspect);
       
   958 
       
   959     // Set the extent to the display area in the window.  The final height and with is to 
       
   960     // be changed by deltaHeight and deltaWidth respectively.
       
   961     TRect extent(videoExtent);
       
   962 
       
   963     TInt deltaHeight = 0;
       
   964     TInt deltaWidth = 0;
       
   965     
       
   966     if (aWindowData.iAutoScaleType == EAutoScaleBestFit)
       
   967         {
       
   968         if (viewportAspect > vidextAspect)
       
   969             {
       
   970             // Shrink height to get the correct aspect ratio
       
   971             deltaHeight = (TInt) (extent.Width() / viewportAspect - extent.Height());
       
   972             }
       
   973         else
       
   974             {
       
   975             // Shrink width to get the correct aspect ratio
       
   976             deltaWidth = (TInt) (extent.Height() * viewportAspect - extent.Width());
       
   977             }
       
   978         }
       
   979     else if (aWindowData.iAutoScaleType == EAutoScaleClip)
       
   980         {
       
   981         if (viewportAspect > vidextAspect)
       
   982             {
       
   983             // Expand width to get the correct aspect ratio
       
   984             deltaWidth = (TInt) (extent.Height() * viewportAspect - extent.Width());
       
   985             }
       
   986         else
       
   987             {
       
   988             // Expand height to get the correct aspect ratio
       
   989             deltaHeight = (TInt) (extent.Width() / viewportAspect - extent.Height());
       
   990             }
       
   991         }
       
   992     else if (aWindowData.iAutoScaleType == EAutoScaleStretch)
       
   993         {
       
   994         if(iSwitchedToExternalDisplay)
       
   995             {
       
   996             UpdateDeltaForExtDisplay(viewportAspect, videoExtent, deltaHeight, deltaWidth);
       
   997             }
       
   998         }
       
   999     else if (aWindowData.iAutoScaleType == EAutoScaleNone)
       
  1000         {
       
  1001         // for non-square pixels, reduce one dimension
       
  1002         // XXX other option is to enlarge in the other dimension
       
  1003         if(pixelAspectRatio > 1)
       
  1004             {
       
  1005             inputHeight /= pixelAspectRatio;
       
  1006             }
       
  1007         else if(pixelAspectRatio < 1)
       
  1008             {
       
  1009             inputWidth *= pixelAspectRatio;
       
  1010             }
       
  1011         deltaHeight = (TInt) (inputHeight * aWindowData.iScaleHeight * 0.01 - videoExtent.Height());
       
  1012         deltaWidth = (TInt) (inputWidth * aWindowData.iScaleWidth * 0.01 - videoExtent.Width());
       
  1013         }
       
  1014     
       
  1015     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - deltaWidth %d, deltaHeight %d", deltaWidth, deltaHeight);
       
  1016 
       
  1017     // Change the width of the extent in the proper directions and propertions.
       
  1018     switch (aWindowData.iHorizPos)
       
  1019         {
       
  1020     case EHorizontalAlignCenter:
       
  1021         extent.iTl.iX -= deltaWidth / 2;
       
  1022         extent.iBr.iX += deltaWidth / 2;
       
  1023         break;
       
  1024     case EHorizontalAlignLeft:
       
  1025         extent.iBr.iX += deltaWidth;
       
  1026         break;
       
  1027     case EHorizontalAlignRight:
       
  1028         extent.iTl.iX -= deltaWidth;
       
  1029         break;
       
  1030     default:
       
  1031         TInt width = extent.Width() + deltaWidth;
       
  1032         extent.iTl.iX += aWindowData.iHorizPos;
       
  1033         extent.iBr.iX = extent.iTl.iX + width;
       
  1034         break;
       
  1035         }
       
  1036     
       
  1037     // Change the height of the extent in the proper directions and propertions.
       
  1038     switch (aWindowData.iVertPos)
       
  1039         {
       
  1040     case EVerticalAlignCenter:
       
  1041         extent.iTl.iY -= deltaHeight / 2;
       
  1042         extent.iBr.iY += deltaHeight / 2;
       
  1043         break;
       
  1044     case EVerticalAlignTop:
       
  1045         extent.iBr.iY += deltaHeight;
       
  1046         break;
       
  1047     case EVerticalAlignBottom:
       
  1048         extent.iTl.iY -= deltaHeight;
       
  1049         break;
       
  1050     default:
       
  1051         TInt height = extent.Height() + deltaHeight;
       
  1052         extent.iTl.iY += aWindowData.iVertPos;
       
  1053         extent.iBr.iY = extent.iTl.iY + height;
       
  1054         break;
       
  1055         }
       
  1056         
       
  1057     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - extent1 %d,%d - %d,%d", extent.iTl.iX, extent.iTl.iY, extent.iBr.iX, extent.iBr.iY);
       
  1058 
       
  1059     // The video should not be displayed outside the intended video extent or clipping rectangle.  
       
  1060     // The extent already has the correct size and position for displaying the entire viewport.  
       
  1061     // The viewport is clipped such that the video is not moved/distorted when we take the extent 
       
  1062     // to be the intersection of itself and the intended video extent.
       
  1063     
       
  1064     TRect viewableArea(videoExtent);
       
  1065     viewableArea.Intersection(aWindowData.iClipRect);
       
  1066     
       
  1067     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewableArea %d,%d - %d,%d", viewableArea.iTl.iX, viewableArea.iTl.iY, viewableArea.iBr.iX, viewableArea.iBr.iY);
       
  1068 
       
  1069     // Number of pixels (in window coordinates) to be clipped on the right, bottom, top and left sides of
       
  1070     // the video.
       
  1071     TInt dr = Max(0, extent.iBr.iX - viewableArea.iBr.iX);
       
  1072     TInt db = Max(0, extent.iBr.iY - viewableArea.iBr.iY);
       
  1073     TInt dt = Max(0, viewableArea.iTl.iY - extent.iTl.iY);
       
  1074     TInt dl = Max(0, viewableArea.iTl.iX - extent.iTl.iX);
       
  1075     
       
  1076     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - dr %d, db %d, dt %d, dl %d", dr, db, dt, dl);
       
  1077 
       
  1078     // Calculate the number of pixels in the video per window pixel in both x and y directions.
       
  1079     TReal32 wRatio = 0.0f; 
       
  1080     TReal32 hRatio = 0.0f;
       
  1081 
       
  1082     // Make sure we don't divide by 0
       
  1083     if (extent.Width() != 0)
       
  1084         {
       
  1085         wRatio = inputWidth / static_cast<TReal32>(extent.Width());
       
  1086         }
       
  1087     
       
  1088     if (extent.Height() != 0)
       
  1089         {
       
  1090         hRatio = inputHeight / static_cast<TReal32>(extent.Height());
       
  1091         }
       
  1092     
       
  1093     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - wRatio %f, hRatio %f", wRatio, hRatio);
       
  1094 
       
  1095     // Clip the viewport 
       
  1096     switch (aWindowData.iRotation)
       
  1097     {
       
  1098     case EVideoRotationNone:
       
  1099         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(dr));
       
  1100         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(db));
       
  1101         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(dl));
       
  1102         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(dt));
       
  1103         break;
       
  1104     case EVideoRotationClockwise180:
       
  1105         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(dl));
       
  1106         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(dt));
       
  1107         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(dr));
       
  1108         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(db));
       
  1109         break;
       
  1110     case EVideoRotationClockwise90:
       
  1111         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(db));
       
  1112         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(dl));
       
  1113         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(dt));
       
  1114         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(dr));
       
  1115         break;
       
  1116     case EVideoRotationClockwise270:
       
  1117         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(dt));
       
  1118         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(dr));
       
  1119         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(db));
       
  1120         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(dl));
       
  1121         break;
       
  1122     default:
       
  1123         // Should never get to default unless there's been some programming error.
       
  1124 		DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
       
  1125         return KErrArgument;
       
  1126     }
       
  1127     
       
  1128     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewport2 %d,%d - %d,%d", viewport.iTl.iX, viewport.iTl.iY, viewport.iBr.iX, viewport.iBr.iY);
       
  1129 
       
  1130     // Clip the extent.
       
  1131     extent.Intersection(viewableArea);
       
  1132     
       
  1133     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - extent2 %d,%d - %d,%d", extent.iTl.iX, extent.iTl.iY, extent.iBr.iX, extent.iBr.iY);
       
  1134 
       
  1135     aWindowData.iSurfaceConfig.SetViewport(viewport);
       
  1136     aWindowData.iSurfaceConfig.SetExtent(extent);
       
  1137     aWindowData.iSurfaceConfig.SetOrientation(ConvertRotation(aWindowData.iRotation));
       
  1138     
       
  1139     aWindowData.iSurfaceConfig.SetSurfaceId(iSurfaceId);
       
  1140 
       
  1141     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - iSurfaceId %08x:%08x:%08x:%08x",
       
  1142             iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
       
  1143     
       
  1144     // Get the rectangle that bounds the crop rectangle and the viewport.  This should be
       
  1145     // the same as the crop rectangle as long as the viewport does not go outside this area.
       
  1146     TRect rect(iCropRect);
       
  1147     rect.BoundingRect(viewport);
       
  1148     TInt err = KErrNone;
       
  1149     
       
  1150     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - rect %d,%d - %d,%d", rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
       
  1151 
       
  1152     // Check if the viewport and extent can be displayed as a background surface. The viewport 
       
  1153     // is valid if it is within the crop rectangle and is not empty.  The extent is valid if 
       
  1154     // it is not empty. 
       
  1155     if (rect == iCropRect && !viewport.IsEmpty() && !extent.IsEmpty())
       
  1156         {
       
  1157         DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetBackgroundSurface - Calling SetBackgroundSurface");
       
  1158         err = aWindowData.iWindow->SetBackgroundSurface(aWindowData.iSurfaceConfig, ETrue);
       
  1159         }
       
  1160 
       
  1161     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- err %d", err);
       
  1162     return err;
       
  1163     }
       
  1164 
       
  1165 TBool CMediaClientVideoDisplayBody::IsUsed() const
       
  1166 	{
       
  1167 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IsUsed +++");
       
  1168 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsUsed --- return %d", (iEventHandler || iClientWindows.Count() > 0));
       
  1169 	return (iEventHandler || iClientWindows.Count() > 0);
       
  1170 	}
       
  1171 	
       
  1172 
       
  1173 TBool CMediaClientVideoDisplayBody::IsSurfaceCreated() const
       
  1174 	{
       
  1175 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IsSurfaceCreated +++");
       
  1176     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsSurfaceCreated --- return %d", !(iSurfaceId.IsNull()));
       
  1177 	return !(iSurfaceId.IsNull());
       
  1178 	}
       
  1179 		
       
  1180 TInt CMediaClientVideoDisplayBody::DisplayId() const
       
  1181 	{
       
  1182 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::DisplayId +++");
       
  1183     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::DisplayId --- return %d", iDisplayId);
       
  1184 	return iDisplayId;
       
  1185 	}
       
  1186 	
       
  1187 TInt CMediaClientVideoDisplayBody::CompareByDisplay(const TInt* aDisplayId, const CMediaClientVideoDisplayBody& aDisplay)
       
  1188 	{
       
  1189 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CompareByDisplay +++");
       
  1190     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::CompareByDisplay --- return %d", (*aDisplayId - aDisplay.DisplayId()));
       
  1191 	return (*aDisplayId - aDisplay.DisplayId());
       
  1192 	}
       
  1193 		
       
  1194 TInt CMediaClientVideoDisplayBody::Compare(const CMediaClientVideoDisplayBody& aLeft, const CMediaClientVideoDisplayBody& aRight)
       
  1195 	{
       
  1196 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::Compare +++");
       
  1197     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::Compare --- return %d", (aLeft.DisplayId() - aRight.DisplayId()));
       
  1198 	return (aLeft.DisplayId() - aRight.DisplayId());
       
  1199 	}
       
  1200 	
       
  1201 CFbsBitGc::TGraphicsOrientation CMediaClientVideoDisplayBody::ConvertRotation(TVideoRotation aRotation)
       
  1202 	{
       
  1203 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConvertRotation +++");
       
  1204 	
       
  1205 	CFbsBitGc::TGraphicsOrientation orientation;
       
  1206 	
       
  1207 	switch(aRotation)
       
  1208 		{
       
  1209 		case EVideoRotationNone:
       
  1210 		    orientation = CFbsBitGc::EGraphicsOrientationNormal;
       
  1211 		    break;
       
  1212 		case EVideoRotationClockwise90:
       
  1213 		    orientation = CFbsBitGc::EGraphicsOrientationRotated270;
       
  1214 		    break;
       
  1215 		case EVideoRotationClockwise180:
       
  1216 		    orientation = CFbsBitGc::EGraphicsOrientationRotated180;
       
  1217 		    break;
       
  1218 		case EVideoRotationClockwise270:
       
  1219 		    orientation = CFbsBitGc::EGraphicsOrientationRotated90;
       
  1220 		    break;
       
  1221 		default:
       
  1222 			// Should never get to default unless there's been some programming error.
       
  1223 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- Failed due to %d bad aRotation argument", aRotation);
       
  1224 			__ASSERT_DEBUG(FALSE, User::Invariant());
       
  1225 			// Use the normal option otherwise
       
  1226 			orientation = CFbsBitGc::EGraphicsOrientationNormal;
       
  1227 		}
       
  1228     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- return %d", orientation);	
       
  1229     return orientation;
       
  1230 	}
       
  1231 
       
  1232 CMediaClientVideoDisplayBody* CMediaClientVideoDisplayBody::FindDisplayWithWindowL(const RPointerArray<CMediaClientVideoDisplayBody>& aDisplays, const RWindowBase& aWindow)
       
  1233 	{
       
  1234 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::FindDisplayWithWindowL +++");
       
  1235 	TInt count = aDisplays.Count();
       
  1236 	
       
  1237 	for (TInt i = 0; i < count; ++i)
       
  1238 		{
       
  1239 		CMediaClientVideoDisplayBody* display = aDisplays[i];
       
  1240 	
       
  1241 		if (display->iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle) != KErrNotFound)
       
  1242 			{
       
  1243 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::FindDisplayWithWindowL window found at position ", i);
       
  1244 			DEBUG_PRINTF("CMediaClientVideoDisplayBody::FindDisplayWithWindowL ---");
       
  1245 			return display;	
       
  1246 			}
       
  1247 		}
       
  1248 		
       
  1249 	User::Leave(KErrNotFound);
       
  1250 	return NULL;
       
  1251 	}
       
  1252 	
       
  1253 RArray<CMediaClientVideoDisplayBody::TWindowData>& CMediaClientVideoDisplayBody::Windows()
       
  1254 	{
       
  1255 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::Windows +++");
       
  1256 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::Windows ---");
       
  1257 	return iClientWindows;	
       
  1258 	}
       
  1259 
       
  1260 void CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL(TBool aControl)
       
  1261     {
       
  1262     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL +++ aControl=%d", aControl);
       
  1263 
       
  1264     // not supported
       
  1265     if(!iExtDisplaySwitchingSupported)
       
  1266         {
       
  1267         User::Leave(KErrNotSupported);
       
  1268         }
       
  1269     
       
  1270     // need active scheduler installed
       
  1271     if(!CActiveScheduler::Current())
       
  1272         {
       
  1273         User::Leave(KErrNotReady);
       
  1274         }
       
  1275 
       
  1276     if(iClientRequestedExtDisplaySwitching != aControl)
       
  1277         {
       
  1278         iClientRequestedExtDisplaySwitching = aControl;     
       
  1279         SwitchSurface();
       
  1280         }
       
  1281     
       
  1282     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL ---");
       
  1283     }
       
  1284 
       
  1285 void CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected(TExtDisplayConnectionProviderConnType aExtDisplayConnType)
       
  1286 	{
       
  1287 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected +++ aExtDisplayConnType=%d", aExtDisplayConnType);
       
  1288 	
       
  1289 	if(aExtDisplayConnType != iExtDisplayConnType)
       
  1290 	    {
       
  1291         TExtDisplayConnectionProviderConnType prevExtDisplayConnType = iExtDisplayConnType;
       
  1292         iExtDisplayConnType = aExtDisplayConnType;
       
  1293         
       
  1294         if(prevExtDisplayConnType == EExtDisplayConnectionProviderConnTypeDisconnected)
       
  1295             {
       
  1296             // disconnected -> connected  - don't care which type it is
       
  1297             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected disconnected -> connected(type %d)", iExtDisplayConnType);
       
  1298             iExtDisplayConnected = ETrue;
       
  1299             SwitchSurface();
       
  1300             }
       
  1301         else if(iExtDisplayConnType == EExtDisplayConnectionProviderConnTypeDisconnected)
       
  1302             {
       
  1303             // connected -> disconnected  - don't care from which type it is
       
  1304             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected connected(type %d) -> disconnected", prevExtDisplayConnType);
       
  1305             iExtDisplayConnected = EFalse;
       
  1306             SwitchSurface();
       
  1307             }
       
  1308         else
       
  1309             {
       
  1310             // If we get this far then the connection type has changed from "AV Out -> HDMI" or "HDMI -> AV Out"
       
  1311             // Both are likely. "AV Out -> HDMI" occurs if AV Out cable is connected and HDMI cable is then connected.
       
  1312             // "HDMI -> AV Out" occurs if both AV Out and HDMI cables are connected and HDMI cable is then disconnected.
       
  1313             // HDMI is preferred over AV Out.
       
  1314         
       
  1315             // update external display window data
       
  1316             iExtDisplayHandler->UpdateWindow();
       
  1317             TRect externalDisplayRect(TPoint(0, 0), iExtDisplayHandler->DisplaySizeInPixels());
       
  1318             (*iWindowsArrayPtr)[0].iClipRect = externalDisplayRect;
       
  1319             (*iWindowsArrayPtr)[0].iVideoExtent = externalDisplayRect;
       
  1320             TRAPD(err, (*iWindowsArrayPtr)[0].iAutoScaleType = ExtDisplayAutoScaleTypeL());
       
  1321             if(err == KErrNone)
       
  1322                 {
       
  1323                 RemoveBackgroundSurface(ETrue);
       
  1324                 RedrawWindows(iCropRegion);
       
  1325                 }
       
  1326             else
       
  1327                 {
       
  1328                 // Not a lot we can do. Just keep as it is but external display output will be incorrect. 
       
  1329                 DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected ExtDisplayAutoScaleTypeL failed %d", err);
       
  1330                 }
       
  1331             }
       
  1332 	    }
       
  1333 	else
       
  1334         {
       
  1335         DEBUG_PRINTF("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected No change to connection type");
       
  1336         }
       
  1337 	
       
  1338 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected ---");
       
  1339 	}
       
  1340 
       
  1341 void CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client()
       
  1342     {
       
  1343     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client +++");
       
  1344 
       
  1345     iWindowsArrayPtr = &iClientWindows;
       
  1346     iSwitchedToExternalDisplay = EFalse;
       
  1347 
       
  1348     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client ---");
       
  1349     }
       
  1350 
       
  1351 void CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext()
       
  1352     {
       
  1353     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext +++");
       
  1354 
       
  1355     iWindowsArrayPtr = &iExtDisplayWindows;
       
  1356     iSwitchedToExternalDisplay = ETrue;
       
  1357 
       
  1358     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext ---");
       
  1359     }
       
  1360 
       
  1361 void CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL()
       
  1362     {
       
  1363     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL +++");
       
  1364 
       
  1365     CMediaClientExtDisplayHandler* extDisplayHandler = CMediaClientExtDisplayHandler::NewL(iExtDisplayConnectionProvider->ExtDisplayId());
       
  1366     CleanupStack::PushL(extDisplayHandler);
       
  1367     
       
  1368     TWindowData windowData;
       
  1369     windowData.iWindow = extDisplayHandler->Window();
       
  1370     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL - iWindow WsHandle 0x%X", windowData.iWindow->WsHandle());
       
  1371     
       
  1372     TRect externalDisplayRect(TPoint(0, 0), extDisplayHandler->DisplaySizeInPixels());
       
  1373     windowData.iClipRect = externalDisplayRect;
       
  1374     windowData.iVideoExtent = externalDisplayRect;
       
  1375     // windowData.iScaleWidth only required for EAutoScaleNone
       
  1376     // windowData.iScaleWidth only required for EAutoScaleNone
       
  1377     windowData.iRotation = EVideoRotationNone;
       
  1378     windowData.iAutoScaleType = ExtDisplayAutoScaleTypeL();
       
  1379     windowData.iHorizPos = EHorizontalAlignCenter;
       
  1380     windowData.iVertPos = EVerticalAlignCenter;
       
  1381     // windowData.iWindow2 not used        
       
  1382     
       
  1383     iExtDisplayWindows.AppendL(windowData);
       
  1384     CleanupStack::Pop(extDisplayHandler);
       
  1385     iExtDisplayHandler = extDisplayHandler;
       
  1386     
       
  1387     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL ---");
       
  1388     }
       
  1389 
       
  1390 void CMediaClientVideoDisplayBody::RemoveExtDisplayHandler()
       
  1391     {
       
  1392     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayHandler +++");
       
  1393 
       
  1394     delete iExtDisplayHandler;
       
  1395     iExtDisplayHandler = NULL;
       
  1396     iExtDisplayWindows.Reset();
       
  1397 
       
  1398     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayHandler ---");
       
  1399     }
       
  1400 
       
  1401 void CMediaClientVideoDisplayBody::CreateExtDisplayPluginL()
       
  1402     {
       
  1403     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayPluginL +++");
       
  1404     
       
  1405     iExtDisplayConnectionProvider = CExtDisplayConnectionProviderInterface::NewL();
       
  1406     
       
  1407     if(iExtDisplayConnectionProvider)
       
  1408         {
       
  1409         iExtDisplaySwitchingSupported = ETrue;
       
  1410         iExtDisplayConnectionProvider->SetExtDisplayConnectionProviderCallback(*this);
       
  1411         iExtDisplayConnType = iExtDisplayConnectionProvider->ExtDisplayConnType();
       
  1412         iExtDisplayConnected = (iExtDisplayConnType != EExtDisplayConnectionProviderConnTypeDisconnected);
       
  1413         }
       
  1414 
       
  1415     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayPluginL ---");
       
  1416     }
       
  1417 
       
  1418 void CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin()
       
  1419     {
       
  1420     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin +++");
       
  1421     
       
  1422     if(iExtDisplaySwitchingSupported)
       
  1423         {
       
  1424         delete iExtDisplayConnectionProvider;
       
  1425         iExtDisplayConnectionProvider = NULL;
       
  1426         iExtDisplaySwitchingSupported = EFalse;
       
  1427         iExtDisplayConnected = EFalse;
       
  1428         }    
       
  1429     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin ---");
       
  1430     }
       
  1431 
       
  1432 void CMediaClientVideoDisplayBody::MmcweoFocusWindowGroupChanged()
       
  1433     {
       
  1434     DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged +++");
       
  1435     
       
  1436     TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
       
  1437     UpdateFocus();
       
  1438     
       
  1439     if(prevClientWindowIsInFocus != iClientWindowIsInFocus)
       
  1440         {
       
  1441         SwitchSurface();
       
  1442         }
       
  1443     
       
  1444     DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged ---");
       
  1445     }
       
  1446 
       
  1447 TBool CMediaClientVideoDisplayBody::MmcweoIgnoreProcess(TSecureId aId)
       
  1448     {
       
  1449     DEBUG_PRINTF("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess +++");
       
  1450     
       
  1451     TBool ignore = ETrue;
       
  1452     if (iServerClient)
       
  1453         {
       
  1454         ignore = iServerClient->IgnoreProcess(aId);
       
  1455         }
       
  1456     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess --- return %d", ignore);
       
  1457     return ignore;
       
  1458     }
       
  1459 
       
  1460 void CMediaClientVideoDisplayBody::UpdateFocus()
       
  1461     {
       
  1462     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus +++");
       
  1463     
       
  1464     if(!iWsEventObserver)
       
  1465         {
       
  1466         iClientWindowIsInFocus = ETrue;
       
  1467         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Event Observer is NULL");
       
  1468         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---");
       
  1469         return;
       
  1470         }
       
  1471     
       
  1472     TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
       
  1473     
       
  1474     TInt focusGroupId;
       
  1475     if(iWsEventObserver->FocusWindowGroupId(focusGroupId) == KErrNone)
       
  1476         {
       
  1477         iClientWindowIsInFocus = EFalse;
       
  1478         TInt count = iClientWindows.Count();
       
  1479         for(TInt i = 0; i < count; i++)
       
  1480             {
       
  1481             if(iClientWindows[i].iWindow->WindowGroupId() == focusGroupId)
       
  1482                 {
       
  1483                 iClientWindowIsInFocus = ETrue;
       
  1484                 break;
       
  1485                 }
       
  1486             }
       
  1487         }
       
  1488     else
       
  1489         {
       
  1490         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Error retrieving focus WgId from observer");
       
  1491         iClientWindowIsInFocus = ETrue;
       
  1492         }
       
  1493 
       
  1494     if(iServerClient && (prevClientWindowIsInFocus != iClientWindowIsInFocus))
       
  1495         {
       
  1496         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged calling server, focus %d", iClientWindowIsInFocus);
       
  1497         iServerClient->FocusChanged(iClientWindowIsInFocus);
       
  1498         }
       
  1499     
       
  1500     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateFocus Client window in focus %d", iClientWindowIsInFocus);
       
  1501     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---");
       
  1502     }
       
  1503 
       
  1504 void CMediaClientVideoDisplayBody::SwitchSurface()
       
  1505     {
       
  1506     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface +++");
       
  1507 
       
  1508     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface SurfaceCreated %d", IsSurfaceCreated());
       
  1509     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client window count %d", iClientWindows.Count());
       
  1510     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Requested Ext Display Switching %d", iClientRequestedExtDisplaySwitching);
       
  1511     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Window in Focus %d", iClientWindowIsInFocus);
       
  1512     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface External Display Connected %d", iExtDisplayConnected);
       
  1513 
       
  1514     if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching &&
       
  1515             iClientWindowIsInFocus && iExtDisplayConnected)
       
  1516         {
       
  1517         TRAPD(err, CreateExtDisplayHandlerL());
       
  1518         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface CreateExtDisplayHandlerL error %d", err);
       
  1519         if(err == KErrNone)
       
  1520             {
       
  1521             SetWindowArrayPtr2Ext();
       
  1522             RedrawWindows(iCropRegion); 
       
  1523             
       
  1524 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
  1525             // Hide surface so that video is not seen on client window
       
  1526             HideAllClientWindows();
       
  1527 #else
       
  1528             // Surface removed from window
       
  1529             SetWindowArrayPtr2Client();
       
  1530             RemoveBackgroundSurface(ETrue);
       
  1531             SetWindowArrayPtr2Ext();
       
  1532 #endif
       
  1533             }
       
  1534         }
       
  1535     else if(iSwitchedToExternalDisplay)
       
  1536         {
       
  1537         // Set background surface for clientwindows before removing from external display window.
       
  1538         SetWindowArrayPtr2Client();
       
  1539         // RedrawWindows handles both the case where the surface was removed from client window and 
       
  1540         // also the case where the surface was hidden from client window
       
  1541         RedrawWindows(iCropRegion);
       
  1542         SetWindowArrayPtr2Ext();
       
  1543         RemoveBackgroundSurface(ETrue);
       
  1544         RemoveExtDisplayHandler();
       
  1545         SetWindowArrayPtr2Client();
       
  1546         }
       
  1547 
       
  1548     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface ---");
       
  1549     }
       
  1550 
       
  1551 TBool CMediaClientVideoDisplayBody::IsRotationValid(TVideoRotation aVideoRotation)
       
  1552 	{
       
  1553 	if (aVideoRotation == EVideoRotationNone ||
       
  1554 	    aVideoRotation == EVideoRotationClockwise90 ||
       
  1555 		aVideoRotation == EVideoRotationClockwise180 ||
       
  1556 		aVideoRotation == EVideoRotationClockwise270)
       
  1557 		{
       
  1558 		return ETrue;
       
  1559 		}
       
  1560 
       
  1561 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsRotationValid - Rotation %d not valid", aVideoRotation);
       
  1562 	return EFalse;
       
  1563 	}
       
  1564 
       
  1565 TBool CMediaClientVideoDisplayBody::IsAutoScaleTypeValid(TAutoScaleType aAutoScaleType)
       
  1566 	{
       
  1567 	if (aAutoScaleType == EAutoScaleNone ||
       
  1568 	    aAutoScaleType == EAutoScaleBestFit ||
       
  1569 	    aAutoScaleType == EAutoScaleClip ||
       
  1570 	    aAutoScaleType == EAutoScaleStretch)
       
  1571 		{
       
  1572 		return ETrue;
       
  1573 		}
       
  1574 
       
  1575 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsAutoScaleTypeValid - Auto scale %d not valid", aAutoScaleType);
       
  1576 	return EFalse;
       
  1577 	}
       
  1578 
       
  1579 /**
       
  1580 Check whether a change in the surface crop rectangle would mean that the surface viewport calculated in SetBackgroundSurface would change.
       
  1581 The surface viewport is the intersection of the surface crop rectangle and the client crop region
       
  1582 */
       
  1583 TBool CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw(TRect aOldSurfaceCropRect, TRect aNewSurfaceCropRect, TRect aClientCropRegion)
       
  1584 	{
       
  1585 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw +++");
       
  1586 	
       
  1587 	// If aClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations.
       
  1588 	// This means that only aOldSurfaceCropRect is being used to decide which part of the video is displayed.
       
  1589 	// By setting aClientCropRect to the same as aOldSurfaceCropRect we ensure that only aOldSurfaceCropRect is
       
  1590 	// used in the subsequent intersection area checks.
       
  1591 	if (aClientCropRegion.IsEmpty())
       
  1592 		{
       
  1593 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw - Client crop region is empty");		
       
  1594 		aClientCropRegion = aOldSurfaceCropRect;
       
  1595 		}
       
  1596 
       
  1597 	TBool ret = IntersectionAreaChanged(aOldSurfaceCropRect, aNewSurfaceCropRect, aClientCropRegion);
       
  1598 
       
  1599 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw --- ret = %d", ret);
       
  1600 
       
  1601 	return ret;
       
  1602 	}
       
  1603 
       
  1604 /**
       
  1605 Check whether a change in the client crop region would mean that the surface viewport calculated in SetBackgroundSurface would change.
       
  1606 The surface viewport is the intersection of the surface crop rectangle and the client crop region
       
  1607 */
       
  1608 TBool CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw(TRect aOldClientCropRegion, TRect aNewClientCropRegion, TRect aSurfaceCropRect)
       
  1609 	{
       
  1610 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw +++");
       
  1611 
       
  1612 	// If aOldClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations.
       
  1613 	// This means that only aSurfaceCropRect is being used to decide which part of the video is displayed. By
       
  1614 	// setting aOldClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is
       
  1615 	// used in the subsequent intersection area checks.
       
  1616 	if (aOldClientCropRegion.IsEmpty())
       
  1617 		{
       
  1618 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - Old client crop region is empty");
       
  1619 		aOldClientCropRegion = aSurfaceCropRect;
       
  1620 		}
       
  1621 
       
  1622 	// If aNewClientCropRegion is empty then it will not be used in the SetBackgroundSurface calculations.
       
  1623 	// This means that only aSurfaceCropRect will impact which part of the video is displayed. By
       
  1624 	// setting aNewClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is
       
  1625 	// used in the subsequent intersection area checks.
       
  1626 	if (aNewClientCropRegion.IsEmpty())
       
  1627 		{
       
  1628 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - New client crop region is empty");
       
  1629 		aNewClientCropRegion = aSurfaceCropRect;
       
  1630 		}
       
  1631 
       
  1632 	TBool ret = IntersectionAreaChanged(aOldClientCropRegion, aNewClientCropRegion, aSurfaceCropRect);
       
  1633 
       
  1634 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw --- ret = %d", ret);
       
  1635 
       
  1636 	return ret;
       
  1637 	}
       
  1638 
       
  1639 /**
       
  1640 Check whether the change in size of a rectangle means its intersection with another rectangle has changed.
       
  1641 This is used to check whether changes in things like the surface crop rectangle, client crop region, and window clip rectangle, would mean
       
  1642 the area of video displayed would change.
       
  1643 */
       
  1644 TBool CMediaClientVideoDisplayBody::IntersectionAreaChanged(TRect aOldRect, TRect aNewRect, TRect aOtherRect)
       
  1645 	{
       
  1646 	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOldRect %d,%d - %d,%d", aOldRect.iTl.iX, aOldRect.iTl.iY, aOldRect.iBr.iX, aOldRect.iBr.iY);
       
  1647 	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aNewRect %d,%d - %d,%d", aNewRect.iTl.iX, aNewRect.iTl.iY, aNewRect.iBr.iX, aNewRect.iBr.iY);
       
  1648 	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOtherRect %d,%d - %d,%d", aOtherRect.iTl.iX, aOtherRect.iTl.iY, aOtherRect.iBr.iX, aOtherRect.iBr.iY);
       
  1649 
       
  1650 	aOldRect.Intersection(aOtherRect);
       
  1651 	aNewRect.Intersection(aOtherRect);
       
  1652 
       
  1653 	if (aOldRect != aNewRect)
       
  1654 		{
       
  1655 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged --- Intersection area has changed");
       
  1656 		return ETrue;
       
  1657 		}
       
  1658 
       
  1659 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged --- Intersection area has not changed");
       
  1660 	return EFalse;
       
  1661 	}
       
  1662 
       
  1663 /**
       
  1664 * This function calculates the delta width and delta height for AV out when the TV-Out setting is set to "widescreen".
       
  1665 *
       
  1666 * AV out has fixed resolution whether TV-Out is set to "normal" or "widescreen". The TV-Out setting indicates
       
  1667 * that the video should be scaled so that when displayed on a corresponding TV the aspect looks correct.
       
  1668 * 
       
  1669 * When displaying video on a widescreen TV through AV out, because the resolution is the same the TV stretches
       
  1670 * the video horizontally. When displaying on a normal TV no stretching takes place.
       
  1671 * 
       
  1672 * For "normal" TAutoScaleType::EAutoScaleClip is used.
       
  1673 * 
       
  1674 * For "widescreen" this function calculates the width delta and height delta required so that when the video is stretched
       
  1675 * the aspect looks correct on a widescreen TV.
       
  1676 * 
       
  1677 * This function must only be called when autoscale is set to TAutoScaleType::EAutoScaleStretch and an external display is
       
  1678 * connected.
       
  1679 **/
       
  1680 void CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay(TReal32 aViewportAspect, const TRect& aVideoExtent, TInt& aDeltaHeight, TInt& aDeltaWidth)
       
  1681     {
       
  1682     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay +++");
       
  1683     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aViewportAspect %f", aViewportAspect);
       
  1684     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
       
  1685     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aDeltaHeight %d", aDeltaHeight);
       
  1686     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aDeltaWidth %d", aDeltaWidth);
       
  1687 
       
  1688     aDeltaWidth = 0;
       
  1689     aDeltaHeight = 0;
       
  1690     
       
  1691     TReal32 wideScreenAspect = (TReal32)16 / (TReal32)9;
       
  1692     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay wideScreenAspect %f", wideScreenAspect);
       
  1693 
       
  1694     if(aViewportAspect == wideScreenAspect)
       
  1695         {
       
  1696         // no need to calculate
       
  1697         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - Viewport Aspect equals wideScreenAspect");
       
  1698         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - width delta and height delta not changed");
       
  1699         }
       
  1700     else if(aViewportAspect < wideScreenAspect)
       
  1701         {
       
  1702         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - Viewport Aspect is less than wideScreenAspect");
       
  1703         
       
  1704         // calculate video width for viewport that when stretched looks ok on widescreen
       
  1705         TReal32 correctedWidth = (TReal32)aVideoExtent.Width() * aViewportAspect / wideScreenAspect;
       
  1706         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay corrected viewport width %f", correctedWidth);
       
  1707         
       
  1708         aDeltaWidth = correctedWidth - aVideoExtent.Width();
       
  1709         }
       
  1710     else // aViewportAspect > wideScreenAspect
       
  1711         {
       
  1712         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - Viewport Aspect is greater than wideScreenAspect");
       
  1713 
       
  1714         // calculate video height for viewport that when stretched looks ok on widescreen
       
  1715         TReal32 correctedHeight = (TReal32)aVideoExtent.Height() * wideScreenAspect / aViewportAspect;
       
  1716         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay corrected viewport height %f", correctedHeight);
       
  1717         
       
  1718         aDeltaHeight = aVideoExtent.Height() - correctedHeight;
       
  1719         }        
       
  1720     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay --- aDeltaHeight %d", aDeltaHeight);
       
  1721     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay --- aDeltaWidth %d", aDeltaWidth);
       
  1722     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay ---");
       
  1723     }
       
  1724 
       
  1725 TBool CMediaClientVideoDisplayBody::IsWideScreenL()
       
  1726     {
       
  1727     DEBUG_PRINTF("CMediaClientVideoDisplayBody::IsWideScreenL +++");
       
  1728     
       
  1729     CRepository* repo = CRepository::NewLC(KCRUidTvoutSettings);
       
  1730     TInt value;
       
  1731     User::LeaveIfError(repo->Get(KSettingsTvAspectRatio, value));
       
  1732 
       
  1733     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsWideScreenL Tv Apect Ratio set to %d, 0=4x3 1=16x9", value);
       
  1734 
       
  1735     CleanupStack::PopAndDestroy(repo);
       
  1736     
       
  1737     TBool ret = value > 0;
       
  1738     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsWideScreenL --- return %d", ret);
       
  1739     return ret;
       
  1740     }
       
  1741 
       
  1742 TAutoScaleType CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL()
       
  1743     {
       
  1744     DEBUG_PRINTF("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL +++");
       
  1745     
       
  1746     // EExtDisplayConnectionProviderConnTypeHdmi - EAutoScaleBestFit
       
  1747     // EExtDisplayConnectionProviderConnTypeAnalog / normal - EAutoScaleBestFit
       
  1748     // EExtDisplayConnectionProviderConnTypeAnalog / widescreen - EAutoScaleStretch
       
  1749     
       
  1750     TAutoScaleType autoScaleType;
       
  1751     if((iExtDisplayConnType == EExtDisplayConnectionProviderConnTypeAnalog) && IsWideScreenL())
       
  1752         {
       
  1753         DEBUG_PRINTF("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL External display scale type EAutoScaleStretch");
       
  1754         autoScaleType = EAutoScaleStretch;
       
  1755         }
       
  1756     else
       
  1757         {
       
  1758         DEBUG_PRINTF("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL External display scale type EAutoScaleBestFit");
       
  1759         autoScaleType = EAutoScaleBestFit;
       
  1760         }
       
  1761     
       
  1762     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL --- return %d", autoScaleType);
       
  1763     return autoScaleType;
       
  1764     }
       
  1765 
       
  1766 #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
       
  1767 
       
  1768 void CMediaClientVideoDisplayBody::HideAllClientWindows()
       
  1769     {
       
  1770     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideAllClientWindows +++");
       
  1771 
       
  1772     TInt count = iClientWindows.Count();
       
  1773     for (TInt i = 0; i < count; ++i)
       
  1774         {
       
  1775         // ignore error - cannot be handled
       
  1776         HideWindow(iClientWindows[i].iWindow);
       
  1777         }
       
  1778     
       
  1779     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideAllClientWindows ---");
       
  1780     }
       
  1781 
       
  1782 TInt CMediaClientVideoDisplayBody::HideWindow(RWindowBase* aWindow)
       
  1783     {
       
  1784     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideWindow +++");
       
  1785 
       
  1786     TSurfaceConfiguration config;
       
  1787     TInt err = aWindow->GetBackgroundSurface(config);
       
  1788     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::HideWindow GetBackgroundSurface error %d", err);
       
  1789     
       
  1790 #ifdef _DEBUG
       
  1791     TSurfaceId surface;
       
  1792     config.GetSurfaceId(surface);
       
  1793     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::HideWindow - Retrieved Surface %08x:%08x:%08x:%08x", 
       
  1794             surface.iInternal[3], surface.iInternal[2], surface.iInternal[1], surface.iInternal[0]);
       
  1795 #endif
       
  1796     
       
  1797     if (err == KErrNone)
       
  1798         {
       
  1799         config.SetExtent(TRect(KHiddenExtentA, KHiddenExtentA, KHiddenExtentB, KHiddenExtentB));
       
  1800         err = aWindow->SetBackgroundSurface(config, ETrue);
       
  1801         // Make sure all window rendering has completed before proceeding
       
  1802         RWsSession* ws = aWindow->Session();
       
  1803         if (ws)
       
  1804            {
       
  1805            ws->Finish();
       
  1806            }
       
  1807         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::HideWindow SetBackgroundSurface error %d", err);
       
  1808         }
       
  1809     
       
  1810     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideWindow ---");
       
  1811     return err;
       
  1812     }
       
  1813 
       
  1814 void CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnAllClientWindows()
       
  1815     {
       
  1816     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnAllClientWindows +++");
       
  1817 
       
  1818     TInt count = iClientWindows.Count();
       
  1819     for (TInt i = 0; i < count; ++i)
       
  1820         {
       
  1821         // ignore error - cannot be handled
       
  1822         SetHiddenBackgroundSurfaceOnClientWindow(iClientWindows[i]);
       
  1823         }
       
  1824     
       
  1825     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnAllClientWindows ---");
       
  1826     }
       
  1827 
       
  1828 
       
  1829 TInt CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow(TWindowData& aWindowData)
       
  1830     {
       
  1831     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow +++");    
       
  1832     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow - iSurfaceId %08x:%08x:%08x:%08x",
       
  1833                 iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
       
  1834     
       
  1835     TSurfaceConfiguration config;
       
  1836     config.SetExtent(TRect(KHiddenExtentA, KHiddenExtentA, KHiddenExtentB, KHiddenExtentB));   
       
  1837     config.SetSurfaceId(iSurfaceId);
       
  1838     TInt err = aWindowData.iWindow->SetBackgroundSurface(config, ETrue);
       
  1839     
       
  1840     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow ---, return %d", err);
       
  1841     return err;
       
  1842     }
       
  1843 #endif