sl@0: // Copyright (c) 2008-2009 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: /**
sl@0:  @file
sl@0:  @internalComponent
sl@0: */
sl@0: 
sl@0: #include "mmfsubtitleutility.h"
sl@0: 
sl@0: 
sl@0: CMMFSubtitleUtility* CMMFSubtitleUtility::NewL(RMMFController& aController, RWsSession &aWs)
sl@0: 	{
sl@0: 	CMMFSubtitleUtility* self = new(ELeave) CMMFSubtitleUtility(aController);
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aWs);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;	
sl@0: 	}
sl@0: 
sl@0: CMMFSubtitleUtility::CMMFSubtitleUtility(RMMFController& aController): iSubtitleSupportCustomCommands(aController)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: void CMMFSubtitleUtility::ConstructL(RWsSession &aWs)
sl@0: 	{
sl@0: 	iDevice = new (ELeave) CWsScreenDevice(aWs);
sl@0: 	User::LeaveIfError(iDevice->Construct());
sl@0: 	iSubtitleGc = new (ELeave) CWindowGc(iDevice);
sl@0: 	User::LeaveIfError(iSubtitleGc->Construct());
sl@0: 	}
sl@0: 
sl@0: CMMFSubtitleUtility::~CMMFSubtitleUtility()
sl@0: 	{
sl@0: 	delete iSubtitleGc;
sl@0: 	delete iDevice;
sl@0: 	iSubtitleLanguages.Close();
sl@0: 	iCrpDataArray.Close();
sl@0: 	}
sl@0: 
sl@0: // Add subtitle related config to controller
sl@0: TInt CMMFSubtitleUtility::AddSubtitleConfig(const TMMFSubtitleWindowConfig& aConfig)
sl@0: 	{
sl@0: 	TCrpData crpData(aConfig.iWindowId);
sl@0: 	// Add the crp data before calling custom commands in case append fails
sl@0: 	TInt err = iCrpDataArray.Append(crpData);
sl@0: 	if (KErrNone == err)
sl@0: 		{
sl@0: 		err = iSubtitleSupportCustomCommands.AddSubtitleConfig(aConfig);
sl@0: 	
sl@0: 		if (KErrNone != err)
sl@0: 			{
sl@0: 			// removed the added crp data on error
sl@0: 			iCrpDataArray.Remove(iCrpDataArray.Count()-1);
sl@0: 			}
sl@0: 		}
sl@0: 	
sl@0: 	return err;
sl@0: 	}
sl@0: 
sl@0: // Found the index of the subtitle data in iCrpDataArray given aWindowId
sl@0: TInt CMMFSubtitleUtility::FindCrpArrayIndex(TInt aWindowId)
sl@0: 	{
sl@0: 	TInt ret = KErrNotFound;
sl@0: 	for (TInt i = iCrpDataArray.Count(); --i >= 0; )
sl@0: 		{
sl@0: 		if (iCrpDataArray[i].iWindowId == aWindowId)
sl@0: 			{
sl@0: 			ret = i;
sl@0: 			break;
sl@0: 			}
sl@0: 		}
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: // Remove subtitle related config from controller
sl@0: TInt CMMFSubtitleUtility::RemoveSubtitleConfig(TInt aWindowId)
sl@0: 	{
sl@0: 	TInt ret = FindCrpArrayIndex(aWindowId);
sl@0: 	if (ret >= 0)
sl@0: 		{		
sl@0: 		iCrpDataArray.Remove(ret);
sl@0: 		ret = iSubtitleSupportCustomCommands.RemoveSubtitleConfig(aWindowId);
sl@0: 		}
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: // Update subtitle related config from controller and clear the subtitle region
sl@0: TInt CMMFSubtitleUtility::UpdateSubtitleConfig(const TMMFSubtitleWindowConfig& aConfig)
sl@0: 	{
sl@0: 	TInt ret = FindCrpArrayIndex(aConfig.iWindowId);
sl@0: 	if (ret >= 0)
sl@0: 		{
sl@0: 		// clear the CRP id
sl@0: 		iCrpDataArray[ret].iCrpId.Set(0);
sl@0: 
sl@0: 		ret = iSubtitleSupportCustomCommands.UpdateSubtitleConfig(aConfig);
sl@0: 		}
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: // Return if subtitle is available
sl@0: TBool CMMFSubtitleUtility::SubtitlesAvailable(RMMFController& aController)
sl@0: 	{
sl@0: 	TBool available = EFalse;
sl@0: 	RMMFVideoPlaySubtitleSupportCustomCommands subtitleSupportCustomCommands(aController);
sl@0: 	subtitleSupportCustomCommands.GetSubtitlesAvailable(available);
sl@0: 	return available;
sl@0: 	}
sl@0: 
sl@0: TInt CMMFSubtitleUtility::EnableSubtitles()
sl@0: 	{
sl@0: 	return iSubtitleSupportCustomCommands.EnableSubtitles();
sl@0: 	}
sl@0: 
sl@0: void CMMFSubtitleUtility::DisableSubtitles()
sl@0: 	{
sl@0: 	for (TInt i = iCrpDataArray.Count(); --i >= 0; )
sl@0: 		{
sl@0: 		iSubtitleSupportCustomCommands.RemoveSubtitleConfig(iCrpDataArray[i].iWindowId);
sl@0: 		}
sl@0: 
sl@0: 	iCrpDataArray.Reset();
sl@0: 	
sl@0: 	// still need to send disable command to controller event if array count was 0
sl@0: 	// because window may have been removed after subtitle is enabled
sl@0: 	iSubtitleSupportCustomCommands.DisableSubtitles();
sl@0: 	}
sl@0: 
sl@0: // Helper function to draw CRP
sl@0: void CMMFSubtitleUtility::DrawCrp(RWindow& aWindow, TInt aCrpIdx, TBool aCallBeginRedraw)
sl@0: 	{
sl@0: 	TCrpData& crpData = iCrpDataArray[aCrpIdx];
sl@0: 
sl@0: 	if (crpData.iCrpId.Id() != 0)
sl@0: 		{
sl@0: 
sl@0: 		if (aCallBeginRedraw)
sl@0: 			{
sl@0: 			// CRP is ready to be drawn
sl@0: 			aWindow.Invalidate(crpData.iCrpRect);
sl@0: 			aWindow.BeginRedraw(crpData.iCrpRect);
sl@0: 			}
sl@0: 		
sl@0: 		iSubtitleGc->Activate(aWindow);
sl@0: 		iSubtitleGc->DrawWsGraphic(crpData.iCrpId, crpData.iCrpRect);
sl@0: 		iSubtitleGc->Deactivate();
sl@0: 		
sl@0: 		if (aCallBeginRedraw)
sl@0: 			{
sl@0: 			aWindow.EndRedraw();
sl@0: 			}
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: // Handle CRP ready event from controller and draw the CRP
sl@0: void CMMFSubtitleUtility::HandleCrpReady(RWindow& aWindow)
sl@0: 	{
sl@0: 	TInt index = FindCrpArrayIndex(aWindow.WsHandle());
sl@0: 	if (index >= 0)
sl@0: 		{
sl@0: 		TCrpData& crpData = iCrpDataArray[index];
sl@0: 		TInt err = iSubtitleSupportCustomCommands.GetCrpParameters(aWindow.WsHandle(), 
sl@0: 																	crpData.iCrpId, 
sl@0: 																	crpData.iCrpRect);
sl@0: 
sl@0: 		if (KErrNone == err)
sl@0: 			{
sl@0: 			DrawCrp(aWindow, index, ETrue);
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			// Window may have been removed before the event was received, ignore event
sl@0: 			RDebug::Print(_L("CMMFSubtitleUtility::HandleCrpReady aWindowId=%d, err==%d"), aWindow.WsHandle(), err);
sl@0: 			}
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: // Redraw subtitle CRP if redraw rect intersect with subtitle region
sl@0: void CMMFSubtitleUtility::RedrawSubtitle(RWindow& aWindow, const TRect& aRedrawRect)
sl@0: 	{
sl@0: 	TInt index = FindCrpArrayIndex(aWindow.WsHandle());
sl@0: 	if (index >= 0 && aRedrawRect.Intersects(iCrpDataArray[index].iCrpRect))
sl@0: 		{
sl@0: 		DrawCrp(aWindow, index, EFalse);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: TInt CMMFSubtitleUtility::SetSubtitleLanguage(TLanguage aSubtitleLanguage)
sl@0: 	{
sl@0: 	return iSubtitleSupportCustomCommands.SetSubtitleLanguage(aSubtitleLanguage);
sl@0: 	}
sl@0: 
sl@0: TArray<TLanguage> CMMFSubtitleUtility::SupportedSubtitleLanguagesL()
sl@0: 	{
sl@0: 	TRAPD(err, iSubtitleSupportCustomCommands.GetSupportedSubtitleLanguagesL(iSubtitleLanguages));
sl@0: 	
sl@0: 	// Do not propagate KErrNotSupported; return empty list of languages.
sl@0: 	if (KErrNone != err && KErrNotSupported != err)
sl@0: 		{
sl@0: 		User::Leave(err);
sl@0: 		}
sl@0: 	return iSubtitleLanguages.Array();
sl@0: 	}
sl@0: 
sl@0: TLanguage CMMFSubtitleUtility::SubtitleLanguage()
sl@0: 	{
sl@0: 	TLanguage language = ELangNone;
sl@0: 	
sl@0: 	// ignore returned value, language parameter is unchanged on error
sl@0: 	iSubtitleSupportCustomCommands.GetSubtitleLanguage(language);
sl@0: 
sl@0: 	return language;
sl@0: 	}