sl@0: // Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #include "mediaclientvideodisplaybody.h"
sl@0: #include "mediaclientvideotrace.h"
sl@0: #include "mediaclientpolicyserverclient.h"
sl@0: #include <surfaceeventhandler.h>
sl@0: #include <mmf/plugin/mmfmediaclientextdisplayinterface.hrh>
sl@0: #include <e32cmn.h>
sl@0: #include <ecom/ecom.h>
sl@0: #include <centralrepository.h>
sl@0: 
sl@0: const TUid KCRUidTvoutSettings = {0x1020730B};
sl@0: const TUint32 KSettingsTvAspectRatio = 0x00000001;
sl@0: 
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0: // make sure that off screen is bottom right and not top left. This makes it more efficient for GCE backend
sl@0: // to render
sl@0: const TInt KHiddenExtentA = 2000; // rect Ax and Ay co-ordinate used to set extent off screen
sl@0: const TInt KHiddenExtentB = 2001; // rect Bx and By co-ordinate used to set extent off screen
sl@0: #endif
sl@0: 
sl@0: CMediaClientVideoDisplayBody* CMediaClientVideoDisplayBody::NewL(TInt aDisplayId, TBool aExtDisplaySwitchingControl)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aDisplayId %d", aDisplayId);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aExtDisplaySwitchingControl %d", aExtDisplaySwitchingControl);
sl@0:     
sl@0:     CMediaClientVideoDisplayBody* self = new (ELeave) CMediaClientVideoDisplayBody(aDisplayId);
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aExtDisplaySwitchingControl);
sl@0: 	CleanupStack::Pop(self);
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL ---");
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: CMediaClientVideoDisplayBody* CMediaClientVideoDisplayBody::NewL(TInt aDisplayId, const TSurfaceId& aSurfaceId,
sl@0: 		const TRect& aCropRect, TVideoAspectRatio aAspectRatio, TBool aExtDisplaySwitchingControl)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL +++");
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aDisplayId %d", aDisplayId);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::NewL - aSurfaceId %08x:%08x:%08x:%08x", aSurfaceId.iInternal[3], aSurfaceId.iInternal[2], aSurfaceId.iInternal[1], aSurfaceId.iInternal[0]);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::NewL - aCropRect %d,%d - %d,%d", aCropRect.iTl.iX, aCropRect.iTl.iY, aCropRect.iBr.iX, aCropRect.iBr.iY);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::NewL - aAspectRatio %d/%d", aAspectRatio.iNumerator, aAspectRatio.iDenominator);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::NewL - aExtDisplaySwitchingControl %d", aExtDisplaySwitchingControl);
sl@0: 
sl@0: 	if(aSurfaceId.IsNull())
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 	CMediaClientVideoDisplayBody* self = new(ELeave) CMediaClientVideoDisplayBody(aDisplayId, aSurfaceId, aCropRect, aAspectRatio);
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aExtDisplaySwitchingControl);
sl@0: 	CleanupStack::Pop();
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::NewL ---");
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::ConstructL(TBool aExtDisplaySwitchingControl)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL +++");
sl@0: 
sl@0: 	SetWindowArrayPtr2Client();
sl@0: 
sl@0: 	// External display switching and wserv events are only possible if there is
sl@0: 	// an active scheduler in client thread
sl@0: 	if(CActiveScheduler::Current())
sl@0: 	    {
sl@0:         CreateExtDisplayPluginL();
sl@0:         iWsEventObserver = CMediaClientWsEventObserver::NewL(*this);
sl@0: 
sl@0:         iServerClient = CMediaClientPolicyServerClient::NewL();
sl@0:         if(iServerClient->Connect() != KErrNone)
sl@0:             {
sl@0:             delete iServerClient;
sl@0:             iServerClient = NULL;
sl@0:             }
sl@0:         
sl@0:         if(IsSurfaceCreated() && iServerClient)
sl@0:             {
sl@0:             iServerClient->SetSurface(iSurfaceId);
sl@0:             }
sl@0:         
sl@0:         // Try and enable display switching by default. If this leaves then do so quietly.
sl@0:         // Either the client has no scheduler installed or the device does not support external
sl@0:         // switching (i.e. no plugin was found) 
sl@0:         TRAPD(err, SetExternalDisplaySwitchingL(aExtDisplaySwitchingControl));
sl@0:         err = err; // remove compile warning
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConstructL SetExternalDisplaySwitchingL returned with %d", err);
sl@0: 	    }
sl@0: 	else
sl@0: 	    {
sl@0: 	    DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL No CActiveScheduler - ext display and focus features disabled ");
sl@0: 	    }
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL ---");
sl@0: 	}
sl@0: 
sl@0: CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody(TInt aDisplayId, const TSurfaceId& aSurfaceId,
sl@0: 		const TRect& aCropRect, TVideoAspectRatio aAspectRatio) :
sl@0: 	iDisplayId(aDisplayId),
sl@0: 	iSurfaceId(aSurfaceId),
sl@0: 	iCropRect(aCropRect),
sl@0: 	iAspectRatio(aAspectRatio)
sl@0: 	{	
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody +++");
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody ---");
sl@0: 	}
sl@0: 
sl@0: CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody(TInt aDisplayId) :
sl@0: 	iDisplayId(aDisplayId)
sl@0: 	{	
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody +++");
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CMediaClientVideoDisplayBody ---");
sl@0: 	}
sl@0: 
sl@0: CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody()
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody +++");
sl@0: 
sl@0: 	// remove for whichever array is current
sl@0: 	RemoveBackgroundSurface(ETrue);
sl@0: 
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0:     if(iSwitchedToExternalDisplay)
sl@0:         {
sl@0:         SetWindowArrayPtr2Client();
sl@0:         RemoveBackgroundSurface(ETrue);
sl@0:         }
sl@0: #endif
sl@0: 
sl@0: 	iClientWindows.Close();	
sl@0:     iExtDisplayWindows.Close(); 
sl@0: 
sl@0: 	delete iExtDisplayHandler;
sl@0: 	RemoveExtDisplayPlugin();
sl@0: 	REComSession::FinalClose();
sl@0: 	
sl@0:     delete iWsEventObserver;
sl@0: 
sl@0:     delete iServerClient;
sl@0:     
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody ---");
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::AddDisplayL(MMMFSurfaceEventHandler& aEventHandler)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayL +++");
sl@0: 	if (iEventHandler)
sl@0: 		{
sl@0: 		User::Leave(KErrInUse);
sl@0: 		}
sl@0: 		
sl@0: 	iEventHandler = &aEventHandler;
sl@0: 	
sl@0: 	if (IsSurfaceCreated())
sl@0: 		{
sl@0: 		iEventHandler->MmsehSurfaceCreated(iDisplayId, iSurfaceId, iCropRect, iAspectRatio);
sl@0: 		}
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayL ---");
sl@0: 	}
sl@0: 	
sl@0: void CMediaClientVideoDisplayBody::AddDisplayWindowL(const RWindowBase* aWindow, const TRect& aClipRect, const TRect& aCropRegion, const TRect& aVideoExtent, 
sl@0: 															TReal32 aScaleWidth, TReal32 aScaleHeight, TVideoRotation aRotation, 
sl@0: 															TAutoScaleType aAutoScaleType, TInt aHorizPos, TInt aVertPos, RWindow* aWindow2)
sl@0: 	{	
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayWindowL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aWindow WsHandle 0x%X", aWindow->WsHandle());
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aClipRect %d,%d - %d,%d", aClipRect.iTl.iX, aClipRect.iTl.iY, aClipRect.iBr.iX, aClipRect.iBr.iY);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::AddDisplayWindowL - aScaleWidth %f, aScaleHeight %f", aScaleWidth, aScaleHeight);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aRotation %d", aRotation);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aAutoScaleType %d", aAutoScaleType);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::AddDisplayWindowL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
sl@0: 
sl@0: 	if (!IsRotationValid(aRotation))
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0: 	if (!IsAutoScaleTypeValid(aAutoScaleType))
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0: 	TInt pos = iClientWindows.Find(aWindow->WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	
sl@0: 	if (pos != KErrNotFound)
sl@0: 		{
sl@0: 		User::Leave(KErrInUse);
sl@0: 		}
sl@0: 	
sl@0: 	TWindowData winData(aWindow, aClipRect, aVideoExtent, aScaleWidth, aScaleHeight, aRotation, aAutoScaleType, aHorizPos, aVertPos, aWindow2);
sl@0: 	iClientWindows.AppendL(winData);
sl@0: 	
sl@0: 	iCropRegion = aCropRegion;
sl@0: 	
sl@0: 	TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
sl@0:     UpdateFocus();
sl@0: 	
sl@0: 	if (IsSurfaceCreated())
sl@0: 		{
sl@0:         // if first window was just added OR the new window has moved us from out of focus to in focus
sl@0:         if(((iClientWindows.Count() == 1) || !prevClientWindowIsInFocus) && iClientRequestedExtDisplaySwitching &&
sl@0:                 iClientWindowIsInFocus && iExtDisplayConnected)
sl@0:             {
sl@0:             TRAPD(err, CreateExtDisplayHandlerL());
sl@0:             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL CreateExtDisplayHandlerL error %d", err);
sl@0:             if(err == KErrNone)
sl@0:                 {
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0:                 // attach surface to client window and hide
sl@0:                 // ignore error - no handling required
sl@0:                 SetHiddenBackgroundSurfaceOnClientWindow(winData);
sl@0: #endif                
sl@0:                 // handle external display
sl@0:                 SetWindowArrayPtr2Ext();
sl@0:                 User::LeaveIfError(RedrawWindows(aCropRegion));
sl@0:                 }
sl@0:             }
sl@0:         
sl@0:         if(!iSwitchedToExternalDisplay)
sl@0:             {
sl@0:             User::LeaveIfError(SetBackgroundSurface(winData, aCropRegion));
sl@0:             }
sl@0: 		}
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayWindowL ---");
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::UpdateDisplayWindowL(const RWindowBase* aWindow, const TRect& aClipRect, const TRect& aCropRegion, const TRect& aVideoExtent, 
sl@0:                                                             TReal32 aScaleWidth, TReal32 aScaleHeight, TVideoRotation aRotation, 
sl@0:                                                             TAutoScaleType aAutoScaleType, TInt aHorizPos, TInt aVertPos, RWindow* aWindow2)
sl@0:     {   
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDisplayWindowL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aWindow WsHandle 0x%X", aWindow->WsHandle());
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aClipRect %d,%d - %d,%d", aClipRect.iTl.iX, aClipRect.iTl.iY, aClipRect.iBr.iX, aClipRect.iBr.iY);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aScaleWidth %f, aScaleHeight %f", aScaleWidth, aScaleHeight);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aRotation %d", aRotation);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aAutoScaleType %d", aAutoScaleType);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::UpdateDisplayWindowL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
sl@0: 
sl@0:     if (!IsRotationValid(aRotation))
sl@0:         {
sl@0:         User::Leave(KErrArgument);
sl@0:         }
sl@0: 
sl@0:     if (!IsAutoScaleTypeValid(aAutoScaleType))
sl@0:         {
sl@0:         User::Leave(KErrArgument);
sl@0:         }
sl@0: 
sl@0:     TInt pos = iClientWindows.Find(aWindow->WsHandle(), TWindowData::CompareByWsHandle);
sl@0:     User::LeaveIfError(pos);
sl@0:     iClientWindows.Remove(pos);
sl@0:     
sl@0:     TWindowData winData(aWindow, aClipRect, aVideoExtent, aScaleWidth, aScaleHeight, aRotation, aAutoScaleType, aHorizPos, aVertPos, aWindow2);
sl@0:     iClientWindows.AppendL(winData);
sl@0:     
sl@0:     TRect prevCropRegion = iCropRegion;
sl@0:     iCropRegion = aCropRegion;
sl@0:     
sl@0:     if (IsSurfaceCreated())
sl@0:         {
sl@0:         if(ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
sl@0:             {
sl@0:             // all windows need to be redrawn
sl@0:             User::LeaveIfError(RedrawWindows(aCropRegion));
sl@0:             }
sl@0:         else
sl@0:             {
sl@0:             // only redraw affected window as other window data may have changed
sl@0:             if(!iSwitchedToExternalDisplay)
sl@0:                 {
sl@0:                 User::LeaveIfError(SetBackgroundSurface(winData, aCropRegion));
sl@0:                 }
sl@0:             }
sl@0:         }
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDisplayWindowL ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::RemoveDisplay()
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplay +++");
sl@0: 	iEventHandler = NULL;
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplay ---");
sl@0: 	}	
sl@0: 
sl@0: TInt CMediaClientVideoDisplayBody::RemoveDisplayWindow(const RWindowBase& aWindow)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplayWindow +++");
sl@0: 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	
sl@0: 	if (pos >= 0)
sl@0: 	    {
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0:         if(IsSurfaceCreated())
sl@0: #else
sl@0: 	    if(IsSurfaceCreated() && !iSwitchedToExternalDisplay)
sl@0: #endif
sl@0: 	        {
sl@0:             iClientWindows[pos].iWindow->RemoveBackgroundSurface(ETrue);
sl@0:             // Make sure all window rendering has completed before proceeding
sl@0:             RWsSession* ws = iClientWindows[pos].iWindow->Session();
sl@0:             if (ws)
sl@0:                 {
sl@0:                 ws->Finish();
sl@0:                 }
sl@0:             }
sl@0: 
sl@0: 	    iClientWindows.Remove(pos);
sl@0: 	    
sl@0: 	    TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
sl@0:         UpdateFocus();
sl@0: 
sl@0:         // if only window was just removed OR removal has moved us from in focus to out of focus
sl@0:         if((iClientWindows.Count() == 0 || prevClientWindowIsInFocus) && iSwitchedToExternalDisplay &&
sl@0:                 !iClientWindowIsInFocus)
sl@0:             {
sl@0:             RemoveBackgroundSurface(ETrue);
sl@0:             SetWindowArrayPtr2Client();
sl@0:             RemoveExtDisplayHandler();
sl@0:             RedrawWindows(iCropRegion);
sl@0:             }
sl@0: 		}
sl@0: 	
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplayWindow ---");
sl@0: 	return pos;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: TInt CMediaClientVideoDisplayBody::SurfaceCreated(const TSurfaceId& aSurfaceId, const TRect& aCropRect, TVideoAspectRatio aAspectRatio, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCreated +++");
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aSurfaceId %08x:%08x:%08x:%08x", aSurfaceId.iInternal[3], aSurfaceId.iInternal[2], aSurfaceId.iInternal[1], aSurfaceId.iInternal[0]);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aCropRect %d,%d - %d,%d", aCropRect.iTl.iX, aCropRect.iTl.iY, aCropRect.iBr.iX, aCropRect.iBr.iY);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SurfaceCreated - aAspectRatio %d/%d", aAspectRatio.iNumerator, aAspectRatio.iDenominator);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0:     TBool emitEvent = EFalse;
sl@0: 	if((iSurfaceId != aSurfaceId) && (!aSurfaceId.IsNull()))
sl@0: 		{
sl@0: 		emitEvent = ETrue;
sl@0: 		}
sl@0: 
sl@0: 	iSurfaceId = aSurfaceId;
sl@0: 	iCropRect = aCropRect;
sl@0: 	iAspectRatio = aAspectRatio;
sl@0: 	iCropRegion = aCropRegion;
sl@0: 	
sl@0: 	if(iServerClient)
sl@0: 	    {
sl@0:         iServerClient->SetSurface(iSurfaceId);
sl@0: 	    }
sl@0: 	
sl@0: 	if (emitEvent && iEventHandler)
sl@0: 		{
sl@0: 		iEventHandler->MmsehSurfaceCreated(iDisplayId, iSurfaceId, iCropRect, iAspectRatio);
sl@0: 		}
sl@0: 
sl@0: 	TInt err = KErrNone;
sl@0:     if((iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching && iClientWindowIsInFocus)
sl@0:         {
sl@0:         if(iExtDisplayConnected && !iExtDisplayHandler)
sl@0:             {
sl@0:             TRAP(err, CreateExtDisplayHandlerL());
sl@0:             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCreated CreateExtDisplayHandlerL error %d", err);
sl@0:             if(err == KErrNone)
sl@0:                 {
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0:                 SetHiddenBackgroundSurfaceOnAllClientWindows();
sl@0: #endif          
sl@0:                 SetWindowArrayPtr2Ext();
sl@0:                 }
sl@0:             }
sl@0:         }
sl@0:     
sl@0:     err = RedrawWindows(aCropRegion);
sl@0:     
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCreated --- Return error %d", err);
sl@0: 	return err;
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::RemoveBackgroundSurface(TBool aTriggerRedraw)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveBackgroundSurface +++");
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::RemoveBackgroundSurface - iSurfaceId %08x:%08x:%08x:%08x", iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
sl@0: 
sl@0: 	if (IsSurfaceCreated())
sl@0: 		{
sl@0: 		RWsSession* ws = NULL;
sl@0: 		TInt count = iWindowsArrayPtr->Count();
sl@0: 	
sl@0: 		for (TInt i = 0; i < count; ++i)
sl@0: 			{
sl@0: 			(*iWindowsArrayPtr)[i].iWindow->RemoveBackgroundSurface(aTriggerRedraw);
sl@0:             // Make sure all window rendering has completed before proceeding
sl@0:             ws = (*iWindowsArrayPtr)[i].iWindow->Session();
sl@0:             if (ws)
sl@0:                 {
sl@0:                 ws->Finish();
sl@0:                 }
sl@0: 			}
sl@0: 		}
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveBackgroundSurface ---");
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::RemoveSurface(TBool aControllerEvent)
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveSurface +++");
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::RemoveSurface - iSurfaceId %08x:%08x:%08x:%08x", iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
sl@0: 
sl@0:     if (IsSurfaceCreated())
sl@0:         {
sl@0:         RemoveBackgroundSurface(ETrue);
sl@0: 
sl@0:         if (iEventHandler  && aControllerEvent)
sl@0:             {
sl@0:             iEventHandler->MmsehRemoveSurface(iSurfaceId);
sl@0:             }
sl@0: 
sl@0:         if(iSwitchedToExternalDisplay)
sl@0:             {
sl@0:             SetWindowArrayPtr2Client();
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0:             RemoveBackgroundSurface(ETrue);
sl@0: #endif
sl@0:             RemoveExtDisplayHandler();
sl@0:             }
sl@0:         iSurfaceId = TSurfaceId::CreateNullId();
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveSurface ---");
sl@0:     }
sl@0: 
sl@0: TInt CMediaClientVideoDisplayBody::SurfaceParametersChanged(const TSurfaceId& aSurfaceId, const TRect& aCropRect, TVideoAspectRatio aAspectRatio)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged +++");
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aSurfaceId %08x:%08x:%08x:%08x", aSurfaceId.iInternal[3], aSurfaceId.iInternal[2], aSurfaceId.iInternal[1], aSurfaceId.iInternal[0]);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SurfaceCreated - aCropRect %d,%d - %d,%d", aCropRect.iTl.iX, aCropRect.iTl.iY, aCropRect.iBr.iX, aCropRect.iBr.iY);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SurfaceCreated - aAspectRatio %d/%d", aAspectRatio.iNumerator, aAspectRatio.iDenominator);
sl@0: 
sl@0:     if (!IsSurfaceCreated())
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrNotSupproted");
sl@0: 		return KErrNotSupported;
sl@0: 		}
sl@0: 
sl@0: 	if (iSurfaceId != aSurfaceId)
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrInUse");
sl@0: 		return KErrInUse;
sl@0: 		}
sl@0: 
sl@0: 	if (iEventHandler)
sl@0: 		{
sl@0: 		iEventHandler->MmsehSurfaceParametersChanged(iSurfaceId, aCropRect, aAspectRatio);
sl@0: 		}
sl@0: 
sl@0: 	TInt error = KErrNone;
sl@0: 	if (iCropRect != aCropRect || iAspectRatio != aAspectRatio)
sl@0: 		{
sl@0: 		// We only need to redraw if the aspect ratio has changed, or the area of the video to
sl@0: 		// display (i.e the intersection of client crop region and surface crop rectangle) has changed.
sl@0: 		TBool redraw = EFalse;
sl@0: 		if (iAspectRatio != aAspectRatio || SurfaceCropRectChangeRequiresRedraw(iCropRect, aCropRect, iCropRegion))
sl@0: 			{
sl@0: 			redraw = ETrue;
sl@0: 			}
sl@0: 
sl@0: 		iCropRect = aCropRect;
sl@0: 		iAspectRatio = aAspectRatio;
sl@0: 
sl@0: 		if (redraw)
sl@0: 			{
sl@0: 			error = RedrawWindows(iCropRegion);
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged - Surface parameters have not changed");
sl@0: 		}
sl@0: 
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error %d", error);
sl@0: 	return error;
sl@0: 	}
sl@0: 	
sl@0: TInt CMediaClientVideoDisplayBody::RedrawWindows(const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RedrawWindows +++");
sl@0: 	TInt err = KErrNone;	
sl@0: 
sl@0: 	iCropRegion = aCropRegion;
sl@0: 	
sl@0: 	if(IsSurfaceCreated())
sl@0: 		{
sl@0: 		TInt count = iWindowsArrayPtr->Count();
sl@0: 	
sl@0: 		for (TInt i = 0; i < count; ++i)
sl@0: 			{
sl@0: 			err = SetBackgroundSurface((*iWindowsArrayPtr)[i], aCropRegion);
sl@0: 		
sl@0: 			if (err != KErrNone)
sl@0: 				{
sl@0: 				break;
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 		
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::RedrawWindows --- return with %d", err);
sl@0: 	return err;
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::UpdateCropRegionL(const TRect& aCropRegion, TInt aPos, TBool aRedrawIndividualWindow)
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL +++");
sl@0: 
sl@0:     TRect prevCropRegion(iCropRegion);
sl@0:     iCropRegion = aCropRegion;
sl@0:     
sl@0:     if (IsSurfaceCreated())
sl@0:         {
sl@0:         if(prevCropRegion == aCropRegion)
sl@0:             {
sl@0:             if(!iSwitchedToExternalDisplay && aRedrawIndividualWindow)
sl@0:                 {
sl@0:                 User::LeaveIfError(SetBackgroundSurface(iClientWindows[aPos], aCropRegion));
sl@0:                 }
sl@0:             }
sl@0:         else
sl@0:             {
sl@0: 			// We only need to redraw if the area of the video to display (i.e the
sl@0: 			// intersection of client crop region and surface crop rectangle) has changed.
sl@0: 			if (ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
sl@0: 				{
sl@0: 				User::LeaveIfError(RedrawWindows(aCropRegion));
sl@0: 				}
sl@0:             }
sl@0:         }
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL ---");    
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetAutoScaleL(const RWindowBase& aWindow, TAutoScaleType aScaleType, TInt aHorizPos, TInt aVertPos, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aWindow WsHandle 0x%X", aWindow.WsHandle());
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aScaleType %d", aScaleType);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0: 	if (!IsAutoScaleTypeValid(aScaleType))
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0:     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 
sl@0: 	TBool parameterChanged = EFalse;
sl@0: 	if (aScaleType != iClientWindows[pos].iAutoScaleType || aHorizPos != iClientWindows[pos].iHorizPos || aVertPos != iClientWindows[pos].iVertPos)
sl@0: 		{
sl@0: 		iClientWindows[pos].iAutoScaleType = aScaleType;
sl@0: 		iClientWindows[pos].iHorizPos = aHorizPos;
sl@0: 		iClientWindows[pos].iVertPos = aVertPos;
sl@0: 		parameterChanged = ETrue;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters have not changed");
sl@0: 		}
sl@0: 
sl@0: 	UpdateCropRegionL(aCropRegion, pos, parameterChanged);
sl@0: 
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL ---");
sl@0: 	}
sl@0: 	
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetRotationL(const RWindowBase& aWindow, TVideoRotation aRotation, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aWindow WsHandle 0x%X", aWindow.WsHandle());
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0: 	if (!IsRotationValid(aRotation))
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0:     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 
sl@0: 	TBool parameterChanged = EFalse;
sl@0: 	if (aRotation != iClientWindows[pos].iRotation)
sl@0: 		{
sl@0: 		iClientWindows[pos].iRotation = aRotation;
sl@0: 		parameterChanged = ETrue;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL - Rotation has not changed");
sl@0: 		}
sl@0: 
sl@0:     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
sl@0: 
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL ---");
sl@0: 	}
sl@0: 
sl@0: TVideoRotation CMediaClientVideoDisplayBody::RotationL(const RWindowBase& aWindow)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RotationL +++");
sl@0: 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 	
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RotationL ---");
sl@0: 	return iClientWindows[pos].iRotation;
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetScaleFactorL(const RWindowBase& aWindow, TReal32 aWidthPercentage, TReal32 aHeightPercentage, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetScaleFactorL - aWindow WsHandle 0x%X", aWindow.WsHandle());
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetScaleFactorL - aWidthPercentage %f, aHeightPercentage %f", aWidthPercentage, aHeightPercentage);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetScaleFactorL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0:     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 	
sl@0: 	if (aWidthPercentage <= 0.0 || aHeightPercentage <= 0.0)
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0: 	TBool parameterChanged = EFalse;
sl@0: 	if (aWidthPercentage != iClientWindows[pos].iScaleWidth ||
sl@0: 	    aHeightPercentage != iClientWindows[pos].iScaleHeight ||
sl@0: 		EAutoScaleNone != iClientWindows[pos].iAutoScaleType)
sl@0: 		{
sl@0: 		iClientWindows[pos].iScaleWidth = aWidthPercentage;
sl@0: 		iClientWindows[pos].iScaleHeight = aHeightPercentage;
sl@0: 		iClientWindows[pos].iAutoScaleType = EAutoScaleNone;
sl@0: 		parameterChanged = ETrue;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters have not changed");
sl@0: 		}
sl@0: 
sl@0:     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
sl@0: 	
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL ---");
sl@0: 	}
sl@0: 	
sl@0: void CMediaClientVideoDisplayBody::GetScaleFactorL(const RWindowBase& aWindow, TReal32& aWidthPercentage, TReal32& aHeightPercentage)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::GetScaleFactorL +++");
sl@0: 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 	
sl@0: 	aWidthPercentage = iClientWindows[pos].iScaleWidth;
sl@0: 	aHeightPercentage = iClientWindows[pos].iScaleHeight;
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::GetScaleFactorL ---");
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetAutoScaleL(TAutoScaleType aScaleType, TInt aHorizPos, TInt aVertPos, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aScaleType %d", aScaleType);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0: 	if (!IsAutoScaleTypeValid(aScaleType))
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0:     TRect prevCropRegion(iCropRegion);
sl@0: 	iCropRegion = aCropRegion;
sl@0: 	
sl@0: 	TBool parameterChanged;
sl@0: 	TInt count = iClientWindows.Count();
sl@0: 
sl@0: 	for (TInt i = 0; i < count; ++i)
sl@0: 		{
sl@0: 		parameterChanged = EFalse;
sl@0: 		if (aScaleType != iClientWindows[i].iAutoScaleType || aHorizPos != iClientWindows[i].iHorizPos || aVertPos != iClientWindows[i].iVertPos)
sl@0: 			{
sl@0: 			iClientWindows[i].iAutoScaleType = aScaleType;
sl@0: 			iClientWindows[i].iHorizPos = aHorizPos;
sl@0: 			iClientWindows[i].iVertPos = aVertPos;
sl@0: 			parameterChanged = ETrue;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters for window pos %d have not changed", i);
sl@0: 			}
sl@0: 
sl@0: 		// We only need to redraw if the scale parameters have changed, or the area of the video
sl@0: 		// to display (i.e the intersection of client crop region and surface crop rectangle) has changed.
sl@0: 		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
sl@0: 			{
sl@0: 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	// We only need to redraw if the area of the video to display (i.e the
sl@0: 	// intersection of client crop region and surface crop rectangle) has changed.
sl@0: 	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
sl@0:         {
sl@0:         User::LeaveIfError(RedrawWindows(aCropRegion));
sl@0:         }
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL ---");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetRotationL(TVideoRotation aRotation, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0: 	if (!IsRotationValid(aRotation))
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0:     TRect prevCropRegion(iCropRegion);
sl@0:     iCropRegion = aCropRegion;
sl@0: 
sl@0: 	TBool parameterChanged;
sl@0: 	TInt count = iClientWindows.Count();
sl@0: 	
sl@0: 	for (TInt i = 0; i < count; ++i)
sl@0: 		{
sl@0: 		parameterChanged = EFalse;
sl@0: 		if (aRotation != iClientWindows[i].iRotation)
sl@0: 			{
sl@0: 			iClientWindows[i].iRotation = aRotation;
sl@0: 			parameterChanged = ETrue;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - Rotation for window pos %d has not changed", i);
sl@0: 			}
sl@0: 
sl@0: 		// We only need to redraw if the scale parameters have changed, or the area of the video
sl@0: 		// to display (i.e the intersection of client crop region and surface crop rectangle) has changed.
sl@0: 		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
sl@0: 			{
sl@0: 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
sl@0: 			}
sl@0: 		}
sl@0: 	
sl@0: 	// We only need to redraw if the area of the video to display (i.e the
sl@0: 	// intersection of client crop region and surface crop rectangle) has changed.
sl@0: 	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
sl@0:         {
sl@0:         User::LeaveIfError(RedrawWindows(aCropRegion));
sl@0:         }
sl@0: 	   
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL ---");
sl@0: 	}
sl@0: 		
sl@0: void CMediaClientVideoDisplayBody::SetScaleFactorL(TReal32 aWidthPercentage, TReal32 aHeightPercentage, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL +++");
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetScaleFactorL - aWidthPercentage %f, aHeightPercentage %f", aWidthPercentage, aHeightPercentage);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetScaleFactorL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0:     if (aWidthPercentage <= 0.0 || aHeightPercentage <= 0.0)
sl@0: 		{
sl@0: 		User::Leave(KErrArgument);
sl@0: 		}
sl@0: 	
sl@0:     TRect prevCropRegion(iCropRegion);
sl@0: 	iCropRegion = aCropRegion;
sl@0: 
sl@0: 	TBool parameterChanged;
sl@0: 	TInt count = iClientWindows.Count();
sl@0: 	
sl@0: 	for (TInt i = 0; i < count; ++i)
sl@0: 		{
sl@0: 		parameterChanged = EFalse;
sl@0: 		
sl@0: 		if (aWidthPercentage != iClientWindows[i].iScaleWidth ||
sl@0: 		    aHeightPercentage != iClientWindows[i].iScaleHeight ||
sl@0: 			EAutoScaleNone != iClientWindows[i].iAutoScaleType)
sl@0: 			{
sl@0: 			iClientWindows[i].iScaleWidth = aWidthPercentage;
sl@0: 			iClientWindows[i].iScaleHeight = aHeightPercentage;
sl@0: 			iClientWindows[i].iAutoScaleType = EAutoScaleNone;
sl@0: 			parameterChanged = ETrue;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters for window pos %d have not changed", i);
sl@0: 			}
sl@0: 
sl@0: 		// We only need to redraw if the scale parameters have changed, or the area of the video to
sl@0: 		// display (i.e the intersection of client crop region and surface crop rectangle) has changed.
sl@0: 		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
sl@0: 			{
sl@0: 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	// We only need to redraw if the area of the video to display (i.e the
sl@0: 	// intersection of client crop region and surface crop rectangle) has changed.
sl@0: 	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
sl@0:         {
sl@0:         User::LeaveIfError(RedrawWindows(aCropRegion));
sl@0:         }
sl@0: 	   
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL ---");
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetWindowClipRectL(const RWindowBase& aWindow, const TRect& aWindowClipRect, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetWindowClipRectL - aWindow WsHandle 0x%X", aWindow.WsHandle());
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetWindowClipRectL - aWindowClipRect %d,%d - %d,%d", aWindowClipRect.iTl.iX, aWindowClipRect.iTl.iY, aWindowClipRect.iBr.iX, aWindowClipRect.iBr.iY);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetWindowClipRectL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 	
sl@0: 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 
sl@0: 	TBool parameterChanged = EFalse;
sl@0: 	if (aWindowClipRect != iClientWindows[pos].iClipRect)
sl@0: 		{
sl@0: 		// We only want to redraw if the change in the clipping rectangle would result
sl@0: 		// in a change to the area of the display used for the video.
sl@0: 		// The video is always displayed in the intersection of the clipping rectangle
sl@0: 		// and the video extent, so check if this has changed.
sl@0: 		parameterChanged = IntersectionAreaChanged(iClientWindows[pos].iClipRect, aWindowClipRect, iClientWindows[pos].iVideoExtent);
sl@0: 
sl@0: 		iClientWindows[pos].iClipRect = aWindowClipRect;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL - Clip rect parameter has not changed");
sl@0: 		}
sl@0: 
sl@0:     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL ---");
sl@0: 	}
sl@0: 	
sl@0: void CMediaClientVideoDisplayBody::SetVideoExtentL(const RWindowBase& aWindow, const TRect& aVideoExtent, const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetVideoExtentL - aWindow WsHandle 0x%X", aWindow.WsHandle());
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetVideoExtentL - aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetVideoExtentL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 
sl@0:     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
sl@0: 	User::LeaveIfError(pos);
sl@0: 
sl@0: 	TBool parameterChanged = EFalse;
sl@0: 	if (aVideoExtent != iClientWindows[pos].iVideoExtent)
sl@0: 		{
sl@0: 		iClientWindows[pos].iVideoExtent = aVideoExtent;
sl@0: 		parameterChanged = ETrue;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL - Video extent parameter has not changed");
sl@0: 		}
sl@0: 
sl@0:     UpdateCropRegionL(aCropRegion, pos, parameterChanged);
sl@0:     
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL ---");
sl@0: 	}
sl@0: 	
sl@0: TBool CMediaClientVideoDisplayBody::HasWindows() const
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::HasWindows +++");
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::HasWindows --- return %d", (iClientWindows.Count() > 0));
sl@0: 	return (iClientWindows.Count() > 0);
sl@0: 	}
sl@0: 	
sl@0: TInt CMediaClientVideoDisplayBody::SetBackgroundSurface(TWindowData& aWindowData,  
sl@0: 									const TRect& aCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetBackgroundSurface +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface - iWindow WsHandle 0x%X", aWindowData.iWindow->WsHandle());
sl@0:     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);
sl@0:     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);
sl@0:     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);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - iScaleWidth %f, iScaleHeight %f", aWindowData.iScaleWidth, aWindowData.iScaleHeight);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface - iRotation %d", aWindowData.iRotation);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface - iAutoScaleType %d", aWindowData.iAutoScaleType);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - iHorizPos %d, iVertPos %d", aWindowData.iHorizPos, aWindowData.iVertPos);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
sl@0: 	
sl@0: 	// required as this private function is called directly from external friend class
sl@0: 	iCropRegion = aCropRegion;
sl@0: 
sl@0:     // viewport is the viewable area of surface
sl@0:     TRect viewport(iCropRect);
sl@0:     if (aCropRegion.Width() > 0 || aCropRegion.Height() > 0)
sl@0:         {
sl@0:         viewport.Intersection(aCropRegion);
sl@0:         }
sl@0:     
sl@0:     // Viewport is 0 size, don't show any video
sl@0:     if (viewport.Width() <= 0 || viewport.Height() <= 0)
sl@0:         {
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
sl@0:         return KErrArgument;
sl@0:         }
sl@0: 
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewport1 %d,%d - %d,%d", viewport.iTl.iX, viewport.iTl.iY, viewport.iBr.iX, viewport.iBr.iY);
sl@0: 
sl@0:     TRect videoExtent(aWindowData.iVideoExtent);
sl@0: 
sl@0:     TReal32 inputWidth = 0.0f;
sl@0:     TReal32 inputHeight = 0.0f;
sl@0:     TReal32 pixelAspectRatio = 0.0f;
sl@0:     switch (aWindowData.iRotation)
sl@0:         {
sl@0:         case EVideoRotationNone:
sl@0:         case EVideoRotationClockwise180:
sl@0:             inputWidth = static_cast<TReal32>(viewport.Width());
sl@0:             inputHeight = static_cast<TReal32>(viewport.Height());
sl@0:             pixelAspectRatio = static_cast<TReal32>(iAspectRatio.iNumerator) / iAspectRatio.iDenominator;
sl@0:             break;
sl@0:         case EVideoRotationClockwise90:
sl@0:         case EVideoRotationClockwise270:
sl@0:             inputWidth = static_cast<TReal32>(viewport.Height());
sl@0:             inputHeight = static_cast<TReal32>(viewport.Width());
sl@0:             pixelAspectRatio = static_cast<TReal32>(iAspectRatio.iDenominator) / iAspectRatio.iNumerator;
sl@0:             break;
sl@0:         default:
sl@0:             // Should never get to default unless there's been some programming error.
sl@0: 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
sl@0: 			return KErrArgument;
sl@0:         }
sl@0:     
sl@0:     TReal32 viewportAspect = pixelAspectRatio * inputWidth / inputHeight;
sl@0:     TReal32 vidextAspect = static_cast<TReal32>(videoExtent.Width()) / static_cast<TReal32>(videoExtent.Height());
sl@0:     
sl@0:     DEBUG_PRINTF4("CMediaClientVideoDisplayBody::SetBackgroundSurface - inputWidth %f, inputHeight %f, PAR %f", inputWidth, inputHeight, pixelAspectRatio);
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewportAspect %f, vidextAspect %f", viewportAspect, vidextAspect);
sl@0: 
sl@0:     // Set the extent to the display area in the window.  The final height and with is to 
sl@0:     // be changed by deltaHeight and deltaWidth respectively.
sl@0:     TRect extent(videoExtent);
sl@0: 
sl@0:     TInt deltaHeight = 0;
sl@0:     TInt deltaWidth = 0;
sl@0:     
sl@0:     if (aWindowData.iAutoScaleType == EAutoScaleBestFit)
sl@0:         {
sl@0:         if (viewportAspect > vidextAspect)
sl@0:             {
sl@0:             // Shrink height to get the correct aspect ratio
sl@0:             deltaHeight = (TInt) (extent.Width() / viewportAspect - extent.Height());
sl@0:             }
sl@0:         else
sl@0:             {
sl@0:             // Shrink width to get the correct aspect ratio
sl@0:             deltaWidth = (TInt) (extent.Height() * viewportAspect - extent.Width());
sl@0:             }
sl@0:         }
sl@0:     else if (aWindowData.iAutoScaleType == EAutoScaleClip)
sl@0:         {
sl@0:         if (viewportAspect > vidextAspect)
sl@0:             {
sl@0:             // Expand width to get the correct aspect ratio
sl@0:             deltaWidth = (TInt) (extent.Height() * viewportAspect - extent.Width());
sl@0:             }
sl@0:         else
sl@0:             {
sl@0:             // Expand height to get the correct aspect ratio
sl@0:             deltaHeight = (TInt) (extent.Width() / viewportAspect - extent.Height());
sl@0:             }
sl@0:         }
sl@0:     else if (aWindowData.iAutoScaleType == EAutoScaleStretch)
sl@0:         {
sl@0:         if(iSwitchedToExternalDisplay)
sl@0:             {
sl@0:             UpdateDeltaForExtDisplay(viewportAspect, videoExtent, deltaHeight, deltaWidth);
sl@0:             }
sl@0:         }
sl@0:     else if (aWindowData.iAutoScaleType == EAutoScaleNone)
sl@0:         {
sl@0:         // for non-square pixels, reduce one dimension
sl@0:         // XXX other option is to enlarge in the other dimension
sl@0:         if(pixelAspectRatio > 1)
sl@0:             {
sl@0:             inputHeight /= pixelAspectRatio;
sl@0:             }
sl@0:         else if(pixelAspectRatio < 1)
sl@0:             {
sl@0:             inputWidth *= pixelAspectRatio;
sl@0:             }
sl@0:         deltaHeight = (TInt) (inputHeight * aWindowData.iScaleHeight * 0.01 - videoExtent.Height());
sl@0:         deltaWidth = (TInt) (inputWidth * aWindowData.iScaleWidth * 0.01 - videoExtent.Width());
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - deltaWidth %d, deltaHeight %d", deltaWidth, deltaHeight);
sl@0: 
sl@0:     // Change the width of the extent in the proper directions and propertions.
sl@0:     switch (aWindowData.iHorizPos)
sl@0:         {
sl@0:     case EHorizontalAlignCenter:
sl@0:         extent.iTl.iX -= deltaWidth / 2;
sl@0:         extent.iBr.iX += deltaWidth / 2;
sl@0:         break;
sl@0:     case EHorizontalAlignLeft:
sl@0:         extent.iBr.iX += deltaWidth;
sl@0:         break;
sl@0:     case EHorizontalAlignRight:
sl@0:         extent.iTl.iX -= deltaWidth;
sl@0:         break;
sl@0:     default:
sl@0:         TInt width = extent.Width() + deltaWidth;
sl@0:         extent.iTl.iX += aWindowData.iHorizPos;
sl@0:         extent.iBr.iX = extent.iTl.iX + width;
sl@0:         break;
sl@0:         }
sl@0:     
sl@0:     // Change the height of the extent in the proper directions and propertions.
sl@0:     switch (aWindowData.iVertPos)
sl@0:         {
sl@0:     case EVerticalAlignCenter:
sl@0:         extent.iTl.iY -= deltaHeight / 2;
sl@0:         extent.iBr.iY += deltaHeight / 2;
sl@0:         break;
sl@0:     case EVerticalAlignTop:
sl@0:         extent.iBr.iY += deltaHeight;
sl@0:         break;
sl@0:     case EVerticalAlignBottom:
sl@0:         extent.iTl.iY -= deltaHeight;
sl@0:         break;
sl@0:     default:
sl@0:         TInt height = extent.Height() + deltaHeight;
sl@0:         extent.iTl.iY += aWindowData.iVertPos;
sl@0:         extent.iBr.iY = extent.iTl.iY + height;
sl@0:         break;
sl@0:         }
sl@0:         
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - extent1 %d,%d - %d,%d", extent.iTl.iX, extent.iTl.iY, extent.iBr.iX, extent.iBr.iY);
sl@0: 
sl@0:     // The video should not be displayed outside the intended video extent or clipping rectangle.  
sl@0:     // The extent already has the correct size and position for displaying the entire viewport.  
sl@0:     // The viewport is clipped such that the video is not moved/distorted when we take the extent 
sl@0:     // to be the intersection of itself and the intended video extent.
sl@0:     
sl@0:     TRect viewableArea(videoExtent);
sl@0:     viewableArea.Intersection(aWindowData.iClipRect);
sl@0:     
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewableArea %d,%d - %d,%d", viewableArea.iTl.iX, viewableArea.iTl.iY, viewableArea.iBr.iX, viewableArea.iBr.iY);
sl@0: 
sl@0:     // Number of pixels (in window coordinates) to be clipped on the right, bottom, top and left sides of
sl@0:     // the video.
sl@0:     TInt dr = Max(0, extent.iBr.iX - viewableArea.iBr.iX);
sl@0:     TInt db = Max(0, extent.iBr.iY - viewableArea.iBr.iY);
sl@0:     TInt dt = Max(0, viewableArea.iTl.iY - extent.iTl.iY);
sl@0:     TInt dl = Max(0, viewableArea.iTl.iX - extent.iTl.iX);
sl@0:     
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - dr %d, db %d, dt %d, dl %d", dr, db, dt, dl);
sl@0: 
sl@0:     // Calculate the number of pixels in the video per window pixel in both x and y directions.
sl@0:     TReal32 wRatio = 0.0f; 
sl@0:     TReal32 hRatio = 0.0f;
sl@0: 
sl@0:     // Make sure we don't divide by 0
sl@0:     if (extent.Width() != 0)
sl@0:         {
sl@0:         wRatio = inputWidth / static_cast<TReal32>(extent.Width());
sl@0:         }
sl@0:     
sl@0:     if (extent.Height() != 0)
sl@0:         {
sl@0:         hRatio = inputHeight / static_cast<TReal32>(extent.Height());
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetBackgroundSurface - wRatio %f, hRatio %f", wRatio, hRatio);
sl@0: 
sl@0:     // Clip the viewport 
sl@0:     switch (aWindowData.iRotation)
sl@0:     {
sl@0:     case EVideoRotationNone:
sl@0:         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(dr));
sl@0:         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(db));
sl@0:         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(dl));
sl@0:         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(dt));
sl@0:         break;
sl@0:     case EVideoRotationClockwise180:
sl@0:         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(dl));
sl@0:         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(dt));
sl@0:         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(dr));
sl@0:         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(db));
sl@0:         break;
sl@0:     case EVideoRotationClockwise90:
sl@0:         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(db));
sl@0:         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(dl));
sl@0:         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(dt));
sl@0:         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(dr));
sl@0:         break;
sl@0:     case EVideoRotationClockwise270:
sl@0:         viewport.iBr.iX -= (TInt) (wRatio * static_cast<TReal32>(dt));
sl@0:         viewport.iBr.iY -= (TInt) (hRatio * static_cast<TReal32>(dr));
sl@0:         viewport.iTl.iX += (TInt) (wRatio * static_cast<TReal32>(db));
sl@0:         viewport.iTl.iY += (TInt) (hRatio * static_cast<TReal32>(dl));
sl@0:         break;
sl@0:     default:
sl@0:         // Should never get to default unless there's been some programming error.
sl@0: 		DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
sl@0:         return KErrArgument;
sl@0:     }
sl@0:     
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewport2 %d,%d - %d,%d", viewport.iTl.iX, viewport.iTl.iY, viewport.iBr.iX, viewport.iBr.iY);
sl@0: 
sl@0:     // Clip the extent.
sl@0:     extent.Intersection(viewableArea);
sl@0:     
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - extent2 %d,%d - %d,%d", extent.iTl.iX, extent.iTl.iY, extent.iBr.iX, extent.iBr.iY);
sl@0: 
sl@0:     aWindowData.iSurfaceConfig.SetViewport(viewport);
sl@0:     aWindowData.iSurfaceConfig.SetExtent(extent);
sl@0:     aWindowData.iSurfaceConfig.SetOrientation(ConvertRotation(aWindowData.iRotation));
sl@0:     
sl@0:     aWindowData.iSurfaceConfig.SetSurfaceId(iSurfaceId);
sl@0: 
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - iSurfaceId %08x:%08x:%08x:%08x",
sl@0:             iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
sl@0:     
sl@0:     // Get the rectangle that bounds the crop rectangle and the viewport.  This should be
sl@0:     // the same as the crop rectangle as long as the viewport does not go outside this area.
sl@0:     TRect rect(iCropRect);
sl@0:     rect.BoundingRect(viewport);
sl@0:     TInt err = KErrNone;
sl@0:     
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - rect %d,%d - %d,%d", rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
sl@0: 
sl@0:     // Check if the viewport and extent can be displayed as a background surface. The viewport 
sl@0:     // is valid if it is within the crop rectangle and is not empty.  The extent is valid if 
sl@0:     // it is not empty. 
sl@0:     if (rect == iCropRect && !viewport.IsEmpty() && !extent.IsEmpty())
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetBackgroundSurface - Calling SetBackgroundSurface");
sl@0:         err = aWindowData.iWindow->SetBackgroundSurface(aWindowData.iSurfaceConfig, ETrue);
sl@0:         }
sl@0: 
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- err %d", err);
sl@0:     return err;
sl@0:     }
sl@0: 
sl@0: TBool CMediaClientVideoDisplayBody::IsUsed() const
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IsUsed +++");
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsUsed --- return %d", (iEventHandler || iClientWindows.Count() > 0));
sl@0: 	return (iEventHandler || iClientWindows.Count() > 0);
sl@0: 	}
sl@0: 	
sl@0: 
sl@0: TBool CMediaClientVideoDisplayBody::IsSurfaceCreated() const
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IsSurfaceCreated +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsSurfaceCreated --- return %d", !(iSurfaceId.IsNull()));
sl@0: 	return !(iSurfaceId.IsNull());
sl@0: 	}
sl@0: 		
sl@0: TInt CMediaClientVideoDisplayBody::DisplayId() const
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::DisplayId +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::DisplayId --- return %d", iDisplayId);
sl@0: 	return iDisplayId;
sl@0: 	}
sl@0: 	
sl@0: TInt CMediaClientVideoDisplayBody::CompareByDisplay(const TInt* aDisplayId, const CMediaClientVideoDisplayBody& aDisplay)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::CompareByDisplay +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::CompareByDisplay --- return %d", (*aDisplayId - aDisplay.DisplayId()));
sl@0: 	return (*aDisplayId - aDisplay.DisplayId());
sl@0: 	}
sl@0: 		
sl@0: TInt CMediaClientVideoDisplayBody::Compare(const CMediaClientVideoDisplayBody& aLeft, const CMediaClientVideoDisplayBody& aRight)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::Compare +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::Compare --- return %d", (aLeft.DisplayId() - aRight.DisplayId()));
sl@0: 	return (aLeft.DisplayId() - aRight.DisplayId());
sl@0: 	}
sl@0: 	
sl@0: CFbsBitGc::TGraphicsOrientation CMediaClientVideoDisplayBody::ConvertRotation(TVideoRotation aRotation)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConvertRotation +++");
sl@0: 	
sl@0: 	CFbsBitGc::TGraphicsOrientation orientation;
sl@0: 	
sl@0: 	switch(aRotation)
sl@0: 		{
sl@0: 		case EVideoRotationNone:
sl@0: 		    orientation = CFbsBitGc::EGraphicsOrientationNormal;
sl@0: 		    break;
sl@0: 		case EVideoRotationClockwise90:
sl@0: 		    orientation = CFbsBitGc::EGraphicsOrientationRotated270;
sl@0: 		    break;
sl@0: 		case EVideoRotationClockwise180:
sl@0: 		    orientation = CFbsBitGc::EGraphicsOrientationRotated180;
sl@0: 		    break;
sl@0: 		case EVideoRotationClockwise270:
sl@0: 		    orientation = CFbsBitGc::EGraphicsOrientationRotated90;
sl@0: 		    break;
sl@0: 		default:
sl@0: 			// Should never get to default unless there's been some programming error.
sl@0: 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- Failed due to %d bad aRotation argument", aRotation);
sl@0: 			__ASSERT_DEBUG(FALSE, User::Invariant());
sl@0: 			// Use the normal option otherwise
sl@0: 			orientation = CFbsBitGc::EGraphicsOrientationNormal;
sl@0: 		}
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- return %d", orientation);	
sl@0:     return orientation;
sl@0: 	}
sl@0: 
sl@0: CMediaClientVideoDisplayBody* CMediaClientVideoDisplayBody::FindDisplayWithWindowL(const RPointerArray<CMediaClientVideoDisplayBody>& aDisplays, const RWindowBase& aWindow)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::FindDisplayWithWindowL +++");
sl@0: 	TInt count = aDisplays.Count();
sl@0: 	
sl@0: 	for (TInt i = 0; i < count; ++i)
sl@0: 		{
sl@0: 		CMediaClientVideoDisplayBody* display = aDisplays[i];
sl@0: 	
sl@0: 		if (display->iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle) != KErrNotFound)
sl@0: 			{
sl@0: 			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::FindDisplayWithWindowL window found at position ", i);
sl@0: 			DEBUG_PRINTF("CMediaClientVideoDisplayBody::FindDisplayWithWindowL ---");
sl@0: 			return display;	
sl@0: 			}
sl@0: 		}
sl@0: 		
sl@0: 	User::Leave(KErrNotFound);
sl@0: 	return NULL;
sl@0: 	}
sl@0: 	
sl@0: RArray<CMediaClientVideoDisplayBody::TWindowData>& CMediaClientVideoDisplayBody::Windows()
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::Windows +++");
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::Windows ---");
sl@0: 	return iClientWindows;	
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL(TBool aControl)
sl@0:     {
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL +++ aControl=%d", aControl);
sl@0: 
sl@0:     // not supported
sl@0:     if(!iExtDisplaySwitchingSupported)
sl@0:         {
sl@0:         User::Leave(KErrNotSupported);
sl@0:         }
sl@0:     
sl@0:     // need active scheduler installed
sl@0:     if(!CActiveScheduler::Current())
sl@0:         {
sl@0:         User::Leave(KErrNotReady);
sl@0:         }
sl@0: 
sl@0:     if(iClientRequestedExtDisplaySwitching != aControl)
sl@0:         {
sl@0:         iClientRequestedExtDisplaySwitching = aControl;     
sl@0:         SwitchSurface();
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected(TExtDisplayConnectionProviderConnType aExtDisplayConnType)
sl@0: 	{
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected +++ aExtDisplayConnType=%d", aExtDisplayConnType);
sl@0: 	
sl@0: 	if(aExtDisplayConnType != iExtDisplayConnType)
sl@0: 	    {
sl@0:         TExtDisplayConnectionProviderConnType prevExtDisplayConnType = iExtDisplayConnType;
sl@0:         iExtDisplayConnType = aExtDisplayConnType;
sl@0:         
sl@0:         if(prevExtDisplayConnType == EExtDisplayConnectionProviderConnTypeDisconnected)
sl@0:             {
sl@0:             // disconnected -> connected  - don't care which type it is
sl@0:             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected disconnected -> connected(type %d)", iExtDisplayConnType);
sl@0:             iExtDisplayConnected = ETrue;
sl@0:             SwitchSurface();
sl@0:             }
sl@0:         else if(iExtDisplayConnType == EExtDisplayConnectionProviderConnTypeDisconnected)
sl@0:             {
sl@0:             // connected -> disconnected  - don't care from which type it is
sl@0:             DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected connected(type %d) -> disconnected", prevExtDisplayConnType);
sl@0:             iExtDisplayConnected = EFalse;
sl@0:             SwitchSurface();
sl@0:             }
sl@0:         else
sl@0:             {
sl@0:             // If we get this far then the connection type has changed from "AV Out -> HDMI" or "HDMI -> AV Out"
sl@0:             // Both are likely. "AV Out -> HDMI" occurs if AV Out cable is connected and HDMI cable is then connected.
sl@0:             // "HDMI -> AV Out" occurs if both AV Out and HDMI cables are connected and HDMI cable is then disconnected.
sl@0:             // HDMI is preferred over AV Out.
sl@0:         
sl@0:             // update external display window data
sl@0:             iExtDisplayHandler->UpdateWindow();
sl@0:             TRect externalDisplayRect(TPoint(0, 0), iExtDisplayHandler->DisplaySizeInPixels());
sl@0:             (*iWindowsArrayPtr)[0].iClipRect = externalDisplayRect;
sl@0:             (*iWindowsArrayPtr)[0].iVideoExtent = externalDisplayRect;
sl@0:             TRAPD(err, (*iWindowsArrayPtr)[0].iAutoScaleType = ExtDisplayAutoScaleTypeL());
sl@0:             if(err == KErrNone)
sl@0:                 {
sl@0:                 RemoveBackgroundSurface(ETrue);
sl@0:                 RedrawWindows(iCropRegion);
sl@0:                 }
sl@0:             else
sl@0:                 {
sl@0:                 // Not a lot we can do. Just keep as it is but external display output will be incorrect. 
sl@0:                 DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected ExtDisplayAutoScaleTypeL failed %d", err);
sl@0:                 }
sl@0:             }
sl@0: 	    }
sl@0: 	else
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected No change to connection type");
sl@0:         }
sl@0: 	
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected ---");
sl@0: 	}
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client +++");
sl@0: 
sl@0:     iWindowsArrayPtr = &iClientWindows;
sl@0:     iSwitchedToExternalDisplay = EFalse;
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext +++");
sl@0: 
sl@0:     iWindowsArrayPtr = &iExtDisplayWindows;
sl@0:     iSwitchedToExternalDisplay = ETrue;
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL +++");
sl@0: 
sl@0:     CMediaClientExtDisplayHandler* extDisplayHandler = CMediaClientExtDisplayHandler::NewL(iExtDisplayConnectionProvider->ExtDisplayId());
sl@0:     CleanupStack::PushL(extDisplayHandler);
sl@0:     
sl@0:     TWindowData windowData;
sl@0:     windowData.iWindow = extDisplayHandler->Window();
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL - iWindow WsHandle 0x%X", windowData.iWindow->WsHandle());
sl@0:     
sl@0:     TRect externalDisplayRect(TPoint(0, 0), extDisplayHandler->DisplaySizeInPixels());
sl@0:     windowData.iClipRect = externalDisplayRect;
sl@0:     windowData.iVideoExtent = externalDisplayRect;
sl@0:     // windowData.iScaleWidth only required for EAutoScaleNone
sl@0:     // windowData.iScaleWidth only required for EAutoScaleNone
sl@0:     windowData.iRotation = EVideoRotationNone;
sl@0:     windowData.iAutoScaleType = ExtDisplayAutoScaleTypeL();
sl@0:     windowData.iHorizPos = EHorizontalAlignCenter;
sl@0:     windowData.iVertPos = EVerticalAlignCenter;
sl@0:     // windowData.iWindow2 not used        
sl@0:     
sl@0:     iExtDisplayWindows.AppendL(windowData);
sl@0:     CleanupStack::Pop(extDisplayHandler);
sl@0:     iExtDisplayHandler = extDisplayHandler;
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayHandlerL ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::RemoveExtDisplayHandler()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayHandler +++");
sl@0: 
sl@0:     delete iExtDisplayHandler;
sl@0:     iExtDisplayHandler = NULL;
sl@0:     iExtDisplayWindows.Reset();
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayHandler ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::CreateExtDisplayPluginL()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayPluginL +++");
sl@0:     
sl@0:     iExtDisplayConnectionProvider = CExtDisplayConnectionProviderInterface::NewL();
sl@0:     
sl@0:     if(iExtDisplayConnectionProvider)
sl@0:         {
sl@0:         iExtDisplaySwitchingSupported = ETrue;
sl@0:         iExtDisplayConnectionProvider->SetExtDisplayConnectionProviderCallback(*this);
sl@0:         iExtDisplayConnType = iExtDisplayConnectionProvider->ExtDisplayConnType();
sl@0:         iExtDisplayConnected = (iExtDisplayConnType != EExtDisplayConnectionProviderConnTypeDisconnected);
sl@0:         }
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::CreateExtDisplayPluginL ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin +++");
sl@0:     
sl@0:     if(iExtDisplaySwitchingSupported)
sl@0:         {
sl@0:         delete iExtDisplayConnectionProvider;
sl@0:         iExtDisplayConnectionProvider = NULL;
sl@0:         iExtDisplaySwitchingSupported = EFalse;
sl@0:         iExtDisplayConnected = EFalse;
sl@0:         }    
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::MmcweoFocusWindowGroupChanged()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged +++");
sl@0:     
sl@0:     TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
sl@0:     UpdateFocus();
sl@0:     
sl@0:     if(prevClientWindowIsInFocus != iClientWindowIsInFocus)
sl@0:         {
sl@0:         SwitchSurface();
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged ---");
sl@0:     }
sl@0: 
sl@0: TBool CMediaClientVideoDisplayBody::MmcweoIgnoreProcess(TSecureId aId)
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess +++");
sl@0:     
sl@0:     TBool ignore = ETrue;
sl@0:     if (iServerClient)
sl@0:         {
sl@0:         ignore = iServerClient->IgnoreProcess(aId);
sl@0:         }
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess --- return %d", ignore);
sl@0:     return ignore;
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::UpdateFocus()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus +++");
sl@0:     
sl@0:     if(!iWsEventObserver)
sl@0:         {
sl@0:         iClientWindowIsInFocus = ETrue;
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Event Observer is NULL");
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---");
sl@0:         return;
sl@0:         }
sl@0:     
sl@0:     TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
sl@0:     
sl@0:     TInt focusGroupId;
sl@0:     if(iWsEventObserver->FocusWindowGroupId(focusGroupId) == KErrNone)
sl@0:         {
sl@0:         iClientWindowIsInFocus = EFalse;
sl@0:         TInt count = iClientWindows.Count();
sl@0:         for(TInt i = 0; i < count; i++)
sl@0:             {
sl@0:             if(iClientWindows[i].iWindow->WindowGroupId() == focusGroupId)
sl@0:                 {
sl@0:                 iClientWindowIsInFocus = ETrue;
sl@0:                 break;
sl@0:                 }
sl@0:             }
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Error retrieving focus WgId from observer");
sl@0:         iClientWindowIsInFocus = ETrue;
sl@0:         }
sl@0: 
sl@0:     if(iServerClient && (prevClientWindowIsInFocus != iClientWindowIsInFocus))
sl@0:         {
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged calling server, focus %d", iClientWindowIsInFocus);
sl@0:         iServerClient->FocusChanged(iClientWindowIsInFocus);
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateFocus Client window in focus %d", iClientWindowIsInFocus);
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---");
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SwitchSurface()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface +++");
sl@0: 
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface SurfaceCreated %d", IsSurfaceCreated());
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client window count %d", iClientWindows.Count());
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Requested Ext Display Switching %d", iClientRequestedExtDisplaySwitching);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Window in Focus %d", iClientWindowIsInFocus);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface External Display Connected %d", iExtDisplayConnected);
sl@0: 
sl@0:     if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching &&
sl@0:             iClientWindowIsInFocus && iExtDisplayConnected)
sl@0:         {
sl@0:         TRAPD(err, CreateExtDisplayHandlerL());
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface CreateExtDisplayHandlerL error %d", err);
sl@0:         if(err == KErrNone)
sl@0:             {
sl@0:             SetWindowArrayPtr2Ext();
sl@0:             RedrawWindows(iCropRegion); 
sl@0:             
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0:             // Hide surface so that video is not seen on client window
sl@0:             HideAllClientWindows();
sl@0: #else
sl@0:             // Surface removed from window
sl@0:             SetWindowArrayPtr2Client();
sl@0:             RemoveBackgroundSurface(ETrue);
sl@0:             SetWindowArrayPtr2Ext();
sl@0: #endif
sl@0:             }
sl@0:         }
sl@0:     else if(iSwitchedToExternalDisplay)
sl@0:         {
sl@0:         // Set background surface for clientwindows before removing from external display window.
sl@0:         SetWindowArrayPtr2Client();
sl@0:         // RedrawWindows handles both the case where the surface was removed from client window and 
sl@0:         // also the case where the surface was hidden from client window
sl@0:         RedrawWindows(iCropRegion);
sl@0:         SetWindowArrayPtr2Ext();
sl@0:         RemoveBackgroundSurface(ETrue);
sl@0:         RemoveExtDisplayHandler();
sl@0:         SetWindowArrayPtr2Client();
sl@0:         }
sl@0: 
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface ---");
sl@0:     }
sl@0: 
sl@0: TBool CMediaClientVideoDisplayBody::IsRotationValid(TVideoRotation aVideoRotation)
sl@0: 	{
sl@0: 	if (aVideoRotation == EVideoRotationNone ||
sl@0: 	    aVideoRotation == EVideoRotationClockwise90 ||
sl@0: 		aVideoRotation == EVideoRotationClockwise180 ||
sl@0: 		aVideoRotation == EVideoRotationClockwise270)
sl@0: 		{
sl@0: 		return ETrue;
sl@0: 		}
sl@0: 
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsRotationValid - Rotation %d not valid", aVideoRotation);
sl@0: 	return EFalse;
sl@0: 	}
sl@0: 
sl@0: TBool CMediaClientVideoDisplayBody::IsAutoScaleTypeValid(TAutoScaleType aAutoScaleType)
sl@0: 	{
sl@0: 	if (aAutoScaleType == EAutoScaleNone ||
sl@0: 	    aAutoScaleType == EAutoScaleBestFit ||
sl@0: 	    aAutoScaleType == EAutoScaleClip ||
sl@0: 	    aAutoScaleType == EAutoScaleStretch)
sl@0: 		{
sl@0: 		return ETrue;
sl@0: 		}
sl@0: 
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsAutoScaleTypeValid - Auto scale %d not valid", aAutoScaleType);
sl@0: 	return EFalse;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Check whether a change in the surface crop rectangle would mean that the surface viewport calculated in SetBackgroundSurface would change.
sl@0: The surface viewport is the intersection of the surface crop rectangle and the client crop region
sl@0: */
sl@0: TBool CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw(TRect aOldSurfaceCropRect, TRect aNewSurfaceCropRect, TRect aClientCropRegion)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw +++");
sl@0: 	
sl@0: 	// If aClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations.
sl@0: 	// This means that only aOldSurfaceCropRect is being used to decide which part of the video is displayed.
sl@0: 	// By setting aClientCropRect to the same as aOldSurfaceCropRect we ensure that only aOldSurfaceCropRect is
sl@0: 	// used in the subsequent intersection area checks.
sl@0: 	if (aClientCropRegion.IsEmpty())
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw - Client crop region is empty");		
sl@0: 		aClientCropRegion = aOldSurfaceCropRect;
sl@0: 		}
sl@0: 
sl@0: 	TBool ret = IntersectionAreaChanged(aOldSurfaceCropRect, aNewSurfaceCropRect, aClientCropRegion);
sl@0: 
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw --- ret = %d", ret);
sl@0: 
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Check whether a change in the client crop region would mean that the surface viewport calculated in SetBackgroundSurface would change.
sl@0: The surface viewport is the intersection of the surface crop rectangle and the client crop region
sl@0: */
sl@0: TBool CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw(TRect aOldClientCropRegion, TRect aNewClientCropRegion, TRect aSurfaceCropRect)
sl@0: 	{
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw +++");
sl@0: 
sl@0: 	// If aOldClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations.
sl@0: 	// This means that only aSurfaceCropRect is being used to decide which part of the video is displayed. By
sl@0: 	// setting aOldClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is
sl@0: 	// used in the subsequent intersection area checks.
sl@0: 	if (aOldClientCropRegion.IsEmpty())
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - Old client crop region is empty");
sl@0: 		aOldClientCropRegion = aSurfaceCropRect;
sl@0: 		}
sl@0: 
sl@0: 	// If aNewClientCropRegion is empty then it will not be used in the SetBackgroundSurface calculations.
sl@0: 	// This means that only aSurfaceCropRect will impact which part of the video is displayed. By
sl@0: 	// setting aNewClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is
sl@0: 	// used in the subsequent intersection area checks.
sl@0: 	if (aNewClientCropRegion.IsEmpty())
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - New client crop region is empty");
sl@0: 		aNewClientCropRegion = aSurfaceCropRect;
sl@0: 		}
sl@0: 
sl@0: 	TBool ret = IntersectionAreaChanged(aOldClientCropRegion, aNewClientCropRegion, aSurfaceCropRect);
sl@0: 
sl@0: 	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw --- ret = %d", ret);
sl@0: 
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Check whether the change in size of a rectangle means its intersection with another rectangle has changed.
sl@0: This is used to check whether changes in things like the surface crop rectangle, client crop region, and window clip rectangle, would mean
sl@0: the area of video displayed would change.
sl@0: */
sl@0: TBool CMediaClientVideoDisplayBody::IntersectionAreaChanged(TRect aOldRect, TRect aNewRect, TRect aOtherRect)
sl@0: 	{
sl@0: 	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOldRect %d,%d - %d,%d", aOldRect.iTl.iX, aOldRect.iTl.iY, aOldRect.iBr.iX, aOldRect.iBr.iY);
sl@0: 	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aNewRect %d,%d - %d,%d", aNewRect.iTl.iX, aNewRect.iTl.iY, aNewRect.iBr.iX, aNewRect.iBr.iY);
sl@0: 	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOtherRect %d,%d - %d,%d", aOtherRect.iTl.iX, aOtherRect.iTl.iY, aOtherRect.iBr.iX, aOtherRect.iBr.iY);
sl@0: 
sl@0: 	aOldRect.Intersection(aOtherRect);
sl@0: 	aNewRect.Intersection(aOtherRect);
sl@0: 
sl@0: 	if (aOldRect != aNewRect)
sl@0: 		{
sl@0: 		DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged --- Intersection area has changed");
sl@0: 		return ETrue;
sl@0: 		}
sl@0: 
sl@0: 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged --- Intersection area has not changed");
sl@0: 	return EFalse;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: * This function calculates the delta width and delta height for AV out when the TV-Out setting is set to "widescreen".
sl@0: *
sl@0: * AV out has fixed resolution whether TV-Out is set to "normal" or "widescreen". The TV-Out setting indicates
sl@0: * that the video should be scaled so that when displayed on a corresponding TV the aspect looks correct.
sl@0: * 
sl@0: * When displaying video on a widescreen TV through AV out, because the resolution is the same the TV stretches
sl@0: * the video horizontally. When displaying on a normal TV no stretching takes place.
sl@0: * 
sl@0: * For "normal" TAutoScaleType::EAutoScaleClip is used.
sl@0: * 
sl@0: * For "widescreen" this function calculates the width delta and height delta required so that when the video is stretched
sl@0: * the aspect looks correct on a widescreen TV.
sl@0: * 
sl@0: * This function must only be called when autoscale is set to TAutoScaleType::EAutoScaleStretch and an external display is
sl@0: * connected.
sl@0: **/
sl@0: void CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay(TReal32 aViewportAspect, const TRect& aVideoExtent, TInt& aDeltaHeight, TInt& aDeltaWidth)
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay +++");
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aViewportAspect %f", aViewportAspect);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aVideoExtent %d,%d - %d,%d", aVideoExtent.iTl.iX, aVideoExtent.iTl.iY, aVideoExtent.iBr.iX, aVideoExtent.iBr.iY);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aDeltaHeight %d", aDeltaHeight);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay aDeltaWidth %d", aDeltaWidth);
sl@0: 
sl@0:     aDeltaWidth = 0;
sl@0:     aDeltaHeight = 0;
sl@0:     
sl@0:     TReal32 wideScreenAspect = (TReal32)16 / (TReal32)9;
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay wideScreenAspect %f", wideScreenAspect);
sl@0: 
sl@0:     if(aViewportAspect == wideScreenAspect)
sl@0:         {
sl@0:         // no need to calculate
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - Viewport Aspect equals wideScreenAspect");
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - width delta and height delta not changed");
sl@0:         }
sl@0:     else if(aViewportAspect < wideScreenAspect)
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - Viewport Aspect is less than wideScreenAspect");
sl@0:         
sl@0:         // calculate video width for viewport that when stretched looks ok on widescreen
sl@0:         TReal32 correctedWidth = (TReal32)aVideoExtent.Width() * aViewportAspect / wideScreenAspect;
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay corrected viewport width %f", correctedWidth);
sl@0:         
sl@0:         aDeltaWidth = correctedWidth - aVideoExtent.Width();
sl@0:         }
sl@0:     else // aViewportAspect > wideScreenAspect
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay - Viewport Aspect is greater than wideScreenAspect");
sl@0: 
sl@0:         // calculate video height for viewport that when stretched looks ok on widescreen
sl@0:         TReal32 correctedHeight = (TReal32)aVideoExtent.Height() * wideScreenAspect / aViewportAspect;
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay corrected viewport height %f", correctedHeight);
sl@0:         
sl@0:         aDeltaHeight = aVideoExtent.Height() - correctedHeight;
sl@0:         }        
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay --- aDeltaHeight %d", aDeltaHeight);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay --- aDeltaWidth %d", aDeltaWidth);
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateDeltaForExtDisplay ---");
sl@0:     }
sl@0: 
sl@0: TBool CMediaClientVideoDisplayBody::IsWideScreenL()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::IsWideScreenL +++");
sl@0:     
sl@0:     CRepository* repo = CRepository::NewLC(KCRUidTvoutSettings);
sl@0:     TInt value;
sl@0:     User::LeaveIfError(repo->Get(KSettingsTvAspectRatio, value));
sl@0: 
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsWideScreenL Tv Apect Ratio set to %d, 0=4x3 1=16x9", value);
sl@0: 
sl@0:     CleanupStack::PopAndDestroy(repo);
sl@0:     
sl@0:     TBool ret = value > 0;
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsWideScreenL --- return %d", ret);
sl@0:     return ret;
sl@0:     }
sl@0: 
sl@0: TAutoScaleType CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL +++");
sl@0:     
sl@0:     // EExtDisplayConnectionProviderConnTypeHdmi - EAutoScaleBestFit
sl@0:     // EExtDisplayConnectionProviderConnTypeAnalog / normal - EAutoScaleBestFit
sl@0:     // EExtDisplayConnectionProviderConnTypeAnalog / widescreen - EAutoScaleStretch
sl@0:     
sl@0:     TAutoScaleType autoScaleType;
sl@0:     if((iExtDisplayConnType == EExtDisplayConnectionProviderConnTypeAnalog) && IsWideScreenL())
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL External display scale type EAutoScaleStretch");
sl@0:         autoScaleType = EAutoScaleStretch;
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         DEBUG_PRINTF("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL External display scale type EAutoScaleBestFit");
sl@0:         autoScaleType = EAutoScaleBestFit;
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ExtDisplayAutoScaleTypeL --- return %d", autoScaleType);
sl@0:     return autoScaleType;
sl@0:     }
sl@0: 
sl@0: #ifdef MEDIA_CLIENT_SURFACE_NOT_REMOVED_FROM_CLIENT_WINDOW
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::HideAllClientWindows()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideAllClientWindows +++");
sl@0: 
sl@0:     TInt count = iClientWindows.Count();
sl@0:     for (TInt i = 0; i < count; ++i)
sl@0:         {
sl@0:         // ignore error - cannot be handled
sl@0:         HideWindow(iClientWindows[i].iWindow);
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideAllClientWindows ---");
sl@0:     }
sl@0: 
sl@0: TInt CMediaClientVideoDisplayBody::HideWindow(RWindowBase* aWindow)
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideWindow +++");
sl@0: 
sl@0:     TSurfaceConfiguration config;
sl@0:     TInt err = aWindow->GetBackgroundSurface(config);
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::HideWindow GetBackgroundSurface error %d", err);
sl@0:     
sl@0: #ifdef _DEBUG
sl@0:     TSurfaceId surface;
sl@0:     config.GetSurfaceId(surface);
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::HideWindow - Retrieved Surface %08x:%08x:%08x:%08x", 
sl@0:             surface.iInternal[3], surface.iInternal[2], surface.iInternal[1], surface.iInternal[0]);
sl@0: #endif
sl@0:     
sl@0:     if (err == KErrNone)
sl@0:         {
sl@0:         config.SetExtent(TRect(KHiddenExtentA, KHiddenExtentA, KHiddenExtentB, KHiddenExtentB));
sl@0:         err = aWindow->SetBackgroundSurface(config, ETrue);
sl@0:         // Make sure all window rendering has completed before proceeding
sl@0:         RWsSession* ws = aWindow->Session();
sl@0:         if (ws)
sl@0:            {
sl@0:            ws->Finish();
sl@0:            }
sl@0:         DEBUG_PRINTF2("CMediaClientVideoDisplayBody::HideWindow SetBackgroundSurface error %d", err);
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::HideWindow ---");
sl@0:     return err;
sl@0:     }
sl@0: 
sl@0: void CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnAllClientWindows()
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnAllClientWindows +++");
sl@0: 
sl@0:     TInt count = iClientWindows.Count();
sl@0:     for (TInt i = 0; i < count; ++i)
sl@0:         {
sl@0:         // ignore error - cannot be handled
sl@0:         SetHiddenBackgroundSurfaceOnClientWindow(iClientWindows[i]);
sl@0:         }
sl@0:     
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnAllClientWindows ---");
sl@0:     }
sl@0: 
sl@0: 
sl@0: TInt CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow(TWindowData& aWindowData)
sl@0:     {
sl@0:     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow +++");    
sl@0:     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow - iSurfaceId %08x:%08x:%08x:%08x",
sl@0:                 iSurfaceId.iInternal[3], iSurfaceId.iInternal[2], iSurfaceId.iInternal[1], iSurfaceId.iInternal[0]);
sl@0:     
sl@0:     TSurfaceConfiguration config;
sl@0:     config.SetExtent(TRect(KHiddenExtentA, KHiddenExtentA, KHiddenExtentB, KHiddenExtentB));   
sl@0:     config.SetSurfaceId(iSurfaceId);
sl@0:     TInt err = aWindowData.iWindow->SetBackgroundSurface(config, ETrue);
sl@0:     
sl@0:     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetHiddenBackgroundSurfaceOnClientWindow ---, return %d", err);
sl@0:     return err;
sl@0:     }
sl@0: #endif