diff -r efebd1779a59 -r c1e808730d6c mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp --- a/mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp Fri Apr 16 16:34:49 2010 +0300 +++ b/mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp Mon May 03 13:56:28 2010 +0300 @@ -15,6 +15,7 @@ #include "mediaclientvideodisplaybody.h" #include "mediaclientvideotrace.h" +#include "mediaclientpolicyserverclient.h" #include #include #include @@ -62,15 +63,36 @@ SetWindowArrayPtr2Client(); - CreateExtDisplayPluginL(); - - // Try and enable display switching by default. If this leaves then do so quietly. - // Either the client has no scheduler installed or the device does not support external - // switching (i.e. no plugin was found) - TRAPD(err, SetExternalDisplaySwitchingL(aExtDisplaySwitchingControl)); - err = err; // remove compile warning - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConstructL SetExternalDisplaySwitchingL returned with %d", err); - + // External display switching and wserv events are only possible if there is + // an active scheduler in client thread + if(CActiveScheduler::Current()) + { + CreateExtDisplayPluginL(); + iWsEventObserver = CMediaClientWsEventObserver::NewL(*this); + + iServerClient = CMediaClientPolicyServerClient::NewL(); + if(iServerClient->Connect() != KErrNone) + { + delete iServerClient; + iServerClient = NULL; + } + + if(IsSurfaceCreated() && iServerClient) + { + iServerClient->SetSurface(iSurfaceId); + } + + // Try and enable display switching by default. If this leaves then do so quietly. + // Either the client has no scheduler installed or the device does not support external + // switching (i.e. no plugin was found) + TRAPD(err, SetExternalDisplaySwitchingL(aExtDisplaySwitchingControl)); + err = err; // remove compile warning + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConstructL SetExternalDisplaySwitchingL returned with %d", err); + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL No CActiveScheduler - ext display and focus features disabled "); + } DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL ---"); } @@ -106,6 +128,10 @@ RemoveExtDisplayPlugin(); REComSession::FinalClose(); + delete iWsEventObserver; + + delete iServerClient; + DEBUG_PRINTF("CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody ---"); } @@ -129,7 +155,7 @@ void CMediaClientVideoDisplayBody::AddDisplayWindowL(const RWindowBase* aWindow, const TRect& aClipRect, const TRect& aCropRegion, const TRect& aVideoExtent, TReal32 aScaleWidth, TReal32 aScaleHeight, TVideoRotation aRotation, TAutoScaleType aAutoScaleType, TInt aHorizPos, TInt aVertPos, RWindow* aWindow2) - { + { DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayWindowL +++"); DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aWindow WsHandle 0x%X", aWindow->WsHandle()); DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aClipRect %d,%d - %d,%d", aClipRect.iTl.iX, aClipRect.iTl.iY, aClipRect.iBr.iX, aClipRect.iBr.iY); @@ -140,6 +166,16 @@ DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aAutoScaleType %d", aAutoScaleType); DEBUG_PRINTF3("CMediaClientVideoDisplayBody::AddDisplayWindowL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos); + if (!IsRotationValid(aRotation)) + { + User::Leave(KErrArgument); + } + + if (!IsAutoScaleTypeValid(aAutoScaleType)) + { + User::Leave(KErrArgument); + } + TInt pos = iClientWindows.Find(aWindow->WsHandle(), TWindowData::CompareByWsHandle); if (pos != KErrNotFound) @@ -152,24 +188,25 @@ iCropRegion = aCropRegion; + TBool prevClientWindowIsInFocus = iClientWindowIsInFocus; + UpdateFocus(); + if (IsSurfaceCreated()) { - // first client window just added - if((iClientWindows.Count() == 1) && iClientRequestedExtDisplaySwitching) + // if first window was just added OR the new window has moved us from out of focus to in focus + if(((iClientWindows.Count() == 1) || !prevClientWindowIsInFocus) && iClientRequestedExtDisplaySwitching && + iClientWindowIsInFocus && iExtDisplayConnected) { - if(iExtDisplayConnected) + TRAPD(err, CreateExtDisplayHandlerL()); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL CreateExtDisplayHandlerL error %d", err); + if(err == KErrNone) { - TRAPD(err, CreateExtDisplayHandlerL()); - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL CreateExtDisplayHandlerL error %d", err); - if(err == KErrNone) - { - SetWindowArrayPtr2Ext(); - User::LeaveIfError(RedrawWindows(aCropRegion)); - } + SetWindowArrayPtr2Ext(); + User::LeaveIfError(RedrawWindows(aCropRegion)); } } - if(!iExtDisplayConnected || !iExtDisplayHandler) + if(!iSwitchedToExternalDisplay) { User::LeaveIfError(SetBackgroundSurface(winData, aCropRegion)); } @@ -190,25 +227,32 @@ TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle); if (pos >= 0) - { - if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler)) - { - iClientWindows[pos].iWindow->RemoveBackgroundSurface(ETrue); + { + if(IsSurfaceCreated() && !iSwitchedToExternalDisplay) + { + iClientWindows[pos].iWindow->RemoveBackgroundSurface(ETrue); // Make sure all window rendering has completed before proceeding RWsSession* ws = iClientWindows[pos].iWindow->Session(); if (ws) - { - ws->Finish(); - } - } - iClientWindows.Remove(pos); - - if(iClientWindows.Count() == 0 && iExtDisplayConnected && iExtDisplayHandler) - { - RemoveBackgroundSurface(ETrue); - SetWindowArrayPtr2Client(); - RemoveExtDisplayHandler(); - } + { + ws->Finish(); + } + } + + iClientWindows.Remove(pos); + + TBool prevClientWindowIsInFocus = iClientWindowIsInFocus; + UpdateFocus(); + + // if only window was just removed OR removal has moved us from in focus to out of focus + if((iClientWindows.Count() == 0 || prevClientWindowIsInFocus) && iSwitchedToExternalDisplay && + !iClientWindowIsInFocus) + { + RemoveBackgroundSurface(ETrue); + SetWindowArrayPtr2Client(); + RemoveExtDisplayHandler(); + RedrawWindows(iCropRegion); + } } DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplayWindow ---"); @@ -235,13 +279,18 @@ iAspectRatio = aAspectRatio; iCropRegion = aCropRegion; + if(iServerClient) + { + iServerClient->SetSurface(iSurfaceId); + } + if (emitEvent && iEventHandler) { iEventHandler->MmsehSurfaceCreated(iDisplayId, iSurfaceId, iCropRect, iAspectRatio); } TInt err = KErrNone; - if((iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching) + if((iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching && iClientWindowIsInFocus) { if(iExtDisplayConnected && !iExtDisplayHandler) { @@ -256,7 +305,7 @@ err = RedrawWindows(aCropRegion); - DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCreated ---"); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCreated --- Return error %d", err); return err; } @@ -296,7 +345,7 @@ iSurfaceId = TSurfaceId::CreateNullId(); - if(iExtDisplayConnected && iExtDisplayHandler) + if(iSwitchedToExternalDisplay) { SetWindowArrayPtr2Client(); RemoveExtDisplayHandler(); @@ -315,26 +364,47 @@ if (!IsSurfaceCreated()) { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrNotSupproted"); return KErrNotSupported; } if (iSurfaceId != aSurfaceId) { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrInUse"); return KErrInUse; } - - iCropRect = aCropRect; - iAspectRatio = aAspectRatio; - + if (iEventHandler) { - iEventHandler->MmsehSurfaceParametersChanged(iSurfaceId, iCropRect, iAspectRatio); + iEventHandler->MmsehSurfaceParametersChanged(iSurfaceId, aCropRect, aAspectRatio); } - RedrawWindows(iCropRegion); - - DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged ---"); - return KErrNone; + TInt error = KErrNone; + if (iCropRect != aCropRect || iAspectRatio != aAspectRatio) + { + // We only need to redraw if the aspect ratio has changed, or the area of the video to + // display (i.e the intersection of client crop region and surface crop rectangle) has changed. + TBool redraw = EFalse; + if (iAspectRatio != aAspectRatio || SurfaceCropRectChangeRequiresRedraw(iCropRect, aCropRect, iCropRegion)) + { + redraw = ETrue; + } + + iCropRect = aCropRect; + iAspectRatio = aAspectRatio; + + if (redraw) + { + error = RedrawWindows(iCropRegion); + } + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged - Surface parameters have not changed"); + } + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error %d", error); + return error; } TInt CMediaClientVideoDisplayBody::RedrawWindows(const TRect& aCropRegion) @@ -363,7 +433,7 @@ return err; } -void CMediaClientVideoDisplayBody::UpdateCropRegionL(const TRect& aCropRegion, TInt aPos) +void CMediaClientVideoDisplayBody::UpdateCropRegionL(const TRect& aCropRegion, TInt aPos, TBool aRedrawIndividualWindow) { DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL +++"); @@ -374,14 +444,19 @@ { if(prevCropRegion == aCropRegion) { - if(!iExtDisplayConnected || !iExtDisplayHandler) + if(!iSwitchedToExternalDisplay && aRedrawIndividualWindow) { User::LeaveIfError(SetBackgroundSurface(iClientWindows[aPos], aCropRegion)); } } else { - User::LeaveIfError(RedrawWindows(aCropRegion)); + // We only need to redraw if the area of the video to display (i.e the + // intersection of client crop region and surface crop rectangle) has changed. + if (ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)) + { + User::LeaveIfError(RedrawWindows(aCropRegion)); + } } } DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL ---"); @@ -395,15 +470,29 @@ DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos); DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY); + if (!IsAutoScaleTypeValid(aScaleType)) + { + User::Leave(KErrArgument); + } + TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle); User::LeaveIfError(pos); - - iClientWindows[pos].iAutoScaleType = aScaleType; - iClientWindows[pos].iHorizPos = aHorizPos; - iClientWindows[pos].iVertPos = aVertPos; - UpdateCropRegionL(aCropRegion, pos); - + TBool parameterChanged = EFalse; + if (aScaleType != iClientWindows[pos].iAutoScaleType || aHorizPos != iClientWindows[pos].iHorizPos || aVertPos != iClientWindows[pos].iVertPos) + { + iClientWindows[pos].iAutoScaleType = aScaleType; + iClientWindows[pos].iHorizPos = aHorizPos; + iClientWindows[pos].iVertPos = aVertPos; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters have not changed"); + } + + UpdateCropRegionL(aCropRegion, pos, parameterChanged); + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL ---"); } @@ -415,12 +504,26 @@ DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation); DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY); + if (!IsRotationValid(aRotation)) + { + User::Leave(KErrArgument); + } + TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle); User::LeaveIfError(pos); - - iClientWindows[pos].iRotation = aRotation; - UpdateCropRegionL(aCropRegion, pos); + TBool parameterChanged = EFalse; + if (aRotation != iClientWindows[pos].iRotation) + { + iClientWindows[pos].iRotation = aRotation; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL - Rotation has not changed"); + } + + UpdateCropRegionL(aCropRegion, pos, parameterChanged); DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL ---"); } @@ -450,11 +553,22 @@ User::Leave(KErrArgument); } - iClientWindows[pos].iScaleWidth = aWidthPercentage; - iClientWindows[pos].iScaleHeight = aHeightPercentage; - iClientWindows[pos].iAutoScaleType = EAutoScaleNone; - - UpdateCropRegionL(aCropRegion, pos); + TBool parameterChanged = EFalse; + if (aWidthPercentage != iClientWindows[pos].iScaleWidth || + aHeightPercentage != iClientWindows[pos].iScaleHeight || + EAutoScaleNone != iClientWindows[pos].iAutoScaleType) + { + iClientWindows[pos].iScaleWidth = aWidthPercentage; + iClientWindows[pos].iScaleHeight = aHeightPercentage; + iClientWindows[pos].iAutoScaleType = EAutoScaleNone; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters have not changed"); + } + + UpdateCropRegionL(aCropRegion, pos, parameterChanged); DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL ---"); } @@ -476,23 +590,44 @@ DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aScaleType %d", aScaleType); DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos); DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY); - + + if (!IsAutoScaleTypeValid(aScaleType)) + { + User::Leave(KErrArgument); + } + TRect prevCropRegion(iCropRegion); iCropRegion = aCropRegion; + + TBool parameterChanged; TInt count = iClientWindows.Count(); - + for (TInt i = 0; i < count; ++i) { - iClientWindows[i].iAutoScaleType = aScaleType; - iClientWindows[i].iHorizPos = aHorizPos; - iClientWindows[i].iVertPos = aVertPos; - if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler)) + parameterChanged = EFalse; + if (aScaleType != iClientWindows[i].iAutoScaleType || aHorizPos != iClientWindows[i].iHorizPos || aVertPos != iClientWindows[i].iVertPos) + { + iClientWindows[i].iAutoScaleType = aScaleType; + iClientWindows[i].iHorizPos = aHorizPos; + iClientWindows[i].iVertPos = aVertPos; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters for window pos %d have not changed", i); + } + + // We only need to redraw if the scale parameters have changed, or the area of the video + // to display (i.e the intersection of client crop region and surface crop rectangle) has changed. + if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))) { User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion)); } } - - if (IsSurfaceCreated() && iExtDisplayConnected && iExtDisplayHandler && (aCropRegion != prevCropRegion)) + + // We only need to redraw if the area of the video to display (i.e the + // intersection of client crop region and surface crop rectangle) has changed. + if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)) { User::LeaveIfError(RedrawWindows(aCropRegion)); } @@ -506,20 +641,41 @@ DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation); DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY); + if (!IsRotationValid(aRotation)) + { + User::Leave(KErrArgument); + } + TRect prevCropRegion(iCropRegion); iCropRegion = aCropRegion; + + TBool parameterChanged; TInt count = iClientWindows.Count(); for (TInt i = 0; i < count; ++i) { - iClientWindows[i].iRotation = aRotation; - if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler)) + parameterChanged = EFalse; + if (aRotation != iClientWindows[i].iRotation) + { + iClientWindows[i].iRotation = aRotation; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - Rotation for window pos %d has not changed", i); + } + + // We only need to redraw if the scale parameters have changed, or the area of the video + // to display (i.e the intersection of client crop region and surface crop rectangle) has changed. + if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))) { User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion)); } } - if (IsSurfaceCreated() && iExtDisplayConnected && iExtDisplayHandler && (aCropRegion != prevCropRegion)) + // We only need to redraw if the area of the video to display (i.e the + // intersection of client crop region and surface crop rectangle) has changed. + if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)) { User::LeaveIfError(RedrawWindows(aCropRegion)); } @@ -540,20 +696,39 @@ TRect prevCropRegion(iCropRegion); iCropRegion = aCropRegion; + + TBool parameterChanged; TInt count = iClientWindows.Count(); for (TInt i = 0; i < count; ++i) { - iClientWindows[i].iScaleWidth = aWidthPercentage; - iClientWindows[i].iScaleHeight = aHeightPercentage; - iClientWindows[i].iAutoScaleType = EAutoScaleNone; - if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler)) + parameterChanged = EFalse; + + if (aWidthPercentage != iClientWindows[i].iScaleWidth || + aHeightPercentage != iClientWindows[i].iScaleHeight || + EAutoScaleNone != iClientWindows[i].iAutoScaleType) + { + iClientWindows[i].iScaleWidth = aWidthPercentage; + iClientWindows[i].iScaleHeight = aHeightPercentage; + iClientWindows[i].iAutoScaleType = EAutoScaleNone; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters for window pos %d have not changed", i); + } + + // We only need to redraw if the scale parameters have changed, or the area of the video to + // display (i.e the intersection of client crop region and surface crop rectangle) has changed. + if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))) { User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion)); } } - - if (IsSurfaceCreated() && iExtDisplayConnected && iExtDisplayHandler && (aCropRegion != prevCropRegion)) + + // We only need to redraw if the area of the video to display (i.e the + // intersection of client crop region and surface crop rectangle) has changed. + if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)) { User::LeaveIfError(RedrawWindows(aCropRegion)); } @@ -570,10 +745,24 @@ TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle); User::LeaveIfError(pos); - - iClientWindows[pos].iClipRect = aWindowClipRect; - UpdateCropRegionL(aCropRegion, pos); + TBool parameterChanged = EFalse; + if (aWindowClipRect != iClientWindows[pos].iClipRect) + { + // We only want to redraw if the change in the clipping rectangle would result + // in a change to the area of the display used for the video. + // The video is always displayed in the intersection of the clipping rectangle + // and the video extent, so check if this has changed. + parameterChanged = IntersectionAreaChanged(iClientWindows[pos].iClipRect, aWindowClipRect, iClientWindows[pos].iVideoExtent); + + iClientWindows[pos].iClipRect = aWindowClipRect; + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL - Clip rect parameter has not changed"); + } + + UpdateCropRegionL(aCropRegion, pos, parameterChanged); DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL ---"); } @@ -587,10 +776,19 @@ TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle); User::LeaveIfError(pos); - - iClientWindows[pos].iVideoExtent = aVideoExtent; - UpdateCropRegionL(aCropRegion, pos); + TBool parameterChanged = EFalse; + if (aVideoExtent != iClientWindows[pos].iVideoExtent) + { + iClientWindows[pos].iVideoExtent = aVideoExtent; + parameterChanged = ETrue; + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL - Video extent parameter has not changed"); + } + + UpdateCropRegionL(aCropRegion, pos, parameterChanged); DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL ---"); } @@ -656,8 +854,8 @@ break; default: // Should never get to default unless there's been some programming error. - User::Invariant(); - break; + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument); + return KErrArgument; } TReal32 viewportAspect = pixelAspectRatio * inputWidth / inputHeight; @@ -828,8 +1026,8 @@ break; default: // Should never get to default unless there's been some programming error. - User::Invariant(); - break; + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument); + return KErrArgument; } DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewport2 %d,%d - %d,%d", viewport.iTl.iX, viewport.iTl.iY, viewport.iBr.iX, viewport.iBr.iY); @@ -924,8 +1122,9 @@ break; default: // Should never get to default unless there's been some programming error. - User::Invariant(); - // This is never reached, just to keep the compiler happy + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- Failed due to %d bad aRotation argument", aRotation); + __ASSERT_DEBUG(FALSE, User::Invariant()); + // Use the normal option otherwise orientation = CFbsBitGc::EGraphicsOrientationNormal; } DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- return %d", orientation); @@ -978,34 +1177,8 @@ if(iClientRequestedExtDisplaySwitching != aControl) { - iClientRequestedExtDisplaySwitching = aControl; - - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL SurfaceCreated %d", IsSurfaceCreated()); - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL Client window count %d", iClientWindows.Count()); - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL External Display Connected %d", iExtDisplayConnected); - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL Client Requested Ext Display Switching %d", iClientRequestedExtDisplaySwitching); - - if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iExtDisplayConnected) - { - if(iClientRequestedExtDisplaySwitching) - { - TRAPD(err, CreateExtDisplayHandlerL()); - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL CreateExtDisplayHandlerL error %d", err); - if(err == KErrNone) - { - RemoveBackgroundSurface(ETrue); - SetWindowArrayPtr2Ext(); - RedrawWindows(iCropRegion); - } - } - else if(iExtDisplayHandler) - { - RemoveBackgroundSurface(ETrue); - RemoveExtDisplayHandler(); - SetWindowArrayPtr2Client(); - RedrawWindows(iCropRegion); - } - } + iClientRequestedExtDisplaySwitching = aControl; + SwitchSurface(); } DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL ---"); @@ -1018,28 +1191,7 @@ if(iExtDisplayConnected != aExtDisplayConnected) { iExtDisplayConnected = aExtDisplayConnected; - - if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching) - { - if(iExtDisplayConnected) - { - TRAPD(err, CreateExtDisplayHandlerL()); - DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected CreateExtDisplayHandlerL error %d", err); - if(err == KErrNone) - { - RemoveBackgroundSurface(ETrue); - SetWindowArrayPtr2Ext(); - RedrawWindows(iCropRegion); - } - } - else if(iExtDisplayHandler) - { - RemoveBackgroundSurface(ETrue); - RemoveExtDisplayHandler(); - SetWindowArrayPtr2Client(); - RedrawWindows(iCropRegion); - } - } + SwitchSurface(); } else { @@ -1054,6 +1206,7 @@ DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client +++"); iWindowsArrayPtr = &iClientWindows; + iSwitchedToExternalDisplay = EFalse; DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client ---"); } @@ -1063,6 +1216,7 @@ DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext +++"); iWindowsArrayPtr = &iExtDisplayWindows; + iSwitchedToExternalDisplay = ETrue; DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext ---"); } @@ -1136,3 +1290,228 @@ } DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin ---"); } + +void CMediaClientVideoDisplayBody::MmcweoFocusWindowGroupChanged() + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged +++"); + + TBool prevClientWindowIsInFocus = iClientWindowIsInFocus; + UpdateFocus(); + + if(prevClientWindowIsInFocus != iClientWindowIsInFocus) + { + SwitchSurface(); + } + + DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged ---"); + } + +TBool CMediaClientVideoDisplayBody::MmcweoIgnoreProcess(TSecureId aId) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess +++"); + + TBool ignore = ETrue; + if (iServerClient) + { + ignore = iServerClient->IgnoreProcess(aId); + } + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess --- return %d", ignore); + return ignore; + } + +void CMediaClientVideoDisplayBody::UpdateFocus() + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus +++"); + + if(!iWsEventObserver) + { + iClientWindowIsInFocus = ETrue; + DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Event Observer is NULL"); + DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---"); + return; + } + + TBool prevClientWindowIsInFocus = iClientWindowIsInFocus; + + TInt focusGroupId; + if(iWsEventObserver->FocusWindowGroupId(focusGroupId) == KErrNone) + { + iClientWindowIsInFocus = EFalse; + TInt count = iClientWindows.Count(); + for(TInt i = 0; i < count; i++) + { + if(iClientWindows[i].iWindow->WindowGroupId() == focusGroupId) + { + iClientWindowIsInFocus = ETrue; + break; + } + } + } + else + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Error retrieving focus WgId from observer"); + iClientWindowIsInFocus = ETrue; + } + + if(iServerClient && (prevClientWindowIsInFocus != iClientWindowIsInFocus)) + { + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged calling server, focus %d", iClientWindowIsInFocus); + iServerClient->FocusChanged(iClientWindowIsInFocus); + } + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateFocus Client window in focus %d", iClientWindowIsInFocus); + DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---"); + } + +void CMediaClientVideoDisplayBody::SwitchSurface() + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface +++"); + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface SurfaceCreated %d", IsSurfaceCreated()); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client window count %d", iClientWindows.Count()); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Requested Ext Display Switching %d", iClientRequestedExtDisplaySwitching); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Window in Focus %d", iClientWindowIsInFocus); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface External Display Connected %d", iExtDisplayConnected); + + if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching && + iClientWindowIsInFocus && iExtDisplayConnected) + { + TRAPD(err, CreateExtDisplayHandlerL()); + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface CreateExtDisplayHandlerL error %d", err); + if(err == KErrNone) + { + // Set background surface for external display window before removing from client windows. + // Required for switching of paused video + SetWindowArrayPtr2Ext(); + RedrawWindows(iCropRegion); + SetWindowArrayPtr2Client(); + RemoveBackgroundSurface(ETrue); + SetWindowArrayPtr2Ext(); + } + } + else if(iSwitchedToExternalDisplay) + { + // Set background surface for clientwindows before removing from external display window. + // Required for switching of paused video + SetWindowArrayPtr2Client(); + RedrawWindows(iCropRegion); + SetWindowArrayPtr2Ext(); + RemoveBackgroundSurface(ETrue); + RemoveExtDisplayHandler(); + SetWindowArrayPtr2Client(); + } + + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface ---"); + } + +TBool CMediaClientVideoDisplayBody::IsRotationValid(TVideoRotation aVideoRotation) + { + if (aVideoRotation == EVideoRotationNone || + aVideoRotation == EVideoRotationClockwise90 || + aVideoRotation == EVideoRotationClockwise180 || + aVideoRotation == EVideoRotationClockwise270) + { + return ETrue; + } + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsRotationValid - Rotation %d not valid", aVideoRotation); + return EFalse; + } + +TBool CMediaClientVideoDisplayBody::IsAutoScaleTypeValid(TAutoScaleType aAutoScaleType) + { + if (aAutoScaleType == EAutoScaleNone || + aAutoScaleType == EAutoScaleBestFit || + aAutoScaleType == EAutoScaleClip || + aAutoScaleType == EAutoScaleStretch) + { + return ETrue; + } + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsAutoScaleTypeValid - Auto scale %d not valid", aAutoScaleType); + return EFalse; + } + +/** +Check whether a change in the surface crop rectangle would mean that the surface viewport calculated in SetBackgroundSurface would change. +The surface viewport is the intersection of the surface crop rectangle and the client crop region +*/ +TBool CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw(TRect aOldSurfaceCropRect, TRect aNewSurfaceCropRect, TRect aClientCropRegion) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw +++"); + + // If aClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations. + // This means that only aOldSurfaceCropRect is being used to decide which part of the video is displayed. + // By setting aClientCropRect to the same as aOldSurfaceCropRect we ensure that only aOldSurfaceCropRect is + // used in the subsequent intersection area checks. + if (aClientCropRegion.IsEmpty()) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw - Client crop region is empty"); + aClientCropRegion = aOldSurfaceCropRect; + } + + TBool ret = IntersectionAreaChanged(aOldSurfaceCropRect, aNewSurfaceCropRect, aClientCropRegion); + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw --- ret = %d", ret); + + return ret; + } + +/** +Check whether a change in the client crop region would mean that the surface viewport calculated in SetBackgroundSurface would change. +The surface viewport is the intersection of the surface crop rectangle and the client crop region +*/ +TBool CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw(TRect aOldClientCropRegion, TRect aNewClientCropRegion, TRect aSurfaceCropRect) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw +++"); + + // If aOldClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations. + // This means that only aSurfaceCropRect is being used to decide which part of the video is displayed. By + // setting aOldClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is + // used in the subsequent intersection area checks. + if (aOldClientCropRegion.IsEmpty()) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - Old client crop region is empty"); + aOldClientCropRegion = aSurfaceCropRect; + } + + // If aNewClientCropRegion is empty then it will not be used in the SetBackgroundSurface calculations. + // This means that only aSurfaceCropRect will impact which part of the video is displayed. By + // setting aNewClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is + // used in the subsequent intersection area checks. + if (aNewClientCropRegion.IsEmpty()) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - New client crop region is empty"); + aNewClientCropRegion = aSurfaceCropRect; + } + + TBool ret = IntersectionAreaChanged(aOldClientCropRegion, aNewClientCropRegion, aSurfaceCropRect); + + DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw --- ret = %d", ret); + + return ret; + } + +/** +Check whether the change in size of a rectangle means its intersection with another rectangle has changed. +This is used to check whether changes in things like the surface crop rectangle, client crop region, and window clip rectangle, would mean +the area of video displayed would change. +*/ +TBool CMediaClientVideoDisplayBody::IntersectionAreaChanged(TRect aOldRect, TRect aNewRect, TRect aOtherRect) + { + DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOldRect %d,%d - %d,%d", aOldRect.iTl.iX, aOldRect.iTl.iY, aOldRect.iBr.iX, aOldRect.iBr.iY); + DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aNewRect %d,%d - %d,%d", aNewRect.iTl.iX, aNewRect.iTl.iY, aNewRect.iBr.iX, aNewRect.iBr.iY); + DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOtherRect %d,%d - %d,%d", aOtherRect.iTl.iX, aOtherRect.iTl.iY, aOtherRect.iBr.iX, aOtherRect.iBr.iY); + + aOldRect.Intersection(aOtherRect); + aNewRect.Intersection(aOtherRect); + + if (aOldRect != aNewRect) + { + DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged - Intersection area has changed"); + return ETrue; + } + + DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged - Intersection area has not changed"); + return EFalse; + }