--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/ServerCore/Src/alfwindowmanager.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,681 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: ?Description
+*
+*/
+
+
+
+#include <fbs.h>
+
+#include "alfwindowmanager.h"
+#include "alfhierarchymodel.h"
+#include "alfstreamerserver.h"
+#include "alfstreamerbridge.h"
+#include "alfwindow.h"
+#include "alfwindowfxplugin.h"
+#include "alfwindowbuffer.h"
+#include "alfstreamerconsts.h"
+#include "alflogger.h"
+#include "alfwindowdata.h"
+
+#include <ecom.h>
+
+
+struct TPluginInfo
+ {
+ TPluginInfo():iPlugin(0),iDtor(TUid::Uid(0)), iPluginUid(TUid::Uid(0)), iNotifyEnabled(EFalse), iWindowDestroyNotifyEnabled(EFalse)
+ {}
+
+ CAlfWindowFxPlugin* iPlugin;
+ TUid iDtor;
+ TUid iPluginUid;
+ TBool iNotifyEnabled; // flags would be more sophisticated way..
+ TBool iWindowDestroyNotifyEnabled;
+
+ void EnableNotifications(TBool aEnable)
+ {
+ iNotifyEnabled = aEnable;
+ }
+
+ void NotifyNewWindow(const TWindowIdentifier& aId)
+ {
+ if (iNotifyEnabled)
+ iPlugin->NewWindow(aId);
+ }
+ void EnableWindowDestroyNotifications(TBool aEnable)
+ {
+ iWindowDestroyNotifyEnabled = aEnable;
+ }
+
+ void NotifyDestroyWindow(const TWindowIdentifier& aId)
+ {
+ if (iWindowDestroyNotifyEnabled)
+ iPlugin->DestroyWindow(aId);
+ }
+ };
+
+class CAlfWindowManager::TAlfWindowMgrData
+ {
+ public:
+ TInt iScreenId;
+
+ RPointerArray<CAlfWindow> iWindows;
+ RArray<TPluginInfo> iPlugins;
+ CAlfHierarchyModel* iTree;
+
+ RPointerArray<CAlfWindow> iChangedWindows;
+ };
+
+// ---------------------------------------------------------------------------
+// FindPlugin
+// ---------------------------------------------------------------------------
+//
+CAlfWindowFxPlugin* CAlfWindowManager::FindPlugin(const TUid& aPluginUid)
+ {
+ for (TInt i = 0; i <= iData->iPlugins.Count()-1; i++)
+ {
+ if (iData->iPlugins[i].iPluginUid == aPluginUid )
+ {
+ return iData->iPlugins[i].iPlugin;
+ }
+ }
+ return 0;
+ }
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfWindowManager* CAlfWindowManager::NewL(CAlfHierarchyModel* aAlfHierarchy)
+ {
+ CAlfWindowManager* self = new (ELeave) CAlfWindowManager;
+ CleanupStack::PushL(self);
+ self->ConstructL(aAlfHierarchy);
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// destructor
+// ---------------------------------------------------------------------------
+//
+CAlfWindowManager::~CAlfWindowManager()
+ {
+ if (iData)
+ {
+ iData->iWindows.ResetAndDestroy();
+ delete iData;
+ }
+ REComSession::FinalClose();
+ RFbsSession::Disconnect();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CreateNewWindowL
+// For Fx plugins
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfWindow* CAlfWindowManager::CreateNewWindowL(TUint aIndex, const TSize& aSizeInPixels )
+ {
+ if(!RFbsSession::GetSession())
+ {
+ User::LeaveIfError(RFbsSession::Connect());
+ }
+
+ CAlfWindow* window = CAlfWindow::NewL(aIndex,*this, aSizeInPixels);
+ CleanupStack::PushL(window);
+ iData->iWindows.AppendL(window);
+ CleanupStack::Pop();
+
+ TAlfWServInfo wservInfo = window->WsInfo();
+
+ TInt offset;
+ TAlfWindowAttributes* windowAttributes = CreateWindowAttributes( offset );
+ if (windowAttributes)
+ {
+ windowAttributes->iSize = aSizeInPixels;
+ windowAttributes->iScreenNumber = wservInfo.iScreenNumber;
+ windowAttributes->iParentNodeId = wservInfo.iParentRefId.iWindowIdentifer;
+
+ TAlfBridgerData data;
+ data.Set(EAlfDSNewWindow,
+ wservInfo.iRefId.iWindowGroupId,
+ wservInfo.iRefId.iWindowIdentifer,
+ (TAny*)offset);
+
+ User::LeaveIfError(PostIt(data));
+ }
+
+ return window;
+ }
+
+// ---------------------------------------------------------------------------
+// BindWindowToHitch
+//
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::BindWindowToHitchL(CAlfWindow* aWindow, CAlfWindowManager* aMgr)
+ {
+ TAlfWServInfo wservInfo = aWindow->WsInfo();
+
+ TInt offset;
+ TAlfWindowAttributes* windowAttributes = CreateWindowAttributes( offset );
+ if ( !windowAttributes )
+ {
+ return;
+ }
+ windowAttributes->iSize = aWindow->Size();
+ windowAttributes->iPosition = aWindow->Position();
+ windowAttributes->iWindowNodeType = wservInfo.iNodeType;
+ windowAttributes->iScreenNumber = wservInfo.iScreenNumber;
+ windowAttributes->iParentNodeId = wservInfo.iParentRefId.iWindowIdentifer;
+ windowAttributes->iClientHandle = wservInfo.iClientSideId.iWindowIdentifer;
+ windowAttributes->iClientGroupHandle = wservInfo.iClientSideId.iWindowGroupId;
+
+#ifdef ALF_DEBUG_TRACK_DRAWING
+ windowAttributes->iTrackWindow = wservInfo.iTrackWindow;
+#endif
+ TAlfBridgerData data;
+ data.Set(EAlfDSNewWindow,
+ wservInfo.iRefId.iWindowGroupId,
+ wservInfo.iRefId.iWindowIdentifer,
+ (TAny*)offset);
+
+ User::LeaveIfError(aMgr->PostIt(data));
+
+ aWindow->InsertedToScene(ETrue);
+ aWindow->SetPos(aWindow->Position());
+ if (aWindow->Rotation())
+ {
+ aWindow->SetRotation(aWindow->Rotation());
+ }
+
+ if ( aWindow->Opacity() != 1.0f) // different from default
+ {
+ aWindow->SetOpacity(aWindow->Opacity());
+ }
+ aWindow->SetSurfaceExtent(aWindow->SurfaceExtent());
+
+ aWindow->SetActive(aWindow->IsActive());
+ }
+
+// ---------------------------------------------------------------------------
+// CreateNewWindowL
+// for hierarchy model
+// ---------------------------------------------------------------------------
+//
+CAlfWindow* CAlfWindowManager::CreateNewWindowL(TUint aIndex, const TAlfWServInfo& aInfo)
+ {
+ if(!RFbsSession::GetSession())
+ {
+ User::LeaveIfError(RFbsSession::Connect());
+ }
+
+ CAlfWindow* window = CAlfWindow::NewL(aIndex,*this, aInfo.iSize );
+ CleanupStack::PushL(window);
+ iData->iWindows.AppendL(window);
+ CleanupStack::Pop();
+
+ window->SetWsInfo(aInfo);
+
+ // provide notification for plugins that have enabled it
+ for (TInt i = 0; i <= iData->iPlugins.Count()-1; i++)
+ {
+ iData->iPlugins[i].NotifyNewWindow(aInfo.iClientSideId);
+ }
+
+ return window;
+ }
+
+// ---------------------------------------------------------------------------
+// DestroyWindow
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::DestroyWindow(CAlfWindow& aWindow)
+ {
+ TInt i = iData->iWindows.Find(&aWindow);
+ if (i >= 0)
+ {
+ TAlfWServInfo wservInfo = aWindow.WsInfo();
+
+ TInt offset;
+ TAlfWindowAttributes* windowAttributes = CreateWindowAttributes(offset);
+ windowAttributes->iWindowNodeType = wservInfo.iNodeType;
+ windowAttributes->iScreenNumber = wservInfo.iScreenNumber;
+
+ TAlfBridgerData data;
+ data.Set(EAlfDSDestroyWindow,
+ wservInfo.iRefId.iWindowGroupId,
+ wservInfo.iRefId.iWindowIdentifer,
+ (TAny*)offset);
+
+ PostIt(data);
+
+ iData->iWindows.Remove(i);
+ delete &aWindow;
+
+ // provide notification for plugins that have enabled it
+ for (TInt i = 0; i <= iData->iPlugins.Count()-1; i++)
+ {
+ iData->iPlugins[i].NotifyDestroyWindow(wservInfo.iClientSideId);
+ }
+
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// EnableNewWindowNotificationsL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::EnableNewWindowNotificationsL(CAlfWindowFxPlugin& aPlugin,
+ TBool aEnable)
+ {
+ // Assuming the amount of plugins to remain very limited
+ for (TInt i = 0; i <= iData->iPlugins.Count()-1; i++)
+ {
+ if (iData->iPlugins[i].iPluginUid == *aPlugin.Identifier() )
+ {
+ iData->iPlugins[i].EnableNotifications(aEnable);
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// EnableDestroyWindowNotificationsL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::EnableDestroyWindowNotificationsL(CAlfWindowFxPlugin& aPlugin,
+ TBool aEnable )
+ {
+ // Assuming the amount of plugins to remain very limited
+ for (TInt i = 0; i <= iData->iPlugins.Count()-1; i++)
+ {
+ if (iData->iPlugins[i].iPluginUid == *aPlugin.Identifier() )
+ {
+ iData->iPlugins[i].EnableWindowDestroyNotifications(aEnable);
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ReserveL
+// Decaprecated
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfWindow* CAlfWindowManager::ReserveL( const TWindowIdentifier& /*aId*/, TBool aReserveBuffer /*= ETrue*/ )
+ {
+ return 0; // we never get here
+ }
+
+
+// ---------------------------------------------------------------------------
+// Release
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::Release( CAlfWindow& /*aWindow*/, TBool /*aReserveBuffer = ETrue*/ )
+ {
+ /*TInt i = iData->iWindows.Find(&aWindow);
+ if (i >= 0)
+ {
+ CAlfWindow* window = iData->iWindows[i];
+ window->SetReserved( EFalse, aReserveBuffer );
+ if (!window->WsInfo().ExistsInWServ())
+ {
+ __ALFFXLOGSTRING1("CAlfWindowManager::Released, 0x%x", window->Identifier());
+ DestroyWindow( *window, EFalse );
+ }
+ }*/
+ }
+
+// ---------------------------------------------------------------------------
+// ScreenId
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfWindowManager::ScreenId() const
+ {
+ if (iData)
+ {
+ return iData->iScreenId;
+ }
+ return 0;
+ }
+
+
+#ifdef RND_FXPLUGIN_FIX
+// ---------------------------------------------------------------------------
+// GetWinIdListL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::GetWinIdListL(RArray<TWindowIdentifier>& aWinIdList)
+ {
+ // Create list
+ aWinIdList.Reset();
+ for (TInt i=0; i < iData->iWindows.Count(); i++)
+ {
+ if (iData->iWindows[i]->IsActive() && iData->iWindows[i]->IsReserved() == EFalse )
+ {
+ aWinIdList.AppendL( iData->iWindows[i]->WsInfo().iClientSideId ); //\todo shoud this be ordered list?
+ }
+ }
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+// GetWinIdListL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::GetWinIdListL( TInt aWsGroupId, RArray<TWindowIdentifier>& aWinIdList)
+ {
+ // Get list of windows which belong to the window server group specified
+ aWinIdList.Reset();
+ for ( TInt i=0; i < iData->iWindows.Count(); i++ )
+ {
+ if ( iData->iWindows[i]->WsInfo().iClientSideId.iWindowGroupId == aWsGroupId )
+ {
+ aWinIdList.AppendL( iData->iWindows[i]->WsInfo().iClientSideId );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfWindowManager::GetWinInfoListL( TInt aWsGroupId, TInt aClientWindowHandle, RArray<TAlfWServInfo>& aWinInfoList )
+ {
+ aWinInfoList.Reset();
+ for ( TInt i = 0; i < iData->iWindows.Count(); i++ )
+ {
+ if ( iData->iWindows[i]->WsInfo().iClientSideId.iWindowGroupId == aWsGroupId )
+ {
+ if ( aClientWindowHandle == KErrNotFound ||
+ iData->iWindows[i]->WsInfo().iClientSideId.iWindowIdentifer == aClientWindowHandle )
+ {
+ aWinInfoList.AppendL( iData->iWindows[i]->WsInfo() );
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// MoveWindow
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::MoveWindow(CAlfWindow& aWindow, TInt aIndex)
+ {
+ aWindow.Move(aIndex);
+ }
+
+
+// ---------------------------------------------------------------------------
+// SetWindowVisibility
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::SetWindowVisibility(CAlfWindow& /*aWindow*/, TBool /*aVisible*/)
+ {
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// ContentReady
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::ContentReady(CAlfWindow& aWindow, CAlfWindowBuffer* aOutBuffer)
+ {
+ //ASSERT(iData->iChangedWindows.Find(&aWindow) == KErrNotFound); // no plugin should produce more frames
+ // than actually bound to scene
+ iData->iChangedWindows.Append(&aWindow);
+
+ if(!aWindow.IsInsertedToScene())
+ {
+ TRAPD( err, BindWindowToHitchL(&aWindow, this) );
+ if (err)
+ {
+ __ALFLOGSTRING1( "CAlfWindowManager::ContentReady() ignore error: %d", err )
+ }
+ }
+ else
+ {
+ TAlfWServInfo wservInfo = aWindow.WsInfo();
+
+ TInt offset;
+ TAlfWindowAttributes* windowAttributes = CreateWindowAttributes(offset);
+
+ if (windowAttributes)
+ {
+ windowAttributes->iBitmapHandle = aOutBuffer->Handle();
+ TAlfBridgerData d;
+ d.Set(EAlfDSSetCoveringBitmap,
+ wservInfo.iRefId.iWindowGroupId,
+ wservInfo.iRefId.iWindowIdentifer,
+ (TAny*)offset);
+
+ PostIt(d);
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CAlfWindowManager::CAlfWindowManager()
+ {
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::ConstructL(CAlfHierarchyModel* aAlfHierarchy)
+ {
+ iData = new (ELeave) TAlfWindowMgrData;
+ iData->iTree = aAlfHierarchy;
+ }
+
+
+// ---------------------------------------------------------------------------
+// LoadPluginL
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::LoadPluginL(const TUid& aPluginUid)
+ {
+ ASSERT(iData);
+ if ( FindPlugin(aPluginUid) )
+ {
+ User::Leave(KErrAlreadyExists);
+ }
+
+ TUid dtoridkey;
+ CAlfWindowFxPlugin* fxplugin = (CAlfWindowFxPlugin*)REComSession::CreateImplementationL(aPluginUid, dtoridkey);
+ CleanupStack::PushL(fxplugin);
+ fxplugin->ConstructL(*this, EColor16MAP); // TODO: decide buffer format
+ TUid* pluginUid = fxplugin->Identifier();
+
+ ASSERT(pluginUid); // construction was not complete i.e. basecall missing in plugin implementation
+
+ *pluginUid = aPluginUid;
+
+ TPluginInfo info;
+ info.iPlugin = fxplugin;
+ info.iDtor = dtoridkey;
+ info.iPluginUid = aPluginUid;
+ iData->iPlugins.AppendL(info);
+ CleanupStack::Pop();
+ }
+
+
+// ---------------------------------------------------------------------------
+// DestroyPlugin
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::DestroyPlugin(const TUid& aPluginUid)
+ {
+ ASSERT(iData);
+ TPluginInfo info;
+ TInt pluginCount = iData->iPlugins.Count();
+ for (int index = 0; index < pluginCount; index++)
+ {
+ info = iData->iPlugins[index];
+ if (info.iPluginUid == aPluginUid)
+ {
+ delete info.iPlugin;
+ REComSession::DestroyedImplementation(info.iDtor);
+ iData->iPlugins.Remove(index);
+ break;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// HandlePluginMsgL
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::HandlePluginMsgL(const RMessage2& aMessage)
+ {
+ ASSERT(iData);
+ CAlfWindowFxPlugin* fxplugin = FindPlugin(TUid::Uid(aMessage.Int0()));
+ if (fxplugin)
+ {
+ TInt lenght1 = aMessage.GetDesLength(1);
+ TInt lenght2 = aMessage.GetDesMaxLength(2);
+
+ HBufC8* inHBuf = HBufC8::NewLC(lenght1);
+ TPtr8 inBuf = inHBuf->Des();
+ aMessage.ReadL(1,inBuf);
+
+ if ( aMessage.Function() == EAlfDecodSSendSynch )
+ {
+ HBufC8* outBuf = HBufC8::NewLC(lenght2);
+ TPtr8 outptr = outBuf->Des();
+ fxplugin->HandleMessageL(inBuf, outptr);
+
+ if(!aMessage.IsNull())
+ {
+ aMessage.WriteL(2,*outBuf);
+ aMessage.Complete(KErrNone);
+ }
+
+ CleanupStack::PopAndDestroy();
+ }
+ else
+ {
+ fxplugin->HandleMessageL(inBuf, aMessage);
+ }
+
+ CleanupStack::PopAndDestroy();
+ }
+ else
+ {
+ aMessage.Complete(KErrNotFound);
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CancelPluginMsg
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::CancelPluginMsg(const TUid& aPluginUid, TInt aMessageId)
+ {
+ if (!iData)
+ {
+ return;
+ }
+
+ if (aPluginUid == KNullUid)
+ {
+ for (TInt i = iData->iPlugins.Count()-1; i >= 0 ; i--)
+ {
+ iData->iPlugins[i].iPlugin->CancelMessage(aMessageId);
+ }
+ }
+ else
+ {
+ CAlfWindowFxPlugin* fxplugin = FindPlugin(aPluginUid);
+ if (fxplugin)
+ {
+ fxplugin->CancelMessage(aMessageId);
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// PostIt
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfWindowManager::PostIt(const TAlfBridgerData& aData)
+ {
+// RDebug::Print(_L("CAlfWindowManager::PostIt") );
+ return iData->iTree->Server().Bridge()->AddData(aData.iOp, aData.iInt1, aData.iInt2, aData.iPtr);
+ }
+
+// ---------------------------------------------------------------------------
+// Bridge
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfStreamerBridge* CAlfWindowManager::Bridge()
+ {
+ return iData->iTree->Server().Bridge();
+ }
+
+// ---------------------------------------------------------------------------
+// PrepareNewFrame
+// ---------------------------------------------------------------------------
+//
+void CAlfWindowManager::PrepareNewFrame(TUint aEstimatedInterval)
+ {
+ iData->iChangedWindows.Reset();
+ for (TInt i = iData->iPlugins.Count()-1; i >= 0 ; i--)
+ {
+ TRAP_IGNORE(iData->iPlugins[i].iPlugin->PrepareFrameL(aEstimatedInterval));
+ // for now, just ignore error. When collecting complete frames, we could use this info though
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TAlfWindowAttributes* CAlfWindowManager::CreateWindowAttributes(TInt& aIndex)
+ {
+ TAlfWindowAttributes empty;
+ TAlfWindowAttributes* attributes = NULL;
+ TRAP_IGNORE(attributes = (TAlfWindowAttributes*)Bridge()->AppendVarDataL( sizeof(TAlfWindowAttributes), aIndex ))
+ *attributes = empty;
+ return attributes;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TAlfWindowCommandBufferAttributes* CAlfWindowManager::CreateWindowCommandBufferAttributes(TInt& aIndex)
+ {
+ TAlfWindowCommandBufferAttributes empty;
+ TAlfWindowCommandBufferAttributes* windowCommandBuffer = NULL;
+ TRAP_IGNORE(windowCommandBuffer = (TAlfWindowCommandBufferAttributes*)Bridge()->AppendVarDataL( sizeof(TAlfWindowCommandBufferAttributes), aIndex ))
+ *windowCommandBuffer = empty;
+ return windowCommandBuffer;
+ }