--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/ServerCore/Src/alfbridge.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,5513 @@
+/*
+* 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: AppUi class
+*
+*/
+
+
+#include <apgtask.h>
+#include <AknDoc.h>
+#include "alf/alfappui.h"
+#include "alf/alfappserver.h"
+#include <uiacceltk/HuiEnv.h>
+#include <aknenv.h>
+#include <AknsConstants.h>
+#include <s32mem.h>
+#include <uiacceltk/HuiSkin.h>
+#include <uiacceltk/HuiDisplay.h>
+#include <uiacceltk/HuiControl.h>
+#include <uiacceltk/HuiControlGroup.h>
+#include <uiacceltk/HuiEvent.h>
+#include <uiacceltk/HuiDeckLayout.h>
+#include <uiacceltk/HuiImageVisual.h>
+#include <uiacceltk/HuiTransformation.h>
+#include <uiacceltk/HuiBorderBrush.h>
+#include <uiacceltk/HuiUtil.h>
+#include <uiacceltk/HuiTextVisual.h>
+#include <uiacceltk/HuiGradientBrush.h>
+#include <uiacceltk/HuiImageBrush.h>
+#include <uiacceltk/HuiRoster.h>
+
+#ifdef ALF_USE_CANVAS
+#include <uiacceltk/HuiCanvasVisual.h>
+#endif
+
+#include "alflogger.h"
+#include "alf/alfappsrvsessionbase.h"
+#include "alfsrvresourcemanager.h"
+#include "alfsrvsettingshandler.h"
+#include <uiacceltk/HuiTextureManager.h>
+#include "alfsrvtexturemanager.h"
+
+#include "alfstreamerserver.h"
+#include "alfshareddisplaycoecontrol.h"
+#include "alfbridge.h"
+#include "alfstreamerconsts.h"
+#include "alfscreen.h"
+#include <akntranseffect.h>
+
+#include "alfwindowmanager.h"
+#include "alfwindowstructs.h"
+#include <e32property.h>
+#include "HuiFxEffect.h"
+#include <akntransitionutils.h>
+#include <alf/AlfTransEffectPlugin.h>
+#include "alfwindowdata.h"
+#include "huieffectable.h"
+#include <akntranseffect.h>
+#include "HuiRenderPlugin.h"
+#include "huicanvasgc.h"
+#include "huicanvasrenderbuffer.h"
+
+#ifdef HUI_DEBUG_TRACK_DRAWING
+#include <alfcommanddebug.h>
+#endif
+
+#ifdef _ALF_FXLOGGING
+#include <alfcommanddebug.h>
+#endif
+
+#ifdef SYMBIAN_BUILD_GCE
+#include <bautils.h>
+#endif
+
+const TInt KVisualTransformationStepRotate = 0;
+
+const TReal32 KAlfVisualDefaultOpacity = 1.0f;
+//const TReal32 KAlfVisualDefaultOpacity = 0.5f;
+
+_LIT8(KAlfWindowGroupContainerControlTag, "WGROUP");
+const TInt KAlfNumberOfFixedControlGroups = 2;
+
+// This debug option prints window group order with __ALFLOGSTRING
+//#define ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+
+// This debug option shows window groups in a grid
+//#define ALF_DEBUG_VISUALIZE_WINDOWGROUP_ORDER
+
+
+const TInt KFadeAction = 6000;
+
+const TInt KRosterFreezeEndTimeoutInMs = 400;
+
+// Timer to send finish full screen effect
+// ---------------------------------------------------------
+// CAlfFinishTimer
+// ---------------------------------------------------------
+//
+NONSHARABLE_CLASS( CAlfRosterFreezeEndTimer ):public CTimer
+ {
+ public: // Constructors and destructor
+ static CAlfRosterFreezeEndTimer* NewL( CAlfBridge& aBridge );
+ virtual ~CAlfRosterFreezeEndTimer();
+
+ public: // New functions
+ void Start( TTimeIntervalMicroSeconds32 aPeriod );
+
+ protected: // Functions from base classes
+ void DoCancel();
+
+ private:
+ CAlfRosterFreezeEndTimer( CAlfBridge& aBridge );
+ void ConstructL();
+ void RunL();
+
+ private: // Data
+ CAlfBridge& iBridge;
+
+ };
+
+
+// ---------------------------------------------------------
+// CAlfRosterFreezeEndTimer
+// ---------------------------------------------------------
+//
+CAlfRosterFreezeEndTimer::CAlfRosterFreezeEndTimer( CAlfBridge& aBridge )
+ :CTimer ( EPriorityStandard ),
+ iBridge( aBridge )
+ {
+ }
+
+void CAlfRosterFreezeEndTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add( this );
+ }
+
+CAlfRosterFreezeEndTimer* CAlfRosterFreezeEndTimer::NewL( CAlfBridge& aBridge )
+ {
+ CAlfRosterFreezeEndTimer* self = new ( ELeave ) CAlfRosterFreezeEndTimer( aBridge );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CAlfRosterFreezeEndTimer::~CAlfRosterFreezeEndTimer()
+ {
+ Cancel();
+ }
+
+void CAlfRosterFreezeEndTimer::Start( TTimeIntervalMicroSeconds32 aPeriod )
+ {
+ if (!IsActive())
+ {
+ After( aPeriod );
+ }
+ }
+
+void CAlfRosterFreezeEndTimer::RunL()
+ {
+ iBridge.iHuiEnv->Display(0).SetDirty();
+ TRAP_IGNORE(iBridge.iHuiEnv->Display(0).Roster().FreezeVisibleContentL(EFalse));
+ iBridge.SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+void CAlfRosterFreezeEndTimer::DoCancel()
+ {
+ CTimer::DoCancel();
+ }
+
+// ---------------------------------------------------------
+// CAlfLayoutSwitchEffectcoordinator
+// ---------------------------------------------------------
+//
+NONSHARABLE_CLASS( CAlfLayoutSwitchEffectCoordinator ) : public CBase, public MAlfGfxEffectObserver
+ {
+ public: // Constructors and destructor
+ CAlfLayoutSwitchEffectCoordinator( CAlfBridge& aBridge );
+ virtual ~CAlfLayoutSwitchEffectCoordinator();
+
+ public: // MAlfGfxEffectObserver
+ void AlfGfxEffectEndCallBack( TInt aHandle );
+
+ public:
+ void BeginLayoutSwitch();
+ void Cancel();
+
+ private:
+ AknTransEffect::TContext NextLayoutSwitchContext();
+ void SetLayoutSwitchEffect(AknTransEffect::TContext aContext);
+ TBool LayoutSwitchEffectsExist();
+
+ private: // Data
+
+ CAlfBridge& iBridge;
+ AknTransEffect::TContext iLayoutSwitchEffectContext;
+ TThreadPriority iOriginalPriority;
+ CAlfRosterFreezeEndTimer* iRosterFreezeEndTimer;
+ };
+
+CAlfLayoutSwitchEffectCoordinator::CAlfLayoutSwitchEffectCoordinator( CAlfBridge& aBridge ) :
+ iBridge( aBridge ),
+ iLayoutSwitchEffectContext(AknTransEffect::ENone)
+ {
+ RThread me = RThread();
+ iOriginalPriority = me.Priority();
+ me.Close();
+ }
+
+CAlfLayoutSwitchEffectCoordinator::~CAlfLayoutSwitchEffectCoordinator()
+ {
+ }
+
+// ---------------------------------------------------------
+// CAlfLayoutSwitchEffectCoordinator::AlfGfxEffectEndCallBack
+//
+// This method is callback which gets called when layout
+// switch effect has ended.
+// ---------------------------------------------------------
+//
+void CAlfLayoutSwitchEffectCoordinator::AlfGfxEffectEndCallBack( TInt aHandle )
+ {
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::AlfGfxEffectEndCallBack"));
+ if (iLayoutSwitchEffectContext == aHandle)
+ {
+ AknTransEffect::TContext nextContext = NextLayoutSwitchContext();
+
+ // Unfreeze visible content. This reveals real roster content (in new orientation).
+ if (nextContext == AknTransEffect::ELayoutSwitchExit)
+ {
+ #ifdef HUI_DEBUG_TRACK_DRAWING
+ RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::AlfGfxEffectEndCallBack unfreezing roster content"));
+ #endif
+ iBridge.iHuiEnv->Display(0).SetDirty();
+ TRAP_IGNORE(iBridge.iHuiEnv->Display(0).Roster().FreezeVisibleContentL(EFalse));
+ iBridge.SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+ // Set next effect
+ SetLayoutSwitchEffect(nextContext);
+
+ if (nextContext == AknTransEffect::ENone)
+ {
+ // Restore normal priority
+ RThread me = RThread();
+ me.SetPriority(iOriginalPriority);
+ me.Close();
+
+ // Just in case refresh everything
+ iBridge.iHuiEnv->Display(0).SetDirty();
+ }
+ }
+ else
+ {
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::AlfGfxEffectEndCallBack - got different handle (normal, dont worry...) - %i"), aHandle);
+ }
+ }
+
+// ---------------------------------------------------------
+// CAlfLayoutSwitchEffectCoordinator::Cancel
+// ---------------------------------------------------------
+//
+void CAlfLayoutSwitchEffectCoordinator::Cancel()
+ {
+ // Disable effect
+ SetLayoutSwitchEffect( AknTransEffect::ENone );
+
+ // Unfreeze visible content
+ if ( iRosterFreezeEndTimer )
+ {
+ iRosterFreezeEndTimer->Cancel();
+ }
+
+ iBridge.iHuiEnv->Display(0).SetDirty();
+ TRAP_IGNORE(iBridge.iHuiEnv->Display(0).Roster().FreezeVisibleContentL(EFalse));
+ iBridge.SetVisualTreeVisibilityChanged(ETrue);
+
+ // Restore normal priority
+ RThread me = RThread();
+ me.SetPriority(iOriginalPriority);
+ me.Close();
+ }
+
+// ---------------------------------------------------------
+// CAlfLayoutSwitchEffectCoordinator::BeginLayoutSwitch
+//
+// This method starts the layout switch effect procedure.
+// ---------------------------------------------------------
+//
+void CAlfLayoutSwitchEffectCoordinator::BeginLayoutSwitch()
+ {
+ // Hm. what to do if earlier is already in progress ?
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::BeginLayoutSwitch"));
+ if ( iBridge.iHuiEnv->MemoryLevel() <= EHuiMemoryLevelLowest )
+ {
+ // No effects in low memory mode
+ return;
+ }
+
+ if (!iLayoutSwitchEffectContext)
+ {
+ TBool tfxOn = CAknTransitionUtils::TransitionsEnabled(AknTransEffect::ELayoutswitchTransitionsOff );
+ TBool tfxExists = LayoutSwitchEffectsExist();
+ if (tfxOn && tfxExists)
+ {
+ // Boost priority so that we are able to draw more frames for the effect
+ RThread me = RThread();
+ me.SetPriority(EPriorityAbsoluteHigh);
+ me.Close();
+
+ // Freeze visual content
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::BeginLayoutSwitch freezing roster content"));
+ iBridge.iHuiEnv->Display(0).SetDirty();
+ TRAP_IGNORE(iBridge.iHuiEnv->Display(0).Roster().FreezeVisibleContentL(ETrue));
+
+ // Remove all other effects
+ iBridge.HandleGfxStopEvent( EFalse );
+ iBridge.RemoveAllTemporaryPresenterVisuals();
+
+ // Set first layout switch effect
+ SetLayoutSwitchEffect(AknTransEffect::ELayoutSwitchStart);
+ }
+ else
+ {
+ if (!iRosterFreezeEndTimer)
+ {
+ TRAP_IGNORE(iRosterFreezeEndTimer = CAlfRosterFreezeEndTimer::NewL(iBridge));
+ }
+
+ if (iRosterFreezeEndTimer)
+ {
+ iBridge.iHuiEnv->Display(0).SetDirty();
+ TRAP_IGNORE(iBridge.iHuiEnv->Display(0).Roster().FreezeVisibleContentL(ETrue));
+
+ // Remove all other effects
+ iBridge.HandleGfxStopEvent( EFalse );
+ iBridge.RemoveAllTemporaryPresenterVisuals();
+
+ // Set remove freeze timer
+ iRosterFreezeEndTimer->Start(KRosterFreezeEndTimeoutInMs*1000);
+ }
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::BeginLayoutSwitch - tfx are set OFF -> I am not starting effect."));
+ }
+ }
+ else
+ {
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::BeginLayoutSwitch - old effect exists - %i"), iLayoutSwitchEffectContext);
+ }
+ }
+
+// ---------------------------------------------------------
+// CAlfLayoutSwitchEffectCoordinator::NextLayoutSwitchContext
+//
+// This method automatically selects the next context in the
+// layout switch procedure.
+//
+// Contextes change in the following order during layout switch:
+//
+// 1. AknTransEffect::ENone
+// 2. AknTransEffect::ELayoutSwitchStart
+// 3. AknTransEffect::ELayoutSwitchExit
+// 4. AknTransEffect::ENone
+//
+// After new context is selected, appropriate effect is set
+// (and/or removed) from the roster.
+//
+// ---------------------------------------------------------
+//
+AknTransEffect::TContext CAlfLayoutSwitchEffectCoordinator::NextLayoutSwitchContext()
+ {
+ // Resolve next context based on current context
+ AknTransEffect::TContext newContext = AknTransEffect::ENone;
+ switch (iLayoutSwitchEffectContext)
+ {
+ case AknTransEffect::ENone:
+ {
+ newContext = AknTransEffect::ELayoutSwitchStart;
+ break;
+ }
+ case AknTransEffect::ELayoutSwitchStart:
+ {
+ newContext = AknTransEffect::ELayoutSwitchExit;
+ break;
+ }
+ case AknTransEffect::ELayoutSwitchExit: // fallthrough
+ default:
+ {
+ newContext = AknTransEffect::ENone;
+ break;
+ }
+ }
+
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::NextLayoutSwitchEffectL old ctx = %i, new ctx = %i"), iLayoutSwitchEffectContext, newContext);
+ return newContext;
+ }
+
+// ---------------------------------------------------------
+// CAlfLayoutSwitchEffectCoordinator::SetLayoutSwitchEffectL
+//
+// This method sets correct effect based on the given
+// layout switch context.
+//
+// ---------------------------------------------------------
+//
+void CAlfLayoutSwitchEffectCoordinator::SetLayoutSwitchEffect(AknTransEffect::TContext aContext)
+ {
+ MHuiEffectable* effectable = iBridge.iHuiEnv->Display(0).Roster().Effectable();
+ CHuiFxEffect* effect = NULL;
+ CHuiFxEngine* engine = iBridge.iHuiEnv->EffectsEngine();
+
+ if (!effectable || !engine)
+ {
+ return;
+ }
+
+ // Update current context
+ iLayoutSwitchEffectContext = aContext;
+
+ if (aContext == AknTransEffect::ENone)
+ {
+ // Just remove effect
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::NextLayoutSwitchEffectL - removing effect"));
+ effectable->EffectSetEffect(NULL); // This calls AlfGfxEffectEndCallBack
+ }
+ else
+ {
+ // Load correct effect
+ for ( TInt i = 0; i<iBridge.iAlfRegisteredEffects.Count(); i++ )
+ {
+ if ( iBridge.iAlfRegisteredEffects[i].iAction == aContext)
+ {
+ //RDebug::Print(_L("CAlfLayoutSwitchEffectCoordinator::SetLayoutSwitchEffectL - loading effect"));
+ TRAP_IGNORE(engine->LoadEffectL(*iBridge.iAlfRegisteredEffects[i].iEffectFile, effect, effectable, NULL, this, iLayoutSwitchEffectContext, 0 ) );
+ break;
+ }
+ }
+ }
+ }
+
+TBool CAlfLayoutSwitchEffectCoordinator::LayoutSwitchEffectsExist()
+ {
+ TBool appearExists = EFalse;
+ TBool disAppearExists = EFalse;
+
+ for ( TInt i = 0; i<iBridge.iAlfRegisteredEffects.Count(); i++ )
+ {
+ if ( iBridge.iAlfRegisteredEffects[i].iAction == AknTransEffect::ELayoutSwitchStart)
+ {
+ disAppearExists = ETrue;
+ break;
+ }
+ else if ( iBridge.iAlfRegisteredEffects[i].iAction == AknTransEffect::ELayoutSwitchExit)
+ {
+ appearExists = ETrue;
+ break;
+ }
+ }
+
+ return (appearExists || disAppearExists);
+ }
+
+// Timer to send finish full screen effect
+// ---------------------------------------------------------
+// CAlfFinishTimer
+// ---------------------------------------------------------
+//
+NONSHARABLE_CLASS( CAlfEffectEndTimer ):public CTimer
+ {
+ public: // Constructors and destructor
+ static CAlfEffectEndTimer* NewL( CAlfBridge& aBridge );
+ virtual ~CAlfEffectEndTimer();
+
+ public: // New functions
+ void Start( TTimeIntervalMicroSeconds32 aPeriod, TInt aHandle );
+
+ protected: // Functions from base classes
+ void DoCancel();
+
+ private:
+ CAlfEffectEndTimer( CAlfBridge& aBridge );
+ void ConstructL();
+ void RunL();
+
+ private: // Data
+ CAlfBridge& iBridge;
+ TInt iHandle;
+
+ };
+
+
+// ---------------------------------------------------------
+// CAlfFinishTimer
+// ---------------------------------------------------------
+//
+CAlfEffectEndTimer::CAlfEffectEndTimer( CAlfBridge& aBridge )
+ :CTimer(EPriorityHigh),
+ iBridge(aBridge)
+ {
+ }
+
+void CAlfEffectEndTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add( this );
+ }
+
+CAlfEffectEndTimer* CAlfEffectEndTimer::NewL( CAlfBridge& aBridge )
+ {
+ CAlfEffectEndTimer* self = new ( ELeave ) CAlfEffectEndTimer( aBridge );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CAlfEffectEndTimer::~CAlfEffectEndTimer()
+ {
+ Cancel();
+ }
+
+void CAlfEffectEndTimer::Start( TTimeIntervalMicroSeconds32 aPeriod, TInt aHandle )
+ {
+ iHandle = aHandle;
+ After( aPeriod );
+ }
+
+void CAlfEffectEndTimer::RunL()
+ {
+ //
+ // timer completes and control is returned to caller
+ //
+ iBridge.TransitionFinishedHandlerL( iHandle );
+ // We don't become active unless we are explicitly restarted
+ }
+
+void CAlfEffectEndTimer::DoCancel()
+ {
+ CTimer::DoCancel();
+ }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CAlfBridge* CAlfBridge::NewL( CAlfStreamerBridge** aHost, CHuiEnv* aEnv )
+ {
+ CAlfBridge* self = new (ELeave) CAlfBridge( aHost );
+ CleanupStack::PushL( self );
+ self->ConstructL( aEnv );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ProvideBitmapL(TInt /*aId*/, CFbsBitmap*& aBitmap, CFbsBitmap*& aMaskBitmap)
+ {
+ aBitmap = iHack;
+ aMaskBitmap = iDummyMask;
+ };
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CAlfBridge::CAlfBridge(CAlfStreamerBridge** aHost)
+ : iHost(aHost), iCurrentMemoryLevel(EHuiMemoryLevelNormal)
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CAlfBridge::~CAlfBridge()
+ {
+ delete iFadeEffectFile;
+ iWindowHashArray.Close();
+ for( TInt i = 0; i< iAlfRegisteredEffects.Count(); i++ )
+ {
+ delete iAlfRegisteredEffects[i].iEffectFile;
+ }
+ iAlfRegisteredEffects.Close();
+ iFinishedEffects.Close();
+ delete iEffectEndTimer;
+ iDeadControlGroups.Close();
+ iEffectWindowGroups.Close();
+ delete iFullScreenEffectData;
+
+ if (iActivated)
+ {
+ iBridgerClient.Close();
+ }
+
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ delete iCommandDebug;
+#endif
+ delete iCursorTimer;
+ delete iLayoutSwitchEffectCoordinator;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ConstructL(CHuiEnv* aEnv)
+ {
+ iHuiEnv = aEnv;
+
+#ifdef SYMBIAN_BUILD_GCE
+ iPrintFPS = EFalse;
+#ifndef __WINSCW__
+ _LIT(KRDSupport, "c:\\resource\\errrd" );
+ RFs& fs = CHuiStatic::FsSession();
+ if (fs.Handle() && BaflUtils::FileExists( fs, KRDSupport ))
+ {
+ iPrintFPS = ETrue;
+ }
+#endif
+#endif //SYMBIAN_BUILD_GCE
+ // create the key for indication transition ends
+ // No access restrictions for starters
+ TInt err = RProperty::Define( KPSAlfDomain, KAlfTransitionStatus,
+ RProperty::EInt );
+ if (!err)
+ {
+ // Initialize to no transition
+ RProperty::Set( KPSAlfDomain, KAlfTransitionStatus, 0 );
+ }
+
+ iEffectEndTimer = CAlfEffectEndTimer::NewL( *this );
+ iWindowHashArray.ReserveL( 500 );
+ iAlfRegisteredEffects.ReserveL(10);
+
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ iCommandDebug = CAlfCommandDebug::NewL();
+#endif
+
+ iLayoutSwitchEffectCoordinator = new (ELeave) CAlfLayoutSwitchEffectCoordinator(*this);
+ iAlfSecureId = RThread().SecureId();
+ RegisterFadeEffectL();
+ }
+
+// ---------------------------------------------------------------------------
+// RegisterFadeEffectL
+//
+// Note, If theme DOES NOT register its own fade effect, another hardcoded fade
+// effect will be used instead. For example, if theme effects are turned off,
+// a fade that does not belong to the theme may be in use.
+// ---------------------------------------------------------------------------
+void CAlfBridge::RegisterFadeEffectL()
+ {
+ // TODO: RND, REMOVE MMC DRIVE-F, WHEN NOT REQUIRED FOR TESTING
+ _LIT(KDrivePrefence,"FZC");
+ // Force register fade effect. Try first MMC, then ROM.
+ CHuiFxEngine* engine = iHuiEnv->EffectsEngine();
+ RFs& fs = CHuiStatic::FsSession();
+ if (fs.Handle() && engine)
+ {
+ _LIT(KFadeEffectPath, ":\\resource\\effects\\fade_effect.fxml");
+ TBufC<4> drives(KDrivePrefence);
+ HBufC* effectFullName = HBufC::NewLC(KFadeEffectPath().Length() + 1);
+
+ for(TInt i=0; i< drives.Length(); i++)
+ {
+ effectFullName->Des().Copy(drives.Mid(i,1));
+ effectFullName->Des().Append(KFadeEffectPath);
+
+ if (BaflUtils::FileExists( fs, *effectFullName ))
+ {
+ DoRegisterEffectL(*effectFullName, KFadeAction);
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy(effectFullName);
+ DoSetCachedFadeEffectL();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// DoSetCachedFadeEffectL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::DoSetCachedFadeEffectL()
+ {
+ for (TInt i = 0; i < iAlfRegisteredEffects.Count(); i++)
+ {
+ //KFadeAction = 6000, indicating the action corroposnds to fading
+ if (iAlfRegisteredEffects[i].iAction == KFadeAction)
+ {
+ delete iFadeEffectFile;
+ iFadeEffectFile = NULL;
+ iFadeEffectFile = iAlfRegisteredEffects[i].iEffectFile->AllocL();
+ __ALFLOGSTRING1( ">> Setting fade effect file %S", iFadeEffectFile );
+ break;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// AddNewScreenL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::AddNewScreenL(CAlfSharedDisplayCoeControl* aSharedCoeControl)
+ {
+ TInt screenNumber = iAlfScreens.Count(); // \todo this might not be the same as real WServ screen number
+
+ // We do not yet support drawing winGC draw commands to other than primary screen.
+ // As fully functional and tested implementation is not there, better to panic here.
+ if (screenNumber!=0)
+ {
+ __ALFLOGSTRING("CAlfBridge::AddNewScreenL. Fatal error! Only screen 0 is supported in Alf server!");
+ User::Invariant();
+ }
+
+ CAlfScreen* screen = new(ELeave) CAlfScreen();
+ CleanupStack::PushL(screen);
+ screen->ConstructL(screenNumber, *this, *iHuiEnv, aSharedCoeControl);
+ iAlfScreens.AppendL( screen );
+ CleanupStack::Pop(screen);
+
+ ShowControlGroupL(screen->iDisplay->Roster(), *(screen->iFloatingSpriteControlGroup), KHuiRosterShowAtTop, screenNumber);
+ ShowControlGroupL(screen->iDisplay->Roster(), *(screen->iFullscreenEffectControlGroup), KHuiRosterShowAtTop, screenNumber);
+
+
+ screen->iFloatingSpriteControlGroup->SetAcceptInput(EFalse);
+ screen->iFullscreenEffectControlGroup->SetAcceptInput(EFalse);
+ }
+
+//------------------------------------------------------------------------------
+// Dumdidumdidum..
+//------------------------------------------------------------------------------
+void CAlfBridge::AddNewScreenFromWindowL(RWindow* aWindow)
+ {
+ TInt screenNumber = iAlfScreens.Count(); // \todo this might not be the same as real WServ screen number
+
+ CAlfScreen* screen = new(ELeave) CAlfScreen();
+ CleanupStack::PushL(screen);
+ screen->ConstructL(screenNumber, *this, *iHuiEnv, aWindow);
+ iAlfScreens.AppendL( screen );
+ CleanupStack::Pop(screen);
+
+ ShowControlGroupL(screen->iDisplay->Roster(), *(screen->iFloatingSpriteControlGroup), KHuiRosterShowAtTop, screenNumber);
+ ShowControlGroupL(screen->iDisplay->Roster(), *(screen->iFullscreenEffectControlGroup), KHuiRosterShowAtTop, screenNumber);
+
+ screen->iFloatingSpriteControlGroup->SetAcceptInput(EFalse);
+ screen->iFullscreenEffectControlGroup->SetAcceptInput(EFalse);
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// AddVisual
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::AddVisual(
+ TInt aWindowNodeId,
+ TInt aClientSideId,
+ TInt aClientSideGroupId,
+ CHuiCanvasVisual* aVisual )
+ {
+ __ALFFXLOGSTRING1("CAlfBridge::AddVisual 0x%x", aWindowNodeId);
+ THashVisualStruct visualStruct( aVisual, aClientSideId, aClientSideGroupId);
+ iWindowHashArray.Insert( aWindowNodeId, visualStruct );
+ iPreviouslySearchedVisualId = aWindowNodeId;
+ iPreviouslySearchedVisual = aVisual;
+ }
+
+// ---------------------------------------------------------------------------
+// RemoveVisual
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::RemoveVisual( TInt aWindowNodeId )
+ {
+ __ALFFXLOGSTRING1("CAlfBridge::RemoveVisual 0x%x", aWindowNodeId);
+ iWindowHashArray.Remove( aWindowNodeId );
+ iPreviouslySearchedVisualId = 0;
+ }
+
+// ---------------------------------------------------------------------------
+// FindVisual
+// ---------------------------------------------------------------------------
+//
+CHuiCanvasVisual* CAlfBridge::FindVisual(TInt aWindowNodeId )
+ {
+ if ( iPreviouslySearchedVisualId == aWindowNodeId )
+ {
+ return iPreviouslySearchedVisual;
+ }
+
+ THashVisualStruct* visualStruct = iWindowHashArray.Find( aWindowNodeId );
+ if ( visualStruct )
+ {
+ iPreviouslySearchedVisualId = aWindowNodeId;
+ iPreviouslySearchedVisual = visualStruct->iVisual;
+ return iPreviouslySearchedVisual;
+ }
+ __ALFFXLOGSTRING1("CAlfBridge::FindVisual - Visual 0x%x not found", aWindowNodeId);
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// FindVisualByClientSideId
+// ---------------------------------------------------------------------------
+//
+CHuiCanvasVisual* CAlfBridge::FindVisualByClientSideIds(
+ TUint32 aClientSideId,
+ TUint32 aClientSideGroupId )
+ {
+ THashMapIter<TUint32, THashVisualStruct> iter(iWindowHashArray);
+ THashVisualStruct const * node = 0;
+ do
+ {
+ node = iter.NextValue();
+ if (node
+ && (*node).iClientSideId==aClientSideId
+ && (*node).iClientSideGroupId==aClientSideGroupId )
+ {
+ return (*node).iVisual;
+ }
+ }
+ while(node);
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CHuiControlGroup* CAlfBridge::FindControlGroup(TInt aWindowGroupNodeId, TInt aScreenNumber )
+ {
+ for (TInt i=0; i<iAlfScreens[aScreenNumber]->iControlGroups.Count();i++)
+ {
+ if (iAlfScreens[aScreenNumber]->iControlGroups[i].iWindowGroupNodeId == aWindowGroupNodeId)
+ {
+ return iAlfScreens[aScreenNumber]->iControlGroups[i].iControlGroup;
+ }
+ }
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// FindClientWindowGroupId
+// ---------------------------------------------------------------------------
+//
+TInt CAlfBridge::FindClientWindowGroupId( TInt aScreenNumber, CHuiControlGroup& aControlGroup )
+ {
+ for (TInt i=0; i<iAlfScreens[aScreenNumber]->iControlGroups.Count();i++)
+ {
+ if( iAlfScreens[aScreenNumber]->iControlGroups[i].iControlGroup == &aControlGroup )
+ {
+ return iAlfScreens[aScreenNumber]->iControlGroups[i].iClientWindowGroupId;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CHuiControlGroup* CAlfBridge::FindControlGroupByWindowGroupId( TInt aWindowGroupId, TInt& aScreenNumber, TAlfControlGroupEntry** aAlfGroup )
+ {
+ TInt firstWin = aScreenNumber;
+ TInt lastWin = aScreenNumber;
+ if ( aScreenNumber == KErrNotFound )
+ {
+ firstWin = 0;
+ lastWin = iAlfScreens.Count()-1;
+ }
+
+ for ( TInt j = firstWin; j <= lastWin; j++ )
+ {
+ for ( TInt i = 0; i < iAlfScreens[j]->iControlGroups.Count(); i++ )
+ {
+ if ( iAlfScreens[j]->iControlGroups[i].iClientWindowGroupId == aWindowGroupId )
+ {
+ aScreenNumber = j;
+ if ( aAlfGroup != NULL )
+ {
+ *aAlfGroup = &iAlfScreens[j]->iControlGroups[i];
+ }
+ return iAlfScreens[j]->iControlGroups[i].iControlGroup;
+ }
+ }
+ }
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CHuiControlGroup* CAlfBridge::FindControlGroupByAppId( TInt aAppId )
+ {
+ for ( TInt i = 0; i < iAlfScreens[0]->iControlGroups.Count(); i++ )
+ {
+ if ( iAlfScreens[0]->iControlGroups[i].iSecureId == aAppId )
+ {
+ return iAlfScreens[0]->iControlGroups[i].iControlGroup;
+ }
+ }
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+
+void CAlfBridge::ListFamilyTreeL( RPointerArray<CHuiLayout>& aArray, const CHuiLayout* aLayout )
+ {
+ if (aLayout->Count())
+ {
+ aArray.Append(aLayout);
+
+ for(TInt i = 0; i< aLayout->Count(); i++)
+ {
+ ListFamilyTreeL(aArray, (CHuiLayout*)&aLayout->Visual(i));
+ }
+ }
+ else
+ {
+ aArray.Append(aLayout);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::DeleteControlGroupL(TInt aWindowGroupNodeId, TInt aScreenNumber )
+ {
+ for (TInt i=0; i<iAlfScreens[aScreenNumber]->iControlGroups.Count();i++)
+ {
+ if (iAlfScreens[aScreenNumber]->iControlGroups[i].iWindowGroupNodeId == aWindowGroupNodeId)
+ {
+ if (iAlfScreens[aScreenNumber]->iDisplay)
+ {
+ CHuiControl& control = iAlfScreens[aScreenNumber]->iControlGroups[i].iControlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ // wserv has notifed that this control group and its layout should be destroyed. However, we might be
+ // have effect on the layout itself or layout is being drawn as external content. This indicates that
+ // we should not delete the control group at this point, but add it to iDeadControlGroup list, which
+ // is cleared when effect has finished.
+ RPointerArray<CHuiLayout> familyTree;
+ ListFamilyTreeL(familyTree, layout); // recursively dig the family tree
+
+ if (HasActiveEffect(layout))
+ {
+ __ALFFXLOGSTRING1("Layout 0x%x has external content", layout);
+ // EHuiVisualFlagShouldDestroy destroy flag should have come for the windows in this layout already
+ layout->SetFlags(EHuiVisualFlagShouldDestroy);
+ // move this layout to effect control group, where it can still be shown. this control group may be deleted.
+ CHuiControl& control = iAlfScreens[aScreenNumber]->iControlGroups[i].iControlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+
+ for(TInt familyIndex = 0; familyIndex < familyTree.Count();familyIndex++)
+ {
+ control.Remove(familyTree[familyIndex]); // remove ownership from original group
+ }
+
+ control.Remove(layout); // remove ownership from original group
+ // move visuals to safe place. the original group must be destroyed.
+ __ALFFXLOGSTRING1("MOVING 0x%x to effect group", layout);
+ CHuiControl& effectControlGroup = iAlfScreens[0]->iFullscreenEffectControlGroup->Control(0);
+ CHuiLayout* effectControlGroupLayout = (CHuiLayout*) &effectControlGroup.Visual(0);
+ // Transfers ownership of visuals.
+ effectControlGroup.AppendL(layout, effectControlGroupLayout); // this will remove it from the previous layout
+ layout->SetOwner(effectControlGroup);
+
+ for(TInt familyIndex = 0; familyIndex < familyTree.Count();familyIndex++)
+ {
+ familyTree[familyIndex]->SetOwner(effectControlGroup);
+ }
+ }
+ else
+ {
+ // check once more, that the windows in this group are not having effects.
+ // the layout is not have effect, but some child window might.
+ // in this case, the child window effects WILL BE REMOVED.
+ for(TInt familyIndex = 0; familyIndex < familyTree.Count();familyIndex++)
+ {
+ RemoveTemporaryPresenterVisual(familyTree[familyIndex]);
+ }
+ }
+ familyTree.Close();
+ iAlfScreens[aScreenNumber]->iDisplay->Roster().Hide(*iAlfScreens[aScreenNumber]->iControlGroups[i].iControlGroup);
+ __ALFFXLOGSTRING("CAlfBridge::DeleteControlGroupL - Deleting group");
+ iAlfScreens[aScreenNumber]->iControlGroups.Remove(i);
+ iHuiEnv->DeleteControlGroup(aWindowGroupNodeId);
+ __ALFFXLOGSTRING("CAlfBridge::DeleteControlGroupL - Deleting group done");
+ }
+ break;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CHuiControlGroup& CAlfBridge::CreateControlGroupL(
+ TInt aWindowGroupNodeId,
+ TInt aClientWindowGroupId,
+ TInt aSecureId,
+ TInt aScreenNumber )
+ {
+ CHuiControlGroup* group = FindControlGroup(aWindowGroupNodeId,aScreenNumber);
+ if (!group)
+ {
+ group = &iHuiEnv->NewControlGroupL(aWindowGroupNodeId);
+ CleanupStack::PushL(group);
+ CHuiControl* cntrl = new (ELeave) CHuiControl(*iHuiEnv);
+ CleanupStack::PushL(cntrl);
+ CHuiLayout* layout = NULL;
+
+ cntrl->ConstructL();
+ group->AppendL(cntrl);
+ CleanupStack::Pop(cntrl);
+ cntrl->SetRole(EAlfWindowGroupContainer);
+
+ layout = CHuiCanvasVisual::AddNewL(*cntrl);
+ layout->SetTagL(KAlfWindowGroupContainerControlTag);
+ layout->ClearFlag(EHuiVisualFlagClipping); // No need to clip, should be faster without clipping
+ // IsVisualOpaque should return true if there is no effect.
+ // So that's why opaque flag is set to this layout.
+ layout->SetFlag(EHuiVisualFlagOpaqueHint);
+
+ TAlfControlGroupEntry entry;
+ entry.iControlGroup = group;
+ entry.iWindowGroupNodeId = aWindowGroupNodeId;
+ entry.iClientWindowGroupId = aClientWindowGroupId;
+ entry.iSecureId = aSecureId;
+ // we have received start effect for this group, but the group did not exist in alf universe at the time. hide the group.
+ if (iFullScreenEffectData
+ && iFullScreenEffectData->iWaitingWindowGroup
+ && iFullScreenEffectData->iToAppId == aSecureId)
+ {
+ CHuiControlGroup* fromGroup = NULL;
+ CHuiLayout* fromLayout = NULL;
+ fromGroup = FindControlGroupByAppId(iFullScreenEffectData->iFromAppId);
+ if (fromGroup)
+ {
+ CHuiControl& control2 = fromGroup->Control(0);
+ fromLayout = (CHuiLayout*)&control2.Visual(0);
+ }
+
+
+ // First HandleGfxEvent, then clear iWaitingWindowGroup.
+ TBool failed = HandleGfxEventL( *iFullScreenEffectData, layout, fromLayout );
+ if ( iFullScreenEffectData )
+ {
+ iFullScreenEffectData->iWaitingWindowGroup = EFalse;
+ }
+ if ( failed )
+ {
+ // Effect failed, reset state
+ HandleGfxStopEvent( EFalse ); // destroys iFullScreenEffectData
+ }
+ }
+ entry.iScreenNumber = aScreenNumber;
+// entry.iRole = EAlfWindowGroupContainer;
+
+ iAlfScreens[aScreenNumber]->iControlGroups.Append(entry);
+ CleanupStack::Pop(group);
+
+ if (iAlfScreens[aScreenNumber]->iDisplay)
+ ShowControlGroupL(iAlfScreens[aScreenNumber]->iDisplay->Roster(), *group, KHuiRosterShowAtTop, aScreenNumber);
+ }
+
+
+ return *group;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ShowControlGroupL(CHuiRoster& aRoster, CHuiControlGroup& aGroup, TInt aWhere, TInt aScreenNumber )
+ {
+ CAlfScreen* screen = iAlfScreens[aScreenNumber];
+
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ DebugPrintControlGroupOrder(*screen, aRoster, aGroup);
+#endif
+
+#ifdef ALF_DEBUG_VISUALIZE_WINDOWGROUP_ORDER
+ if (!aGroup.IsTransformed())
+ {
+ aGroup.EnableTransformationL();
+ aGroup.Transformation().Translate(0,0);
+ aGroup.Transformation().Scale(0.3,0.3);
+ }
+#endif
+
+ TInt last = aRoster.Count() - 1;
+
+
+// when an application exits, it must be shown on top util the effect has run its course.
+// But this tends to mess up the order of other groups, and application menu softkeys will
+// disappear.
+ if ( aGroup.Control(0).Visual(0).Effect() )
+ {
+ if ( aGroup.Control(0).Role() != EAlfWindowGroupContainer )
+ {
+ // The case where the application control group is deleted by window server
+ // has been solved by deleting the tag when window server wants to delete
+ // the group. Window server no longer has it, but we keep it alive for a while
+ // to show the effect. The group will be deleted when the effect ends.
+ aWhere = aRoster.Count() - KAlfNumberOfFixedControlGroups;
+ }
+ }
+
+ if (aGroup.Control(0).Role() == EAlfWindowGroupContainer)
+ {
+ // Window group control groups
+ ShowWindowGroupControlGroupL(aRoster, aGroup, aWhere, aScreenNumber);
+ aGroup.SetAcceptInput(EFalse);
+ }
+ else if (aGroup.Control(0).Role() == EAlfSessionContainer)
+ {
+ // ALF application control groups
+ ShowSessionContainerControlGroupL(aRoster, aGroup, aWhere, aScreenNumber);
+ }
+ else
+ {
+ aRoster.ShowL(aGroup, aWhere);
+ aGroup.SetAcceptInput(EFalse);
+ }
+
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ DebugPrintControlGroupOrder(*screen, aRoster, aGroup);
+#endif
+
+#ifdef ALF_DEBUG_VISUALIZE_WINDOWGROUP_ORDER
+ VisualizeControlGroupOrderL(aRoster, aGroup);
+#endif
+
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ShowSessionContainerControlGroupL(CHuiRoster& aRoster, CHuiControlGroup& aGroup, TInt aWhere, TInt aScreenNumber )
+ {
+ TInt last = aRoster.Count() - 1;
+
+ CAlfScreen* screen = iAlfScreens[aScreenNumber];
+
+ if (aWhere == KHuiRosterShowAtBottom)
+ {
+ // Most bottom one of alf control groups
+ aRoster.ShowL(aGroup, FirstAlfControlGroupIndex(aScreenNumber));
+ }
+ else if (aWhere == KHuiRosterShowAtTop)
+ {
+ // Most top one of alf control groups
+ TInt newIndex = LastAlfControlGroupIndex(aScreenNumber);
+
+ // check if the aGroup is already in a roster
+ for (TInt j=0; j<newIndex;j++)
+ {
+ if( &aRoster.ControlGroup(j) == &aGroup )
+ {
+ // adjust position a bit because this is in fact "move" operation
+ // move would move alf event window and place this control group
+ // on top of it if we don't do this adjusment
+ newIndex--;
+ break;
+ }
+ }
+
+ aRoster.ShowL(aGroup, newIndex);
+ }
+ else
+ {
+ TInt index = 0; // Index for ALF group control groups
+ TBool added = EFalse;
+ TBool move = EFalse; // indicates that controlgroup is already in the roster somewhere below the new index.
+ for (TInt i=FirstAlfControlGroupIndex(aScreenNumber); i<last; i++)
+ {
+ if (index == aWhere)
+ {
+ if( move )
+ {
+ // adjust the new index because of ShowL call
+ // will first remove the controlgroup from original position
+ index--;
+ }
+ aRoster.ShowL(aGroup, i);
+ added = ETrue;
+ break;
+ }
+
+ if( &aRoster.ControlGroup(i) == &aGroup )
+ {
+ move = ETrue;
+ }
+
+ if (aRoster.ControlGroup(i).Control(0).Role() == EAlfSessionContainer)
+ {
+ index++;
+ }
+ }
+
+ // Too large index was given, just add it to topmost
+ if (!added)
+ {
+ // Topmost alf group
+ ShowSessionContainerControlGroupL( aRoster, aGroup, KHuiRosterShowAtTop, aScreenNumber );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ShowWindowGroupControlGroupL(CHuiRoster& aRoster, CHuiControlGroup& aGroup, TInt aWhere, TInt aScreenNumber )
+ {
+ CAlfScreen* screen = iAlfScreens[aScreenNumber];
+
+ if (aWhere == KHuiRosterShowAtBottom)
+ {
+ // Most bottom one of any control groups
+ aRoster.ShowL(aGroup, KHuiRosterShowAtBottom);
+ }
+ else if (aWhere == KHuiRosterShowAtTop)
+ {
+ // Topmost
+ aRoster.ShowL(aGroup, aRoster.Count() - KAlfNumberOfFixedControlGroups);
+ }
+ else
+ {
+ TInt index = 0; // Index for Window group control groups
+ TBool added = EFalse;
+ for (TInt i=0; i<aRoster.Count() - KAlfNumberOfFixedControlGroups; i++)
+ {
+ if (index == aWhere)
+ {
+ aRoster.ShowL(aGroup, i);
+ added = ETrue;
+ break;
+ }
+
+ if (aRoster.ControlGroup(i).Control(0).Role() == EAlfWindowGroupContainer &&
+ &aRoster.ControlGroup(i) != &aGroup)
+ {
+ index++;
+ }
+ }
+
+ // Too large index was given, just add it to topmost
+ if (!added)
+ {
+ // Topmost
+ for (TInt i=aRoster.Count()-KAlfNumberOfFixedControlGroups; i >= 0; i--)
+ {
+ if (aRoster.ControlGroup(i).Control(0).Role() == EAlfWindowGroupContainer)
+ {
+ aRoster.ShowL(aGroup, i);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::SetAlfWindowGroupId(TInt aAlfWindowGroupId)
+ {
+ iAlfWindowGroupId = aAlfWindowGroupId;
+ // check if hithcock window group was already there
+ TInt secureId = RThread().SecureId();
+ if (iAlfScreens.Count())
+ {
+ for ( TInt i = 0; i < iAlfScreens[0]->iControlGroups.Count(); i++ )
+ {
+ if ( iAlfScreens[0]->iControlGroups[i].iSecureId == secureId &&
+ iAlfScreens[0]->iControlGroups[i].iClientWindowGroupId != CHuiStatic::RootWin(0)->Identifier())
+ {
+ iAlfWindowGroupNodeId = iAlfScreens[0]->iControlGroups[i].iWindowGroupNodeId;
+ return;
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CHuiDisplay* CAlfBridge::Display(TInt aScreenNum)
+ {
+ for ( TInt i = 0 ; i < iAlfScreens.Count() ; i++ )
+ {
+ if ( iAlfScreens[i]->iScreenNum == aScreenNum )
+ {
+ return iAlfScreens[i]->iDisplay;
+ }
+ }
+ return NULL;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ReorderAlfControlGroupsL( TInt aScreenNumber )
+ {
+ if (iAlfScreens[aScreenNumber]->iDisplay)
+ {
+ RPointerArray<CHuiControlGroup> controlGroupOrder;
+ CHuiRoster& roster = iAlfScreens[aScreenNumber]->iDisplay->Roster();
+ for (TInt j=0; j<roster.Count();j++)
+ {
+ CHuiControlGroup& controlGroup = roster.ControlGroup(j);
+ if (controlGroup.Control(0).Role() == EAlfSessionContainer)
+ {
+ controlGroupOrder.Append(&controlGroup);
+ roster.Hide(controlGroup);
+ j--; // roster.Hide does remove controlGroup from the roster
+ }
+ }
+
+ for (TInt k=0;k<controlGroupOrder.Count();k++)
+ {
+ ShowControlGroupL(roster, *controlGroupOrder[k], KHuiRosterShowAtTop, aScreenNumber);
+ }
+
+ controlGroupOrder.Close();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TInt CAlfBridge::FirstAlfControlGroupIndex( TInt aScreenNumber )
+ {
+ if (iAlfScreens[aScreenNumber]->iDisplay)
+ {
+ CHuiRoster& roster = iAlfScreens[aScreenNumber]->iDisplay->Roster();
+ for (TInt j=0; j<roster.Count();j++)
+ {
+ if( roster.ControlGroup(j).Control(0).Role() == EAlfSessionContainer
+ || roster.ControlGroup(j).ResourceId() == iAlfWindowGroupNodeId )
+ {
+ return j; // Alf groups positioned just above alf servers window group
+ }
+ }
+ }
+ return 0; // Not found
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TInt CAlfBridge::LastAlfControlGroupIndex( TInt aScreenNumber )
+ {
+ if (iAlfScreens[aScreenNumber]->iDisplay)
+ {
+ CHuiRoster& roster = iAlfScreens[aScreenNumber]->iDisplay->Roster();
+ for (TInt j=0; j<roster.Count();j++)
+ { // last is always a index of pointer event window position
+ if( roster.ControlGroup(j).ResourceId() == iAlfWindowGroupNodeId )
+ {
+ return j; // Alf groups positioned just above alf servers window group
+ }
+ }
+ }
+ return 0;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TInt CAlfBridge::ResolveScreenNumber( CHuiDisplay& aDisplay )
+ {
+ for ( TInt i = 0 ; i < iAlfScreens.Count() ; i++ )
+ {
+ if ( iAlfScreens[i]->iDisplay == &aDisplay )
+ {
+ return iAlfScreens[i]->iScreenNum;
+ }
+ }
+ return KErrNotFound;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::NotifyDisplayRefreshStarted(CHuiDisplay& aDisplay)
+ {
+ // Look for the correct display
+ TInt screenNumber = ResolveScreenNumber(aDisplay);
+ RemoveTemporaryPresenterVisuals();
+ if ( screenNumber != KErrNotFound )
+ {
+ // FPS Counter with hitchcock drawing
+#ifdef SYMBIAN_BUILD_GCE
+ if(iPrintFPS)
+ {
+ TReal fps = CHuiStatic::FrameRate();
+ if(fps > 0)
+ {
+ TBuf<8> numBuf;
+ numBuf.AppendNum(fps, TRealFormat(5,1));
+ TRAP_IGNORE(
+ {
+ iAlfScreens[screenNumber]->iFPSText->SetTextL( numBuf );
+ })
+ }
+ }
+#endif
+
+ if (iAlfScreens[screenNumber]->IsVisualTreeVisibilityChanged())
+ {
+ HandleVisualVisibility( screenNumber );
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(EFalse);
+ }
+
+ if (!iActivated)
+ {
+ iBridgerClient.Connect();
+ iActivated = ETrue;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Check if there is effect and it's not fade effect.
+// ---------------------------------------------------------------------------
+//
+static TBool IsNonFadeEffect(CHuiFxEffect* aEffect)
+ {
+ return aEffect && !(aEffect->EffectFlags() & KHuiFadeEffectFlag);
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TBool CAlfBridge::IsVisualOpaque(CHuiVisual& aVisual)
+ {
+ TBool transparent = EFalse;
+
+ // TODO: We should check transformation too and perhaps parent transformations as well ?
+ //transparent |= aVisual.IsTransformed();
+
+ // if the control has an attached effect which is transformed, it must be considered transparent
+ // as it may not cover the full screen
+ if ( IsNonFadeEffect( aVisual.Effect() ) )
+ {
+ return EFalse;
+ }
+ if ( aVisual.Layout() && IsNonFadeEffect( aVisual.Layout()->Effect() ) )
+ {
+ return EFalse;
+ }
+
+ if (aVisual.Flags() & EHuiVisualFlagDrawOnlyAsExternalContent)
+ {
+ return EFalse; // not transparent
+ }
+
+ transparent |= (!((aVisual.Flags() & EHuiVisualFlagOpaqueHint) == EHuiVisualFlagOpaqueHint));
+ transparent |= (aVisual.iOpacity.Now() < KAlfVisualDefaultOpacity);
+ transparent |= (aVisual.iOpacity.Target() < KAlfVisualDefaultOpacity);
+
+ return !transparent;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ClipVisualRect(TRect& aRect, const TRect& aClippingRect)
+ {
+ if (aRect.Intersects(aClippingRect))
+ {
+ // Clip to visible area, there are windows larger than screen for some reason.
+ aRect.Intersection(aClippingRect);
+ }
+ else
+ {
+ // no intersection with the clipping rect -> outside of the screen -> not visible
+ aRect = TRect(0,0,0,0);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TBool CAlfBridge::IsRectCoveredByRegion(TRect aRect, TRegion& aCoveringRegion)
+ {
+ TBool isCovered = EFalse;
+
+ // Zero sized rects are considered as covered (although it is a bit philosphical question)
+ if (aRect.Size() == TSize(0,0))
+ {
+ isCovered = ETrue;
+ }
+
+ // First check if it is covered by one of the rects in the covering region...
+ if (!isCovered)
+ {
+ TPoint topLeft = aRect.iTl;
+ TPoint bottomRight = aRect.iBr;
+ bottomRight.iX--;
+ bottomRight.iY--;
+
+ for (TInt i=0; i < aCoveringRegion.Count(); i++)
+ {
+ if (aCoveringRegion[i].Contains(topLeft) &&
+ aCoveringRegion[i].Contains(bottomRight))
+ {
+ isCovered = ETrue;
+ }
+ }
+ }
+
+ // ...it may still cover it with a combination of several rects
+ if (!isCovered)
+ {
+ iTempVisualRegion.Clear();
+ iTempIntersectingRegion.Clear();
+
+ iTempVisualRegion.AddRect(aRect);
+
+ iTempIntersectingRegion.Intersection(aCoveringRegion, iTempVisualRegion);
+ iTempIntersectingRegion.Tidy();
+
+ if (iTempIntersectingRegion.Count() == 1)
+ {
+ if (iTempIntersectingRegion[0] == aRect)
+ {
+ isCovered = ETrue;
+ }
+ }
+ }
+
+ return isCovered;
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleVisualVisibility( TInt aScreenNumber )
+ {
+ if (!iAlfScreens.Count())
+ return;
+
+ iTempRegion.Clear();
+
+ CAlfScreen* screen = iAlfScreens[aScreenNumber];
+ TRect fullscreen = TRect(TPoint(0,0), screen->Size());
+ TBool fadeEffectInScreen = EFalse;
+
+
+ // Prepare SW render target (if needed)
+ if (iSwRenderingEnabled)
+ {
+ TBool modified = PrepareSwRenderingTarget( screen );
+
+ if ( modified )
+ {
+ // To avoid debug panic, we need to reset foreground bitmap.
+ TRAP_IGNORE( screen->iDisplay->SetForegroundBitmapL(
+ screen->iSwRenderingTarget ) );
+ }
+ }
+
+ TBool fullscreenCovered = EFalse;
+ //iActiveVisualCount = 0;
+ iBgSurfaceFound = EFalse;
+ //iPaintedArea = 0;
+ // skip the topmost (effect) layer, start from floating sprite group
+ for (TInt j=screen->iDisplay->Roster().Count() - 2; j>=0; j--)
+ {
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ TInt activevisualcount = 0;
+ TInt passivevisualcount = 0;
+#endif
+
+ CHuiControlGroup& controlgroup = iAlfScreens[aScreenNumber]->iDisplay->Roster().ControlGroup(j);
+ CHuiControl& control = controlgroup.Control(0);
+ CHuiCanvasVisual* layout = (CHuiCanvasVisual*)&control.Visual(0);
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( layout->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleVisualVisibility: tracked visual 0x%x"), canvasVisual);
+ }
+#endif
+
+ // Dont mess with alf control group visuals, alf session handling does it for us
+ // just add the rect to covered region because alf draws solid background.
+ if (control.Role() == EAlfSessionContainer)
+ {
+ iTempRegion.AddRect(fullscreen);
+ iTempRegion.Tidy();
+ continue;
+ }
+
+ // For optimization reasons, check if all visuals below in Z-order are covered
+ if (!fullscreenCovered)
+ {
+ fullscreenCovered = IsRectCoveredByRegion(fullscreen, iTempRegion);
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ if (fullscreenCovered)
+ __ALFLOGSTRING("Full screen covered!");
+#endif
+ }
+
+ if (!fullscreenCovered)
+ {
+ fullscreenCovered = screen->iDisplay->Roster().IsVisibleContentFrozen();
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ if (fullscreenCovered)
+ __ALFLOGSTRING("Full screen covered because of frozen roster content");
+#endif
+ }
+
+ TBool subTreeCovered = EFalse;
+ TBool hasActiveVisualsInVisualTree = HandleLayoutVisualVisibility( layout, controlgroup, control, fullscreenCovered, fullscreen, screen, subTreeCovered, IsVisualOpaque(*layout) );
+ TBool hasFadeEffectsInVisualTree = (layout->CanvasFlags() & EHuiCanvasFlagExternalFadeExistsInsideVisualTree);
+
+ // If we layout is active setup the fade effects. Also if it is inactive, but has been
+ // flagged as containing fade effect, then run the setup as well so that effects which
+ // are no more needed get removed.
+ if (hasActiveVisualsInVisualTree || (!hasActiveVisualsInVisualTree && hasFadeEffectsInVisualTree))
+ {
+ fadeEffectInScreen = ETrue;
+
+ // Prepare fade effects to whole visual tree below layout
+ PrepareFadeEffects( *layout );
+
+ // Load needed fade effects (or remove them)
+ TBool visualTreeHasFadeEffects = LoadFadeEffectsL( *layout );
+
+ // Set flag so that next time we can optimize
+ if (visualTreeHasFadeEffects)
+ {
+ layout->SetCanvasFlags(EHuiCanvasFlagExternalFadeExistsInsideVisualTree);
+ }
+ else
+ {
+ layout->ClearCanvasFlags(EHuiCanvasFlagExternalFadeExistsInsideVisualTree);
+ }
+ }
+
+ if (!hasActiveVisualsInVisualTree)
+ {
+ // Setting also the root visual (layout) as inactive, if it had none
+ // active children. This is because otherwise the Inactive checks won't
+ // work correctly within RosterImpl ScanDirty & ClearChanged phases.
+ layout->SetFlag(EHuiVisualFlagInactive);
+ }
+ else
+ {
+ layout->ClearFlag(EHuiVisualFlagInactive);
+ }
+
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ __ALFLOGSTRING1(">>>> HandleVisualVisibility: Control group index: %d", j );
+ __ALFLOGSTRING1(">>>> HandleVisualVisibility: Active visuals : %d", activevisualcount );
+ __ALFLOGSTRING1(">>>> HandleVisualVisibility: Passive visuals: %d", passivevisualcount );
+#endif
+
+ }
+ if (iBgSurfaceFound)
+ {
+ if (!iInLowMemMode)
+ {
+ SetLowMemory(ETrue);
+ iBridgerClient.SendBlind(KAlfCompositionTargetHidden, TIpcArgs());
+ iInLowMemMode = ETrue;
+ }
+ }
+ else if (iInLowMemMode)
+ {
+ SetLowMemory(EFalse);
+ iBridgerClient.SendBlind(KAlfCompositionTargetVisible, TIpcArgs());
+ iInLowMemMode = EFalse;
+ }
+
+
+ // Finally, if there are fadeeffects applied to windowgroups, make sure first one does not
+ // blend itself, but other windowgroups do blend. Otherwise windowgrouops above others
+ // would clear the screen areas where they do not really draw.
+ if (fadeEffectInScreen)
+ {
+ TBool firstFadedWindowGroupFound = EFalse;
+ for (TInt j=0; j<screen->iDisplay->Roster().Count() - 2; j++) // skip the topmost (effect) layer
+ {
+ CHuiControlGroup& controlgroup = iAlfScreens[aScreenNumber]->iDisplay->Roster().ControlGroup(j);
+ CHuiControl& control = controlgroup.Control(0);
+ CHuiCanvasVisual* layout = (CHuiCanvasVisual*)&control.Visual(0);
+ if (layout->Effect() && (layout->Effect()->EffectFlags() & KHuiFadeEffectFlag))
+ {
+ if (firstFadedWindowGroupFound)
+ {
+ TInt flags = layout->Effect()->EffectFlags();
+ flags |= KHuiFxAlwaysBlend;
+ layout->Effect()->SetEffectFlags(flags);
+ }
+ firstFadedWindowGroupFound = ETrue;
+ }
+ }
+ }
+ }
+
+TBool CAlfBridge::HandleLayoutVisualVisibility(
+ CHuiLayout* aLayout,
+ CHuiControlGroup& aControlGroup,
+ CHuiControl& aControl,
+ TBool& aFullscreenCovered,
+ TRect& aFullscreen,
+ CAlfScreen* aScreen,
+ TBool& aSubtreeVisible,
+ TBool aChildCanBeOpaque )
+ {
+ TBool visualTreeActive = EFalse;
+ TRect visualDisplayRect;
+ TBool visualRectIsCovered = EFalse;
+ TBool visualIsOpaque = EFalse;
+ TBool visualIsActive = EFalse;
+ CHuiCanvasVisual* canvasVisual = NULL;
+
+ for (TInt i=aLayout->Count()-1; i >= 0; i--)
+ {
+ visualDisplayRect = TRect(0,0,0,0);
+ visualRectIsCovered = EFalse;
+ visualIsOpaque = EFalse;
+ visualIsActive = EFalse;
+ TBool visualSubtreeVisible = EFalse;
+
+ // Check first if visual itself is hidden or does hide other visuals below
+ // in z-order. If it does not hide, then we do not add its displayrect to covering
+ // region.
+ canvasVisual = (CHuiCanvasVisual*)(&aLayout->Visual(i));
+
+ // Child can be considered to be opaque only if all parents are opaque and
+ // visual itself is opaque.
+ // For example, parent can have opacity < 1 and that affects children as well.
+ // As another example, parent can have scaling transformation.
+ visualIsOpaque = aChildCanBeOpaque && IsVisualOpaque(*canvasVisual);
+ if (canvasVisual->Count())
+ {
+ visualTreeActive |= HandleLayoutVisualVisibility( canvasVisual, aControlGroup, aControl, aFullscreenCovered, aFullscreen, aScreen, visualSubtreeVisible, visualIsOpaque );
+ }
+ #ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( canvasVisual->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleVisualVisibility: tracked visual 0x%x"), canvasVisual);
+ }
+ #endif
+
+ if (visualSubtreeVisible)
+ {
+ aSubtreeVisible = ETrue;
+ }
+
+ // Optimization, it is faster to check fullscreen than read visuals displayrect
+ if (aFullscreenCovered)
+ {
+ visualRectIsCovered = ETrue;
+ }
+ else
+ {
+ // Check where visual is
+ visualDisplayRect = canvasVisual->DisplayRect();
+
+ // Make sure we clip visual rect to visible screen area
+ ClipVisualRect(visualDisplayRect, aFullscreen);
+
+ // Check if this visual is covered by other opaque visuals which rects are in "covered" region
+ visualRectIsCovered = IsRectCoveredByRegion(visualDisplayRect, iTempRegion);
+ }
+
+ /* if ( layout->Effect() || canvasVisual->Effect() )
+ {
+ visualRectIsCovered = EFalse;
+ }
+ */
+ TBool wasInactive = canvasVisual->Flags() &
+ ( EHuiVisualFlagInactive | EHuiVisualFlagUnderOpaqueHint );
+
+ if (visualRectIsCovered)
+ {
+ // We clear texture cache here to avoid running out of texture memory
+ if (!(canvasVisual->Flags() & EHuiVisualFlagAlwaysDraw)) // The window has been hidden. However it has exit effect and it must stay active until effect has stopped
+ {
+ if (visualSubtreeVisible)
+ {
+ canvasVisual->SetFlag(EHuiVisualFlagUnderOpaqueHint);
+ canvasVisual->ClearFlags(EHuiVisualFlagInactive);
+ }
+ else
+ {
+ canvasVisual->SetFlag(EHuiVisualFlagInactive);
+ canvasVisual->ClearFlags(EHuiVisualFlagUnderOpaqueHint);
+ }
+
+ canvasVisual->ClearCache();
+ // For SW rendering, disable capturing buffer
+ canvasVisual->SetCapturingBufferL(NULL);
+ }
+ else
+ { // this should be drawn, but inactivate when effect is done
+ canvasVisual->ClearFlags(
+ EHuiVisualFlagInactive | EHuiVisualFlagUnderOpaqueHint |
+ EHuiVisualFlagShouldBeInactive | EHuiVisualFlagShouldBeUnderOpaqueHint );
+ if (visualSubtreeVisible)
+ {
+ canvasVisual->SetFlag(EHuiVisualFlagShouldBeUnderOpaqueHint);
+ }
+ else
+ {
+ canvasVisual->SetFlag(EHuiVisualFlagShouldBeInactive);
+ }
+ canvasVisual->PrepareCache();
+ // For SW rendering, set capturing buffer if it exists)
+ canvasVisual->SetCapturingBufferL(aScreen->iSwRenderingTarget);
+
+ if (wasInactive)
+ {
+ canvasVisual->SetChanged();
+ }
+ }
+
+ if (!wasInactive)
+ {
+ aScreen->iDisplay->SetDirty();
+ }
+
+ #ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ passivevisualcount++;
+ #endif
+ }
+ else
+ {
+ aSubtreeVisible = ETrue;
+ canvasVisual->ClearFlags(
+ EHuiVisualFlagInactive | EHuiVisualFlagShouldBeInactive |
+ EHuiVisualFlagUnderOpaqueHint | EHuiVisualFlagShouldBeUnderOpaqueHint );
+ canvasVisual->PrepareCache();
+ canvasVisual->SetCapturingBufferL(aScreen->iSwRenderingTarget);
+
+ // we've found non-inactive window which has background surface
+ // attached..
+ if (canvasVisual->IsBackgroundDrawingEnabled() &&
+ canvasVisual->LayerExtent() != TRect() &&
+ !canvasVisual->LayerUsesAlphaFlag() )
+ {
+ // if paintedareacount is exactly one, it means that the window
+ // has background surface but no drawing commands
+ if (canvasVisual->PaintedAreaCount() == 1)
+ {
+ THuiCanvasPaintedArea pa = canvasVisual->PaintedArea(0);
+ TRect r = pa.iPaintedRect.Round();
+ // if we found a fullscreen surface with no other drawing commands
+ // we can safely assume that it's about the only thing to be visible
+ // and we can release memory occupied by other parts of the system
+ //
+ // NOTE: this mechanism keeps the system in low mem state
+ // if the surface is visible, meaning that for example
+ // opening an options menu does not instantly trigger normal
+ // memory state. We want to do it like this as otherwise
+ // we would be triggering for example background animation
+ // on / off quite rapidly........
+ if ( r == Display(0)->VisibleArea())
+ {
+ // Final test. Surface must not be ALF surface, but some other surface.
+ CHuiControlGroup* alfControlGroup = FindControlGroupByAppId( iAlfSecureId );
+ if (alfControlGroup != &aControlGroup)
+ {
+ iBgSurfaceFound = ETrue;
+ }
+ }
+ }
+ }
+
+ if (wasInactive)
+ {
+ canvasVisual->SetChanged();
+ }
+ #ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ activevisualcount++;
+ #endif
+ }
+
+ // Finally check the area that this visual covers and add it to covered region
+ visualIsActive = !(canvasVisual->Flags() & EHuiVisualFlagInactive);
+
+ // Sprites and effects as we consider them always as transparent and also
+ // if controlgroup is transformed somehow
+
+ if (aControl.Role() == EAlfFullScreenEffectContainer
+ || aControl.Role() == EAlfWindowFloatingSpriteContainer ||
+ aControlGroup.IsTransformed())
+ {
+ visualIsOpaque = EFalse;
+ }
+
+ if (visualIsActive && visualIsOpaque && !visualRectIsCovered)
+ {
+ #ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ if (canvasVisual->PaintedAreaCount())
+ __ALFLOGSTRING2("Visual has painted areas: displayrect: iTl: %i, %i", visualDisplayRect.iTl.iX, visualDisplayRect.iTl.iY);
+ __ALFLOGSTRING2("Visual has painted areas: displayrect: iBr: %i, %i", visualDisplayRect.iBr.iX,visualDisplayRect.iBr.iY);
+ #endif
+ for (TInt k=0; k < canvasVisual->PaintedAreaCount(); k++)
+ {
+ THuiCanvasPaintedArea paintArea = canvasVisual->PaintedArea(k);
+ TRect coveredRect = paintArea.iPaintedRect;
+
+ // Clip to visible area, there are windows larger than screen for some reason.
+ ClipVisualRect(coveredRect, aFullscreen);
+
+ // Only add to covering region if the painted area is defined as opaque
+ if (paintArea.iPaintType == EHuiCanvasPaintTypeOpaque)
+ {
+ #ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ __ALFLOGSTRING2("Covered rect: iTl: %i, %i", coveredRect.iTl.iX, coveredRect.iTl.iY);
+ __ALFLOGSTRING2("Covered rect: iBr: %i, %i", coveredRect.iBr.iX,coveredRect.iBr.iY);
+ #endif
+ iTempRegion.AddRect(coveredRect);
+ iTempRegion.Tidy();
+ }
+ }
+ }
+ }
+
+ visualTreeActive |= visualIsActive;
+ return visualTreeActive;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::ClearCanvasVisualCommandSets(TBool aInactiveOnly)
+ {
+ if (!iAlfScreens.Count())
+ return;
+
+ CAlfScreen* screen = iAlfScreens[0]; // TODO
+ for (TInt j=screen->iDisplay->Roster().Count() - 2; j>=0; j--) // skip the topmost (effect) layer
+ {
+ CHuiControlGroup& controlgroup = iAlfScreens[0]->iDisplay->Roster().ControlGroup(j);
+ CHuiControl& control = controlgroup.Control(0);
+
+ if ( control.Role() == EAlfSessionContainer )
+ {
+ continue;
+ }
+
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ for (TInt i=layout->Count()-1; i >= 0; i--)
+ {
+ CHuiCanvasVisual* canvasVisual = (CHuiCanvasVisual*)(&layout->Visual(i));
+ if (!aInactiveOnly)
+ {
+ canvasVisual->ClearCommandSet();
+ }
+ else if (aInactiveOnly && (canvasVisual->Flags() & EHuiVisualFlagInactive))
+ {
+ canvasVisual->ClearCommandSet();
+ }
+ else
+ {
+ // dont clear
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::EnableVisualDefaultTransformationsL(CHuiVisual& aVisual)
+ {
+ aVisual.EnableTransformationL();
+ if (!aVisual.Transformation().Count())
+ {
+ aVisual.Transformation().Rotate(0);
+ aVisual.Transformation().Scale(1,1);
+ aVisual.Transformation().Translate(0,0);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleCallback(TInt aStatus)
+ {
+ TInt err = KErrNone;
+ if (aStatus >= 0)
+ {
+ TRAP(err, DoDispatchL(aStatus))
+ }
+
+ if (aStatus < 0 || err)
+ {
+ __ALFLOGSTRING2("CAlfBridge::HandleCallback status: %d error: %d",aStatus,err);
+
+ CEikonEnv* eikenv = CEikonEnv::Static();
+ if ( eikenv )
+ {
+ eikenv->HandleError(err?err:aStatus);
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// DoDispatchL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::DoDispatchL(TInt aStatus)
+ {
+ if (*iHost)
+ {
+ TAlfBridgerData data = (*iHost)->GetData(aStatus);
+ // dispatch
+ __ALFLOGSTRING1( "CAlfBridge::DoDispatchL: %d",data.iOp );
+
+ switch (data.iOp)
+ {
+ case EAlfDSCreateNewDisplay:
+ {
+ AddNewScreenL(NULL);
+ break;
+ }
+ case EAlfDSDestroyDisplay:
+ {
+ HandleDestroyDisplay( data.iInt1 );
+ break;
+ }
+ case EAlfDSNewWindow:
+ {
+ HandleNewWindowL( data );
+ break;
+ }
+ case EAlfDSDestroyWindow:
+ {
+ HandleDestroyWindowL( data );
+ break;
+ }
+ case EAlfDSSetWindowPos:
+ {
+ HandleSetWindowPosL( data );
+ break;
+ }
+ case EAlfDSSetWindowSize:
+ {
+ HandleSetWindowSizeL( data );
+ break;
+ }
+ case EAlfDSSetWindowRotation:
+ {
+ HandleSetWindowRotationL( data );
+ break;
+ }
+ case EAlfDSSetWindowOpacity:
+ {
+ HandleSetWindowOpacityL( data );
+ break;
+ }
+ case EAlfDSRefreshCallback:
+ {
+ iHuiEnv->ContinueRefresh();
+ break;
+ }
+ case EAlfDSReorder:
+ {
+ HandleReorderWindowL( data );
+ break;
+ }
+ case EAlfDSPostCanvasBuffer:
+ {
+ HandlePostCanvasBufferL( data );
+ break;
+ }
+ case EAlfDSSetWindowActive:
+ {
+ HandleSetWindowActiveL( data );
+ break;
+ }
+ case EAlfDSSetWindowFlag:
+ case EAlfDSClearWindowFlag:
+ {
+ HandleSetWindowFlagL(data, data.iOp);
+ break;
+ }
+ case EAlfDSSetSurfaceExtent:
+ {
+ HandleSetSurfaceExtentL( data );
+ break;
+ }
+ case EAlfDsLayerUsesAlphaFlagChanged:
+ {
+ HandleLayerUsesAlphaFlagChanged( data );
+ break;
+ }
+ case EAlfDSGetAlfNativeWindowData:
+ {
+// HandleGetNativeWindowDataL( data );
+ break;
+ }
+ case EAlfDSGroupChained:
+ {
+ __ALFLOGSTRING("CAlfBridge::DoDispatchL, EAlfDSGroupChained");
+ // TODO, link groups
+ break;
+ }
+ case EAlfDSGroupChainBroken:
+ {
+ __ALFLOGSTRING("CAlfBridge::DoDispatchL, EAlfDSGroupChainBroken");
+ // TODO, break link
+ break;
+ }
+ case EAlfDSMoveWindowToNewGroup:
+ {
+ /*
+ RDebug::Print(_L("CAlfBridge::DoDispatchL, EAlfDSMoveWindowToNewGroup, THIS METHOD IS UNTESTED. EXPECT TROUBLE!"));
+ // TODO: TEST!
+ TInt windowGroupNodeId = data.iInt1;
+ TInt windowNodeId = data.iInt2;
+ TInt newGroupId = (TInt)data.iPtr;
+ CHuiLayout* layout = NULL;
+ CHuiCanvasVisual* viz = (CHuiCanvasVisual*)FindVisual(windowNodeId, windowGroupNodeId,screenNumber);
+ if (viz)
+ {
+ // #1 remove visual from old group
+ layout = viz->Layout();
+ layout->Remove(viz);
+ viz->Owner().Remove(viz);
+ // #2 insert visual to the beginning of the new group
+ CHuiControlGroup* controlGroup = FindControlGroup(newGroupId,screenNumber);
+ if (controlGroup)
+ {
+ CHuiControl& control = controlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ layout->AppendL( viz );
+ }
+ }*/
+ break;
+ }
+ case EAlfEffectFx:
+ {
+ HandleGfxEffectsL( data );
+ break;
+ }
+ case EAlfStopEffectFx:
+ {
+ HandleGfxStopEffectsL( data );
+ break;
+ }
+ case EAlfControlEffectFx:
+ {
+ HandleGfxControlEffectsL( data );
+ break;
+ }
+ // TODO: implement these
+ case EAlfRegisterEffectFx:
+ {
+ HandleRegisterEffectL( data );
+ break;
+ }
+ case EAlfUnregisterEffectFx:
+ {
+ for (TInt i = 0; i < iAlfRegisteredEffects.Count(); i++)
+ {
+ if (iAlfRegisteredEffects[i].iAction == data.iInt1)
+ {
+ TRegisteredEffectsStruct removed =
+ iAlfRegisteredEffects[i];
+ iAlfRegisteredEffects.Remove(i);
+ CHuiFxEngine* engine = NULL;
+ engine = iHuiEnv->EffectsEngine();
+ if (engine)
+ {
+ engine->UnRegisterEffectL(*removed.iEffectFile);
+ }
+ delete removed.iEffectFile;
+ // if this happened to be the fade effect, the cached fade effect filename should
+ // be cleared
+ if ( data.iInt1 == KFadeAction)
+ {
+ RegisterFadeEffectL();
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case EAlfUnregisterAllFx:
+ {
+ while (iAlfRegisteredEffects.Count())
+ {
+ TRegisteredEffectsStruct removed =
+ iAlfRegisteredEffects[0];
+ iAlfRegisteredEffects.Remove(0);
+ CHuiFxEngine* engine = NULL;
+ engine = iHuiEnv->EffectsEngine();
+ if (engine)
+ {
+ engine->UnRegisterEffectL(*removed.iEffectFile);
+ }
+
+ delete removed.iEffectFile;
+ }
+ // fade file might have changed. This will be resolved when next fade effect request arrives.
+ RegisterFadeEffectL();
+ break;
+ }
+ case EAlfDSSetCursorData:
+ {
+ HandleSetCursorDataL( data );
+ break;
+ }
+ case EAlfDSSetFadeEffect:
+ {
+ HandleSetFadeEffectL( data );
+ break;
+ }
+ case EAlfDSSetNodeTracking:
+ {
+ HandleSetNodeTracking( data );
+ break;
+ }
+ case EAlfBridgeSetScreenRotation:
+ {
+ //short cut..
+ __ALFLOGSTRING1("CAlfBridge::DoDispatchL: EAlfBridgeSetScreenRotation: %d",data.iInt1);
+ CHuiGc::TOrientation huiOrientation(CHuiGc::EOrientationNormal);
+ switch(data.iInt1)
+ {
+ case 1: // 90
+ huiOrientation = CHuiGc::EOrientationCCW90;
+ break;
+ case 2: // 180
+ huiOrientation = CHuiGc::EOrientation180;
+ break;
+ case 3: // 270
+ huiOrientation = CHuiGc::EOrientationCW90;
+ break;
+ default:
+ break;
+ }
+ if (iAlfScreens[0]->iDisplay->Orientation() != huiOrientation)
+ {
+ HandleSetLayoutSwitchEffectL();
+ iAlfScreens[0]->iDisplay->SetOrientation(huiOrientation);
+ if (iAppUi)
+ {
+ iAppUi->AdjustWindowGroupPositionL(0,CAlfAppServer::EAlfWindowSize); // hackish, but one way to enforce alf window resizing
+ }
+ __ALFLOGSTRING1("AlfScreens[0]->iDisplay->SetOrientation: %d",huiOrientation);
+ }
+
+ break;
+ }
+ case EAlfEffectFxBeginSyncronizedGroup:
+ {
+ CHuiFxEngine* engine = iHuiEnv->EffectsEngine();
+ if (engine)
+ {
+ engine->BeginGroupEffect(data.iInt1);
+ }
+ break;
+ }
+ case EAlfEffectFxEndSyncronizedGroup:
+ {
+ TInt groupId = data.iInt1;
+ //TBool forced = data.iInt2;
+ __ALFLOGSTRING1("CAlfBridge::DoDispatchL - Ending for group %d requested.",
+ groupId );
+ CHuiFxEngine* engine = iHuiEnv->EffectsEngine();
+ if (engine)
+ {
+ engine->StartGroupEffect(groupId);
+ }
+ iHuiEnv->ContinueRefresh();
+ break;
+ }
+ case KUnInitialized:
+ {
+ __ALFLOGSTRING1("CAlfBridge::DoDispatchL: Received KUnInitialized: %d - CRITICAL ERROR!",data.iOp);
+ USER_INVARIANT();
+ }
+ default:
+ {
+ // Should not happen
+ __ALFLOGSTRING1("CAlfBridge::DoDispatchL: Received Unknown op: %d",data.iOp);
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleDestroyDisplay
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleDestroyDisplay( TInt aScreenNumber )
+ {
+ iAlfScreens[aScreenNumber]->iDisplay->iRefreshObservers.Remove( *this );
+ // TODO: Following delete iAlfScreens[aScreenNumber] crashes when display is trying to delete roster.
+ // RosterEntry is trying to refer to display, which is appareantly alrady destroyed. The roster should have no iRootVisual when display is removed.
+
+ iAlfScreens[aScreenNumber]->iDisplay->Roster().Hide(*(iAlfScreens[aScreenNumber]->iFloatingSpriteControlGroup));
+ iAlfScreens[aScreenNumber]->iDisplay->Roster().Hide(*(iAlfScreens[aScreenNumber]->iFullscreenEffectControlGroup));
+ delete iAlfScreens[aScreenNumber];
+ iAlfScreens.Remove( aScreenNumber );
+ }
+
+// ---------------------------------------------------------------------------
+// HandleNewWindowL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleNewWindowL( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ __ALFLOGSTRING1("CAlfBridge::HandleNewWindowL: new window %d!",windowNodeId);
+
+ switch (windowAttributes->iWindowNodeType)
+ {
+ case EAlfWinTreeNodeGroup:
+ {
+ CHuiControlGroup& controlGroup = CreateControlGroupL(
+ windowGroupNodeId,
+ windowAttributes->iClientHandle,
+ windowAttributes->iSecureId,
+ screenNumber);
+
+ // We just received notification for our own window group creation, store its node id for doing
+ // faster lookups later...
+ if (windowAttributes->iClientHandle == iAlfWindowGroupId)
+ {
+ iAlfWindowGroupNodeId = windowGroupNodeId;
+ }
+ break;
+ }
+ case EAlfWinTreeNodeClient:
+ case EAlfWinTreeNodeRoot: // TODO: Root window receives drawing commands too
+ case EAlfWinTreeNodeAnim:
+ case EAlfWinTreeNodeSprite:
+ case EAlfWinTreeNodeTextCursor:
+ {
+ CHuiControlGroup* controlGroup = FindControlGroup(windowGroupNodeId,screenNumber);
+ // Floating sprites only require own group. Normal sprites should behave as normal visuals.
+ if (!controlGroup && windowAttributes->iWindowNodeType == EAlfWinTreeNodeSprite )
+ {
+ controlGroup = iAlfScreens[screenNumber]->iFloatingSpriteControlGroup;
+ }
+
+ if (controlGroup)
+ {
+ CHuiControl& control = controlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ CHuiCanvasVisual* viz = NULL;
+ CHuiCanvasVisual* parentViz = NULL;
+ parentViz = (CHuiCanvasVisual*)FindVisual(windowAttributes->iParentNodeId);
+ if (parentViz)
+ {
+ viz = CHuiCanvasVisual::AddNewL(control, parentViz);
+ }
+ else
+ {
+ viz = CHuiCanvasVisual::AddNewL(control, layout);
+ }
+ __ALFFXLOGSTRING2("CAlfBridge::HandleNewWindowL visual: 0x%x, id 0x%x", viz, windowNodeId);
+ AddVisual(
+ windowNodeId,
+ windowAttributes->iClientHandle,
+ windowAttributes->iClientGroupHandle,
+ viz );
+
+ // check , if a window is having already defined effect.
+ if (iControlEffectData
+ && iControlEffectData->iClientHandle == windowAttributes->iClientHandle
+ && iControlEffectData->iClientGroupHandle == windowAttributes->iClientGroupHandle)
+ {
+ HandleGfxControlEventL(*iControlEffectData, viz);
+ delete iControlEffectData;
+ iControlEffectData = NULL;
+ }
+ viz->SetCommandType( CHuiCanvasVisual::ECommandBufferSgc );
+ viz->SetFlags(EHuiVisualFlagManualLayout | EHuiVisualFlagInactive);
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( windowAttributes->iTrackWindow )
+ {
+ viz->SetTracking( windowAttributes->iTrackWindow );
+ }
+#endif
+ // draw sprites and anims the last inside their windowgroup
+ /*if (windowAttributes->iWindowNodeType == EAlfWinTreeNodeSprite || windowAttributes->iWindowNodeType == EAlfWinTreeNodeAnim )
+ {
+ viz->SetFlag(EHuiVisualFlagDrawAfterOthers);
+ }
+*/
+ // Store identifier / tag to get handle of this visual later
+ TBuf8<16> buf;
+ buf.AppendNum(windowNodeId);
+ viz->SetTagL(buf);
+ viz->SetPos(windowAttributes->iPosition, windowAttributes->iTransitionTime);
+ viz->SetSize(windowAttributes->iSize, windowAttributes->iTransitionTime);
+
+ // Keep window invisible until activated, for now we use opacity for that.
+ viz->iOpacity.Set(0, 0);
+
+ // Set up parent link for clipping calculations
+ if (parentViz)
+ {
+ viz->SetCanvasFlags(EHuiCanvasFlagEnableCanvasClipping);
+ viz->SetParentCanvas(parentViz);
+ }
+ else
+ {
+ __ALFLOGSTRING1("CAlfBridge::HandleNewWindowL: Parent not found for visual %d!",windowNodeId);
+ }
+ }
+ else
+ {
+ __ALFLOGSTRING1("CAlfBridge::HandleNewWindowL: Control group not found for visual %d!",windowNodeId);
+ }
+
+ break;
+ }
+ default:
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleNewWindowL: Unknown window node type received !");
+ }
+ }
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+// ---------------------------------------------------------------------------
+// HandleDestroyWindow
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::DestroyWindow(CHuiVisual* aVisual, TBool aUseForce)
+ {
+ if ( !aUseForce && HasActiveEffect(aVisual) )
+ {
+ // this visual will be destroyed on the effect call back.
+ __ALFFXLOGSTRING1("CAlfBridge::DestroyWindow - not destroying 0x%x", aVisual);
+ aVisual->SetFlag(EHuiVisualFlagShouldDestroy);
+ // TODO: Revise
+ // move to effect controlgroup
+ //CHuiControl& effectControlGroup = iAlfScreens[0]->iFullscreenEffectControlGroup->Control(0);
+ //CHuiLayout* effectControlGroupLayout = (CHuiLayout*) &effectControlGroup.Visual(0);
+ // Transfers ownership of visuals.
+ //effectControlGroup.AppendL(aVisual, effectControlGroupLayout); // this will remove it from the previous layout
+ //aVisual->SetOwner(effectControlGroup);
+ return;
+ }
+ __ALFFXLOGSTRING1("CAlfBridge::DestroyWindow 0x%x", aVisual);
+ RemoveImageBrushL(*aVisual);
+ CHuiLayout* layout = aVisual->Layout();
+ if (layout)
+ layout->Remove(aVisual);
+ aVisual->Owner().Remove(aVisual);
+ __ALFLOGSTRING1("CAlfBridge::HandleDestroyWindow - destroying visual 0x%x", aVisual);
+ // check if visual is having an effect at the moment. This could occur, if options menu is exited (with effect) and then
+ // application is exited. EHuiVisualFlagDrawOnlyAsExternalContent is indication that
+ // there might be effect on this visual. It is not guaranteen.
+
+ delete aVisual;
+ }
+// ---------------------------------------------------------------------------
+// HandleDestroyWindowL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleDestroyWindowL( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+
+ switch (windowAttributes->iWindowNodeType)
+ {
+ case EAlfWinTreeNodeGroup:
+ {
+ DeleteControlGroupL(windowGroupNodeId, screenNumber);
+ break;
+ }
+ case EAlfWinTreeNodeClient:
+ case EAlfWinTreeNodeRoot:
+ case EAlfWinTreeNodeAnim:
+ case EAlfWinTreeNodeSprite:
+ case EAlfWinTreeNodeFloatingSprite:
+ case EAlfWinTreeNodeTextCursor:
+ {
+ // close cursor timer
+ if (windowAttributes->iWindowNodeType == EAlfWinTreeNodeTextCursor)
+ {
+ iCursorTimer->Cancel();
+ }
+
+ //just remove the visual
+ CHuiCanvasVisual* viz;
+
+ viz = (CHuiCanvasVisual*)FindVisual(windowNodeId);
+ CHuiControlGroup* controlGroup = FindControlGroup( windowGroupNodeId, screenNumber );
+ // Sprite is in its own group, and can be deleted normally.
+ if ( !controlGroup && windowAttributes->iWindowNodeType != EAlfWinTreeNodeSprite )
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleDestroyWindowL: group containing this visual has been destroyed.!");
+ // the group containing this visual has been destroyed. Thus the visual itself has been destroyed by
+ // the group. Ignore this.
+ }
+ else
+ {
+ // = (CHuiCanvasVisual*)de(windowNodeId, windowGroupNodeId,screenNumber);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleDestroyWindowL - Tracked visual"));
+ }
+#endif
+ DestroyWindow(viz);
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleDestroyWindowL: visual not found!");
+ }
+ }
+ RemoveVisual( windowNodeId );
+ break;
+ }
+ default:
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleDestroyWindowL: Unknown window node type received !");
+ break;
+ }
+ }
+ // TODO: Toolkit does not support recycling (of visuals),
+ // this is not in line with Nokia environmental policy...
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetWindowPosL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetWindowPosL( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ // fetch visual
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleSetWindowPosL - Tracked visual"));
+ }
+#endif
+
+ viz->SetPos(windowAttributes->iPosition, windowAttributes->iTransitionTime);
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowPosL, EAlfDSSetWindowPos: Visual not found!");
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetWindowSizeL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetWindowSizeL( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ // fetch visual
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleSetWindowSizeL - Tracked visual"));
+ }
+#endif
+ viz->SetSize(windowAttributes->iSize, windowAttributes->iTransitionTime);
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowSizeL, EAlfDSSetWindowSize: Visual not found!");
+ }
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetWindowRotationL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetWindowRotationL( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ // fetch visual
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleSetWindowRotationL - Tracked visual"));
+ }
+#endif
+ EnableVisualDefaultTransformationsL(*viz);
+ viz->Transformation()[KVisualTransformationStepRotate].iParams[0].Set(windowAttributes->iRotation,
+ windowAttributes->iTransitionTime);
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowRotationL, EAlfDSSetWindowRotation: Visual not found!");
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetWindowOpacityL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetWindowOpacityL( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ // fetch visual
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleSetWindowOpacityL - Tracked visual"));
+ }
+#endif
+ viz->iOpacity.Set(windowAttributes->iOpacity, windowAttributes->iTransitionTime);
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowOpacityL, EAlfDSSetWindowOpacity: Visual not found!");
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleReorderWindowL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleReorderWindowL( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ TInt ordinalPosition = windowAttributes->iOrdinalPosition;
+
+ switch (windowAttributes->iWindowNodeType)
+ {
+ case EAlfWinTreeNodeGroup:
+ {
+
+ // HACK !!!!
+ #ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ if (windowGroupNodeId == iAlfWindowGroupNodeId)
+ {
+ __ALFLOGSTRING1("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Alf window group going to: %d ",windowAttributes->iOrdinalPosition);
+ }
+ else
+ {
+ __ALFLOGSTRING1("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: WS window group going to: %d ",windowAttributes->iOrdinalPosition);
+ }
+ #endif
+
+ CHuiControlGroup* controlGroup = FindControlGroup(windowGroupNodeId,screenNumber);
+
+ if (!controlGroup)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Window server nodes are in inverted Z-order, we switch it here.
+ iAlfScreens[screenNumber]->iDisplay->Roster().Hide(*controlGroup);
+ TInt wsWindowGroupCount = 0;
+ for (TInt i=0; i<iAlfScreens[screenNumber]->iDisplay->Roster().Count();i++)
+ {
+ if (iAlfScreens[screenNumber]->iDisplay->Roster().ControlGroup(i).Control(0).Role()==EAlfWindowGroupContainer)
+ {
+ wsWindowGroupCount++;
+ }
+ }
+ ordinalPosition = wsWindowGroupCount - windowAttributes->iOrdinalPosition;
+
+ #ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+ __ALFLOGSTRING1("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: wsWindowGroupCount: %d ", wsWindowGroupCount);
+ __ALFLOGSTRING1("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Wimpautettu: %d ", ordinalPosition);
+ //RDebug::Print(_L("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Last total pos: %d "), iDisplay->Roster().Count() - 1);
+ #endif
+
+ if (ordinalPosition < -1)
+ {
+ ordinalPosition = -1; // show at top ?
+ }
+
+ if (iAlfScreens[screenNumber]->iDisplay && controlGroup)
+ {
+ ShowControlGroupL(iAlfScreens[screenNumber]->iDisplay->Roster(), *controlGroup, ordinalPosition, screenNumber);
+ }
+ else
+ {
+ __ALFLOGSTRING2("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Control group not found! Screen: %d, Id: %d ", screenNumber, windowNodeId );
+ }
+
+ ReorderAlfControlGroupsL(screenNumber);
+ break;
+ }
+ case EAlfWinTreeNodeClient:
+ case EAlfWinTreeNodeRoot:
+ case EAlfWinTreeNodeAnim:
+ case EAlfWinTreeNodeSprite:
+ case EAlfWinTreeNodeFloatingSprite:
+ case EAlfWinTreeNodeTextCursor:
+ {
+
+ // fetch visual
+ CHuiLayout* layout = NULL;
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleReorderWindowL - Tracked visual");
+ }
+#endif
+ layout = viz->Layout();
+ __ALFLOGSTRING3("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Id: %d, position %d, layout count %d", windowNodeId, windowAttributes->iOrdinalPosition, layout->Count() );
+ TInt pos = windowAttributes->iOrdinalPosition;
+ TInt layoutCount = layout->Count();
+
+ if (windowAttributes->iOrdinalPosition > layoutCount - 1 )
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Illegal visual index !");
+ pos = layoutCount - 1; // FixMe !!!
+ }
+
+ pos = layoutCount - pos - 1;
+ layout->Reorder(*viz, pos);
+ }
+ else
+ {
+ __ALFLOGSTRING2("CAlfBridge::HandleReorderWindowL, EAlfDSReorder: Visual not found! Screen: %d, Id: %d ", screenNumber, windowNodeId );
+ }
+ break;
+ }
+ default:
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleReorderWindowL: Unknown window node type received !");
+ break;
+ }
+ }
+
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+
+// ---------------------------------------------------------------------------
+// HandlePostCanvasBufferL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandlePostCanvasBufferL( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowCommandBufferAttributes* bufferAttributes = (TAlfWindowCommandBufferAttributes*)(*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = bufferAttributes->iScreenNumber;
+
+ CHuiCanvasVisual* viz = (CHuiCanvasVisual*)FindVisual(windowNodeId);
+
+ // For now we omit drawing commands to ALF window group because in some configurations it causes issues
+ // TODO: Possible viz->Flags() & EHuiVisualFlagDrawAf.. is not needed anymore. To be checked. Currently this enables floating sprites on the "root visual"
+ if (viz && iAlfWindowGroupNodeId != windowGroupNodeId
+ || ( viz && viz->Flags() & EHuiVisualFlagDrawAfterOthers )/* THIS LINE IS HACK FOR DRAWING FLOATING SPRITES */ )
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ TBool tracking( EFalse );
+ CHuiControlGroup* controlGroup = FindControlGroup( windowGroupNodeId, screenNumber );
+ CAlfScreen* screen = iAlfScreens[screenNumber];
+
+ //TInt clientWindowGroupId = FindClientWindowGroupId( screenNumber, *controlGroup );
+ // NOTE, THE FOLLOWING WServClientFileName MAY CAUSE DEADLOCK.
+ // THIS DOES NOT HAPPEN IF HUI_DEBUG_TRACK_DRAWING IS NOT ENABLED (DEFAULT)
+ TFileName processName;/* = iCommandDebug->WServClientFileName( clientWindowGroupId, CHuiStatic::WsSession() );
+
+ if ( viz->Tracking() ||
+ ( processName.Length() > 0 && iCommandDebug->TrackProcess( (HBufC16*)processName.Ptr() ) ) )
+ {
+ tracking = ETrue;
+ }*/
+#endif
+ // Now when we receive actual drawing commands, we can set the window as opaque (unless the flags say it isn't opaque).
+ if (bufferAttributes->iWindowNodeFlags & EAlfWinNodeFlagOpaque)
+ {
+ viz->SetFlag(EHuiVisualFlagOpaqueHint);
+ }
+
+ if (!viz->HasCommandBuffers(EFalse))
+ {
+ // For performance resons, only set visual tree changed if this
+ // was the first buffer for the window.
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+ TPtrC8 commands((TUint8*)bufferAttributes->iBuffer, bufferAttributes->iBufferLength);
+ if ( bufferAttributes->iEmptyThisBuffer )
+ {
+ viz->ClearCommandSet();
+ }
+ // If tracking has been enabled for this CHuiCanvasVisual object, the buffers will be marked for tracking aswell in CHuiCanvasVisual
+ switch( bufferAttributes->iPartStatus )
+ {
+ case TAlfWindowCommandBufferAttributes::EPartComplete:
+ {
+ viz->AddCommandSetL( commands );
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ viz->SetTrackCommandSet( processName, tracking );
+#endif
+ break;
+ }
+ case TAlfWindowCommandBufferAttributes::ENotComplete: // ENotComplete part should be eventually followed by ELastPart
+ {
+ viz->AddPartialCommandSetL( commands, EFalse );
+ break;
+ }
+ case TAlfWindowCommandBufferAttributes::ELastPart:
+ {
+ viz->AddPartialCommandSetL( commands, ETrue );
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ viz->SetTrackCommandSet( processName, tracking );
+#endif
+ break;
+ }
+ default:
+ __ALFLOGSTRING("CAlfBridge::HandlePostCanvasBufferL, EAlfDSPostCanvasBuffer: Unknown iPartStatus !!!!");
+ USER_INVARIANT();
+ break;
+ }
+ }
+ else
+ {
+ __ALFLOGSTRING3("CAlfBridge::HandlePostCanvasBufferL, EAlfDSPostCanvasBuffer: Visual not found! Screen: %d, Id: %d, GroupId: %d ", screenNumber, windowNodeId, windowGroupNodeId );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SetWindowActiveL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::SetWindowActiveL(CHuiVisual* aVisual, TBool aActive)
+ {
+ if (!HasActiveEffect(aVisual))
+ {
+ // Does not have effect
+ if (aActive)
+ {
+ aVisual->ClearFlags(EHuiVisualFlagShouldBeHidden | EHuiVisualFlagShouldBeShown);
+ aVisual->iOpacity.Set(KAlfVisualDefaultOpacity);
+ }
+ else
+ {
+ aVisual->ClearFlags(EHuiVisualFlagShouldBeShown | EHuiVisualFlagShouldBeHidden);
+ aVisual->iOpacity.Set(0.0f);
+ }
+ }
+ else
+ {
+ // Has effect
+ // these flags are put to action in RemoveTemporaryPresenterItem
+ if (aActive)
+ {
+ // this prevents windows appearing before their "effected" time
+ aVisual->SetFlag(EHuiVisualFlagShouldBeShown);
+ aVisual->ClearFlag(EHuiVisualFlagShouldBeHidden);
+ }
+ else
+ {
+ // this prevents windows disappearing before their effect has finished
+ aVisual->SetFlag(EHuiVisualFlagShouldBeHidden);
+ aVisual->ClearFlag(EHuiVisualFlagShouldBeShown);
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetWindowActiveL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetWindowActiveL( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)(*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+
+ if (windowAttributes->iWindowNodeType == EAlfWinTreeNodeTextCursor && iCursorTimer)
+ {
+ if (!windowAttributes->iActive)
+ {
+ iCursorTimer->Cancel();
+ }
+ else
+ {
+ SetCursorTimerL(); // continue with set interwal
+ }
+ }
+
+
+ switch (windowAttributes->iWindowNodeType)
+ {
+ case EAlfWinTreeNodeGroup:
+ {
+ CHuiControlGroup* controlGroup = FindControlGroup(windowGroupNodeId,screenNumber);
+ if (controlGroup)
+ {
+ CHuiControl& control = controlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ // Uses opacity for now
+ SetWindowActiveL(layout, windowAttributes->iActive);
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowActiveL, EAlfDSSetWindowActive: EAlfWinTreeNodeGroup not found!");
+ }
+ break;
+ }
+ case EAlfWinTreeNodeClient:
+ case EAlfWinTreeNodeRoot:
+ case EAlfWinTreeNodeAnim:
+ case EAlfWinTreeNodeSprite:
+ case EAlfWinTreeNodeFloatingSprite:
+ case EAlfWinTreeNodeTextCursor:
+ {
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ if ( viz->Tracking() )
+ {
+ RDebug::Print(_L("CAlfBridge::HandleSetWindowActiveL - Tracked visual"));
+ }
+#endif
+ // Uses opacity for now
+ SetWindowActiveL(viz, windowAttributes->iActive);
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowActiveL, EAlfDSSetWindowActive: Visual not found!");
+ }
+ break;
+ }
+ default:
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowActiveL, EAlfDSSetWindowActive: Unknown iWindowNodeType!");
+ USER_INVARIANT();
+ break;
+ }
+ }
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+
+
+// ---------------------------------------------------------------------------
+// HandleSetWindowFlagL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetWindowFlagL( TAlfBridgerData& aData, TInt aOp )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)(*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ TInt windowFlag = windowAttributes->iActive;
+ THuiVisualFlags visualFlag = (THuiVisualFlags)0;
+ switch(windowFlag)
+ {
+ case TAlfWindowData::EShouldInactivate:
+ {
+ visualFlag = EHuiVisualFlagShouldBeHidden;
+ break;
+ }
+ case TAlfWindowData::EShouldDestroy:
+ {
+ visualFlag = EHuiVisualFlagShouldDestroy;
+ break;
+ }
+ default:;
+ }
+
+ switch (windowAttributes->iWindowNodeType)
+ {
+ case EAlfWinTreeNodeGroup:
+ {
+ CHuiControlGroup* controlGroup = FindControlGroup(windowGroupNodeId,screenNumber);
+ if (controlGroup)
+ {
+ CHuiControl& control = controlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ // Uses opacity for now
+ if (aOp == EAlfDSSetWindowFlag)
+ {
+ layout->SetFlag(visualFlag);
+ }
+ else
+ {
+ layout->ClearFlag(visualFlag);
+ }
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowActiveL, EAlfDSSetWindowActive: EAlfWinTreeNodeGroup not found!");
+ }
+ break;
+ }
+ case EAlfWinTreeNodeClient:
+ case EAlfWinTreeNodeRoot:
+ case EAlfWinTreeNodeAnim:
+ case EAlfWinTreeNodeSprite:
+ case EAlfWinTreeNodeFloatingSprite:
+ case EAlfWinTreeNodeTextCursor:
+ {
+ CHuiVisual* viz = FindVisual(windowNodeId);
+ if (viz)
+ {
+ if (aOp == EAlfDSSetWindowFlag)
+ {
+ viz->SetFlag(visualFlag);
+ if (visualFlag == EHuiVisualFlagShouldDestroy )
+ {
+ if (windowAttributes->iWindowNodeType == EAlfWinTreeNodeTextCursor && iCursorTimer)
+ {
+ iCursorTimer->Cancel();
+ }
+ RemoveVisual(windowNodeId); // Only the effect will have pointer to this visual from here on
+ }
+ }
+ else
+ {
+ viz->ClearFlag(visualFlag);
+ }
+ }
+ else
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowFlagL, HandleSetWindowFlagL: Visual not found!");
+ }
+ break;
+ }
+ default:
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleSetWindowFlagL, HandleSetWindowFlagL: Unknown iWindowNodeType!");
+ USER_INVARIANT();
+ break;
+ }
+ }
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+
+// ---------------------------------------------------------------------------
+// InsertImageBrushL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::InsertImageBrushL(CHuiVisual& aVisual, TInt aBitmapHandle)
+ {
+ // NOTE: We wssume that image brush is always the only brush
+ CHuiTexture* texture = CHuiTexture::NewL();
+ CleanupStack::PushL(texture);
+ THuiImage image(*texture);
+ CHuiImageBrush* imageBrush = CHuiImageBrush::NewL(image);
+ imageBrush->SetLayer(EHuiBrushLayerForeground);
+ CleanupStack::Pop(texture);
+
+ aVisual.EnableBrushesL(ETrue);
+ aVisual.Brushes()->InsertL(0, imageBrush, EHuiHasOwnership);
+
+ UpdateImageBrushL(aVisual, aBitmapHandle);
+ }
+
+// ---------------------------------------------------------------------------
+// UpdateImageBrushL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::UpdateImageBrushL(CHuiVisual& aVisual, TInt aBitmapHandle)
+ {
+ // NOTE: We wssume that image brush is always the only brush with EImageBrush type
+ const TInt KAlfCanvasVisualImageBrushIndex = 0;
+
+ if (aVisual.Brushes() && aVisual.Brushes()->BrushWithTypeCount(CHuiBrush::EImageBrush))
+ {
+ CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
+ CleanupStack::PushL(bitmap);
+ bitmap->Duplicate(aBitmapHandle);
+
+ CHuiImageBrush* imageBrush = (CHuiImageBrush*) aVisual.Brushes()->BrushWithTypeAt(CHuiBrush::EImageBrush, KAlfCanvasVisualImageBrushIndex);
+ CHuiTexture* texture = (CHuiTexture*) &imageBrush->Image().Texture();
+
+ // Use of direct upload here would give much better performance, but is
+ // it too risky ?
+ texture->UploadL(*bitmap, NULL);
+ imageBrush->SetChanged();
+
+ CleanupStack::PopAndDestroy(bitmap);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// RemoveImageBrushL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::RemoveImageBrushL(CHuiVisual& aVisual)
+ {
+ // NOTE: We wssume that image brush is always the only brush with EImageBrush type
+ const TInt KAlfCanvasVisualImageBrushIndex = 0;
+
+ if (aVisual.Brushes() && aVisual.Brushes()->BrushWithTypeCount(CHuiBrush::EImageBrush))
+ {
+ CHuiImageBrush* imageBrush = (CHuiImageBrush*) aVisual.Brushes()->BrushWithTypeAt(CHuiBrush::EImageBrush, KAlfCanvasVisualImageBrushIndex);
+ CHuiTexture* texture = (CHuiTexture*) &imageBrush->Image().Texture();
+ THuiImage image;
+ imageBrush->SetImage(image);
+ delete texture;
+ }
+
+ if (aVisual.Brushes())
+ {
+ aVisual.EnableBrushesL(EFalse);
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// HandleSetSurfaceExtentL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetSurfaceExtentL( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)(*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+ // fetch visual
+ CHuiCanvasVisual* viz = FindVisual(windowNodeId);
+
+ // We should not do this for alf window, but renderstage does not know if it is
+ // handling alf window or other window, so we ignore the request here if needed.
+ // TODO: When alf apps work in multiple display, check here for every displays alf groups...
+ if (viz && iAlfWindowGroupNodeId != windowGroupNodeId)
+ {
+ viz->SetLayerExtent(windowAttributes->iSurfaceExtent);
+ // Set surface extend area to be cleared with fully transparent color
+ // Note: does not support extend that is bigger that the visual
+ // if surface extent is (0,0,0,0) then the background item array is reseted
+ // and surface extent will not be cleared.
+ if (windowAttributes->iSurfaceExtent != TRect())
+ {
+ // Set surface extend area to be cleared with fully transparent color
+ // Note: does not support extend that is bigger that the visual
+ TRgb fullyTransparentColor(255,0,0,0); // Red but fully transparent. Red color component has been set only for debug purposes, it is not visible.
+ viz->SetClearBackground(CHuiDisplay::EClearWithColor);
+ viz->SetBackgroundColor(fullyTransparentColor);
+ }
+ else
+ {
+ viz->SetClearBackground(CHuiDisplay::EClearNone);
+ }
+ }
+ else
+ {
+ if (iAlfWindowGroupNodeId != windowGroupNodeId)
+ __ALFLOGSTRING("CAlfBridge::HandleSetSurfaceExtentL, EAlfDSSetSurfaceExtent: Visual not found!");
+ }
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+
+// ---------------------------------------------------------------------------
+// HandleLayerUsesAlphaFlagChanged
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleLayerUsesAlphaFlagChanged( TAlfBridgerData& aData )
+ {
+ TInt windowGroupNodeId = aData.iInt1;
+ TInt windowNodeId = aData.iInt2;
+ TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)(*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ TInt screenNumber = windowAttributes->iScreenNumber;
+
+ // fetch visual
+ CHuiCanvasVisual* viz = (CHuiCanvasVisual*)FindVisual(windowNodeId);
+
+ // We should not do this for alf window, but renderstage does not know if it is
+ // handling alf window or other window, so we ignore the request here if needed.
+ // TODO: When alf apps work in multiple display, check here for every displays alf groups...
+ if (viz && iAlfWindowGroupNodeId != windowGroupNodeId)
+ {
+ viz->SetLayerUsesAlphaFlag(windowAttributes->iLayerUsesAlphaFlagEnabled);
+ }
+ else
+ {
+ if (iAlfWindowGroupNodeId != windowGroupNodeId)
+ __ALFLOGSTRING("CAlfBridge::HandleLayerUsesAlphaFlagChanged: Visual not found!");
+ }
+ iAlfScreens[screenNumber]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Check if really changed
+ }
+
+
+// ---------------------------------------------------------------------------
+// HandleGetNativeWindowDataL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleGetNativeWindowDataL( TAlfBridgerData& aData )
+ {
+ // Get the data from original Render Stage message
+ RMessage2* rsMessage = (RMessage2*)aData.iInt1;
+ TAlfNativeWindowData winData;
+ TPckg<TAlfNativeWindowData> winDataPckg(winData);
+ rsMessage->Read(0, winDataPckg);
+
+ if(winData.iScreenNumber == 0)
+ {
+ // primary screen
+ CHuiDisplay& disp = iHuiEnv->PrimaryDisplay();
+ if (disp.NativeWindow())
+ {
+ winData.iAlfWindowHandle = disp.NativeWindow()->ClientHandle();
+ winData.iAlfWindowGrpId = disp.NativeWindow()->WindowGroupId();
+ }
+ }
+ else
+ {
+ // other than primary screen
+ for (TInt i = 1; i < iAlfScreens.Count(); i++)
+ {
+ if (iAlfScreens[i]->iScreenNum == winData.iScreenNumber)
+ {
+ RDrawableWindow* win = iAlfScreens[i]->iCoeControl->DrawableWindow();
+ winData.iAlfWindowHandle = win->ClientHandle();
+ winData.iAlfWindowGrpId = win->WindowGroupId();
+ }
+ }
+ }
+
+ // write result
+ rsMessage->Write(0, winDataPckg);
+
+ if (winData.iAlfWindowHandle == 0)
+ {
+ __ALFLOGSTRING("CAlfBridge::HandleGetNativeWindowDataL, EAlfDSGetAlfNativeWindowData. Error: window data not found!");
+ }
+ }
+
+
+void CAlfBridge::PrepareFadeEffects( CHuiCanvasVisual& aVisual )
+ {
+ TBool faded = aVisual.CanvasFlags() & EHuiCanvasFlagExternalFade;
+ if (faded)
+ {
+ if (IsFadedByParent( aVisual ))
+ {
+ // Faded by parent
+ aVisual.SetCanvasFlags(EHuiCanvasFlagExternalFadeByParent);
+
+ // Faded by parent, include to parent effect
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExcludeFromParentEffect);
+
+ // Does not fade own children because parent already does that.
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExternalFadeToChildren);
+ }
+ else
+ {
+ // Not faded by parent
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExternalFadeByParent);
+
+ // Not faded by parent, exclude from parent effect
+ aVisual.SetCanvasFlags(EHuiCanvasFlagExcludeFromParentEffect);
+
+ // Does (or does not) fade own children if it can.
+ if (CanFadeChildren(aVisual))
+ {
+ aVisual.SetCanvasFlags(EHuiCanvasFlagExternalFadeToChildren);
+ }
+ else
+ {
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExternalFadeToChildren);
+ }
+ }
+ }
+ else
+ {
+ // Not faded
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExternalFadeByParent);
+
+ if (IsNearestParentEffectFade( aVisual ))
+ {
+ // Exclude from parent effect to avoid getting faded by parent.
+ aVisual.SetCanvasFlags(EHuiCanvasFlagExcludeFromParentEffect);
+ }
+ else
+ {
+ // By default included into parent effects.
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExcludeFromParentEffect);
+ }
+
+ // Does not fade own children because it is not faded itself.
+ aVisual.ClearCanvasFlags(EHuiCanvasFlagExternalFadeToChildren);
+ }
+
+ // Handle children
+ TInt count = aVisual.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ CHuiCanvasVisual* child = (CHuiCanvasVisual*) (&aVisual.Visual(i));
+ PrepareFadeEffects(*child);
+ }
+ }
+
+TBool CAlfBridge::LoadFadeEffectsL( CHuiCanvasVisual& aVisual )
+ {
+ TBool fadeEffectLoadedInsideTree = EFalse;
+
+ // Load fade effect (or remove existing)
+ fadeEffectLoadedInsideTree |= SetupFadeEffectL(aVisual);
+
+ // Handle children
+ TInt count = aVisual.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ CHuiCanvasVisual* child = (CHuiCanvasVisual*) (&aVisual.Visual(i));
+ fadeEffectLoadedInsideTree |= LoadFadeEffectsL(*child);
+ }
+
+ return fadeEffectLoadedInsideTree;
+ }
+
+
+TBool CAlfBridge::CanFadeChildren( CHuiCanvasVisual& aParent )
+ {
+ // NOTE! This function is not yet implemented optimally !!!!
+ // Below is some initial description how it could behave, but even that has some downsides.
+ // Ultimate solution which would implement legacy symbian fading functionality and
+ // on the other hand fully effectable solution needs to be developed at some point.
+ //
+ //
+ // This function shold determine wheter we can fade whole visual tree starting from aParent with just
+ // one fade effect. Even if visual tree has non-fading windows, it is possible to use tree fading
+ // in some cases where children can be excluded from parent visual effects using EHuiCanvasFlagExcludeFromParentEffect
+ // flag. However it changes drawing order of the childern (visuals with EHuiCanvasFlagExcludeFromParentEffect
+ // are drawn after other children) so it cannot be used in those cases without side-effect.
+ //
+ //
+ // V1 = Visual 1, parent of Visual 2 etc. Index number refers to order how visuals are drawn.
+ // (f) = Visal is faded
+ //
+ // Example scenario 1) CanFadeChildren(V1) (YES)
+ // CanFadeChildren(V2) (YES) (Can fade because faded child is drawn first, but no need because parent can fade as well)
+ //
+ // V4 V3(f)
+ // \ /
+ // \ /
+ // V5(f) V2(f)
+ // \ /
+ // \ /
+ // V1(f)
+ //
+ // Example Scenario 2) CanFadeChildren(V1) (NO) (Cant fade because nonfading grandchild draw before faded)
+ // CanFadeChildren(V2) (NO) (Can't fade children because non-faded child is drawn first)
+ //
+ // V4(f) V3
+ // \ /
+ // \ /
+ // V5(f) V2(f)
+ // \ /
+ // \ /
+ // V1(f)
+ //
+ // Example scenario 3) CanFadeChildren(V1) (YES) (Can fade because faded child (V2) is drawn first)
+ // CanFadeChildren(V2) (YES) (Can fade because all children are faded, but no need because parent can fade as well)
+ //
+ // V4(f) V3(f)
+ // \ /
+ // \ /
+ // V5 V2(f)
+ // \ /
+ // \ /
+ // V1(f)
+ //
+ // Scenario 4) CanFadeChildren(V1) (NO) (Can't fade because non-faded child is drawn first)
+ // CanFadeChildren(V2) (NO) (It would be YES, but V2 it self is not faded -> NO)
+ //
+ // V4(f) V3(f)
+ // \ /
+ // \ /
+ // V5(f) V2
+ // \ /
+ // \ /
+ // V1(f)
+ //
+ // Scenario 5) CanFadeChildren(V1) (NO) (Can't fade because non-faded child is drawn first)
+ // CanFadeChildren(V2) (NO) (Can't fade children because it does not have children)
+ // CanFadeChildren(V3) (YES) (All children are faded)
+ //
+ // V4(f) V4(f)
+ // \ /
+ // \ /
+ // V3(f) V2
+ // \ /
+ // \ /
+ // V1(f)
+ //
+ //
+ // TODO: Real implementation for algorithm which takes into account the order of non-fading and
+ // fading children. Current implentation has side-effect where drawing order of non-fading
+ // children may get altered. But on the other hand without visual treefader (i.e each visual
+ // faded with separate effects) there still exists a potential problem with faded transparent
+ // windows above faded windows (double fade)!
+ //
+
+ // For now this function just checks if there are children to be faded...
+ return HasActiveFadedChildren( aParent );
+ }
+
+
+TInt CAlfBridge::RecursiveChildCount( CHuiCanvasVisual& aParent, TInt aCanvasFlags )
+ {
+ TInt childCount = 0;
+ TInt count = aParent.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ CHuiCanvasVisual* child = (CHuiCanvasVisual*) (&aParent.Visual(i));
+ if (aCanvasFlags)
+ {
+ if (child->CanvasFlags() & aCanvasFlags)
+ {
+ childCount++;
+ }
+ }
+ else
+ {
+ childCount++;
+ }
+ childCount += RecursiveChildCount( *child, aCanvasFlags );
+ }
+ return childCount;
+ }
+
+TBool CAlfBridge::IsNearestParentEffectFade( CHuiCanvasVisual& aVisual )
+ {
+ TBool nearestParentEffectFade = EFalse;
+ CHuiCanvasVisual* parent = (CHuiCanvasVisual*) (aVisual.Layout());
+ while (parent)
+ {
+ if (parent->Effect())
+ {
+ nearestParentEffectFade |= (parent->Effect() && (parent->Effect()->EffectFlags() & KHuiFadeEffectFlag));
+ return nearestParentEffectFade;
+ }
+ parent = (CHuiCanvasVisual*) (parent->Layout());
+ }
+ return EFalse;
+ }
+
+
+TBool CAlfBridge::IsFadedByParent( CHuiCanvasVisual& aVisual )
+ {
+ CHuiCanvasVisual* parent = (CHuiCanvasVisual*) (aVisual.Layout());
+ while (parent)
+ {
+ TInt flags = parent->CanvasFlags();
+ if ((flags & EHuiCanvasFlagExternalFade) && (flags & EHuiCanvasFlagExternalFadeToChildren))
+ {
+ return ETrue;
+ }
+ parent = (CHuiCanvasVisual*) (parent->Layout());
+ }
+ return EFalse;
+ }
+
+TBool CAlfBridge::HasActivePaintedAreas( CHuiCanvasVisual& aVisual, TBool aIncludeChildren )
+ {
+ TBool visualHasPaintedAreas = aVisual.PaintedAreaCount() > 0;
+ if (!visualHasPaintedAreas && aIncludeChildren)
+ {
+ TInt count = aVisual.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ CHuiCanvasVisual* child = (CHuiCanvasVisual*) (&aVisual.Visual(i));
+ TBool childIsActive = !(child->Flags() & EHuiVisualFlagInactive);
+ if (childIsActive && child->PaintedAreaCount())
+ {
+ visualHasPaintedAreas = ETrue;
+ break;
+ }
+ }
+ }
+ return visualHasPaintedAreas;
+ }
+
+TBool CAlfBridge::HasActiveFadedChildren( CHuiCanvasVisual& aVisual )
+ {
+ TBool has = EFalse;
+ TInt count = aVisual.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ CHuiCanvasVisual* child = (CHuiCanvasVisual*) (&aVisual.Visual(i));
+ TBool active = !(child->Flags() & EHuiVisualFlagInactive);
+ TBool faded = child->CanvasFlags() & EHuiCanvasFlagExternalFade;
+
+ if (active && faded && child->PaintedAreaCount())
+ {
+ has = ETrue;
+ break;
+ }
+ }
+ return has;
+ }
+
+
+// ---------------------------------------------------------------------------
+// SetupFadeEffectL
+//
+// NOTE: This method gets called very often, so we should not do anything time
+// consuming here (unless we really need to).
+//
+// ---------------------------------------------------------------------------
+//
+TBool CAlfBridge::SetupFadeEffectL( CHuiCanvasVisual& aVisual )
+ {
+ TBool didFadeEffectLoad = EFalse;
+
+ TBool faded = (aVisual.CanvasFlags() & EHuiCanvasFlagExternalFade);
+
+ // Just in case, check if we are alrady faded to avoid unnecassary effect loadings.
+ TBool alreadyFaded = aVisual.Effect() && (aVisual.Effect()->EffectFlags() & KHuiFadeEffectFlag);
+
+ TBool fadesChildren = EFalse;
+
+ if (faded)
+ {
+ fadesChildren = (aVisual.CanvasFlags() & EHuiCanvasFlagExternalFadeToChildren);
+
+ // Inactive visuals are not faded.
+ TBool visualIsActive = !(aVisual.Flags() & EHuiVisualFlagInactive);
+
+ // Avoid interrupting other effects.
+ TBool otherEffectActive = aVisual.Effect() && !(aVisual.Effect()->EffectFlags() & KHuiFadeEffectFlag);
+
+ // Check if we really need to fade. Note the order of if-conditions, fastest checks first to optimize performance.
+ if (visualIsActive && !alreadyFaded && !otherEffectActive && !IsFadedByParent(aVisual) && HasActivePaintedAreas(aVisual, fadesChildren))
+ {
+ CHuiFxEffect* effect = NULL;
+ CHuiFxEngine* engine = iHuiEnv->EffectsEngine();
+
+ if (engine && iFadeEffectFile )
+ {
+ __ALFLOGSTRING1( ">> Using cached fade effect file name: %S", iFadeEffectFile );
+ TInt err = 0;
+ // CHuiFxParser sets the effect to visual if loading succeeds.
+ TInt effectFlags = 0;
+ effectFlags |= KHuiFadeEffectFlag;
+ effectFlags |= KHuiFxEffectDisableMarginsFlag; // Margins cannot safely be used in fade usecase, artefacts may appear depending on window location in window tree
+
+ // For top level canvas visuals (window group visuals) disable background for
+ // performance reasons (in case canvas visual is not opaque).
+ if (!aVisual.Layout())
+ {
+ effectFlags |= KHuiFxDisableBackground;
+ }
+
+ if (fadesChildren)
+ {
+ /*
+ TInt children = RecursiveChildCount( aVisual, 0 );
+ TInt faded = RecursiveChildCount( aVisual, EHuiCanvasFlagExternalFade );
+ TInt fadedbyparent = RecursiveChildCount( aVisual, EHuiCanvasFlagExternalFadeByParent );
+ TInt excludedfromparenteffect = RecursiveChildCount( aVisual, EHuiCanvasFlagExcludeFromParentEffect );
+ RDebug::Print(_L("CAlfBridge::SetupFadeEffectL - faded parent has %i children"), children);
+ RDebug::Print(_L("CAlfBridge::SetupFadeEffectL - faded parent has %i faded children"), faded);
+ RDebug::Print(_L("CAlfBridge::SetupFadeEffectL - faded parent fades %i children"), fadedbyparent);
+ RDebug::Print(_L("CAlfBridge::SetupFadeEffectL - faded parent has %i children which are excluded from parent fx"), excludedfromparenteffect);
+ */
+ }
+ else
+ {
+ // All children in the tree are not faded, do not apply effect on children.
+ effectFlags |= KHuiFxEffectExcludeChildrenFlag;
+ //RDebug::Print(_L("CAlfBridge::SetupFadeEffectL - no children faded by parent"));
+ }
+ TRAP( err, engine->LoadEffectL(*iFadeEffectFile, effect, aVisual.Effectable(), NULL, NULL, 0, effectFlags ) );
+ didFadeEffectLoad = ETrue;
+ }
+ }
+ }
+ else
+ {
+ // remove only an old fade effect, leave any others intact
+ if (alreadyFaded)
+ {
+ aVisual.SetEffect( NULL );
+ alreadyFaded = EFalse;
+ }
+ }
+
+ // If we did load and fade children we must re-prepare the flags again
+ // Maybe there is more elegant way to avoid this.
+ if (didFadeEffectLoad && fadesChildren)
+ {
+ PrepareFadeEffects( aVisual );
+ }
+
+ return (didFadeEffectLoad || alreadyFaded);
+ }
+
+
+// ---------------------------------------------------------------------------
+// HandleSetFadeEffect
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetFadeEffectL( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt1;
+ TBool faded = aData.iInt2;
+
+ CHuiVisual* viz = (CHuiVisual*)FindVisual(windowNodeId);
+ if (!viz)
+ {
+ // Visual not found, it could be window group. It must be searched with other method.
+ CHuiControlGroup* cg = FindControlGroup(windowNodeId, 0); // TODO: Screen
+ if (cg)
+ {
+ CHuiControl& control = cg->Control(0);
+ viz = &control.Visual(0);
+ }
+ }
+
+ if ( viz )
+ {
+ CHuiCanvasVisual* canvasviz = (CHuiCanvasVisual*)viz;
+ if (faded)
+ {
+ canvasviz->SetCanvasFlags(EHuiCanvasFlagExternalFade);
+ }
+ else
+ {
+ canvasviz->ClearCanvasFlags(EHuiCanvasFlagExternalFade);
+ }
+ iAlfScreens[0]->SetVisualTreeVisibilityChanged(ETrue); // TODO: Screen
+ }
+ }
+
+void CAlfBridge::HandleSetLayoutSwitchEffectL()
+ {
+ ClearCanvasVisualCommandSets(EFalse);
+ iLayoutSwitchEffectCoordinator->BeginLayoutSwitch();
+ }
+
+TInt Blink(TAny* aVisual)
+ {
+ CHuiVisual* visual = (CHuiVisual*)aVisual;
+ if (visual->iOpacity.Now() > 0.01 ) // kind of an epsilon
+ {
+ visual->iOpacity.Set(0);
+ }
+ else
+ {
+ visual->iOpacity.Set(1);
+ }
+
+ return ETrue; // call me again
+ }
+
+void CAlfBridge::SetCursorTimerL(TUint aTime, CHuiVisual* aCursor)
+ {
+ if (aTime)
+ {
+ iCursorInterval = aTime;
+ }
+
+ if (aCursor)
+ {
+ iCursorVisual = aCursor;
+ }
+
+ if (iCursorInterval && iCursorVisual)
+ {
+ if (iCursorTimer)
+ {
+ iCursorTimer->Cancel();
+ }
+
+ if (!iCursorTimer)
+ {
+ iCursorTimer = CPeriodic::NewL(CActive::EPriorityHigh);
+ }
+
+ iCursorTimer->Start(iCursorInterval, iCursorInterval, TCallBack(Blink, aCursor));
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetCursorDataL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::HandleSetCursorDataL( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt2;
+
+ TAlfCursorDataBufferAttributes* windowAttributes = (TAlfCursorDataBufferAttributes*) (*iHost)->GetVarDataL( (TInt)aData.iPtr );
+ CHuiVisual* viz = (CHuiVisual*)FindVisual(windowNodeId);
+ if (viz)
+ {
+ viz->SetFlags(windowAttributes->iFlags);
+ SetCursorTimerL(windowAttributes->iFlashInterval, viz);
+ }
+ else
+ {
+ __ALFLOGSTRING1("CAlfBridge::HandleSetCursorDataL - WARNING! Cursor node 0x%x not found!", windowNodeId);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// HandleSetNodeTracking
+// ---------------------------------------------------------------------------
+//
+#ifdef HUI_DEBUG_TRACK_DRAWING
+void CAlfBridge::HandleSetNodeTracking( TAlfBridgerData& aData )
+ {
+ TInt windowNodeId = aData.iInt1;
+ CHuiCanvasVisual* viz = (CHuiCanvasVisual*)FindVisual(windowNodeId);
+ if ( aData.iInt2 )
+ {
+ viz->SetTracking( aData.iInt2 );
+ }
+#else
+void CAlfBridge::HandleSetNodeTracking( TAlfBridgerData& )
+ {
+#endif
+ }
+
+void RecursiveStoreRenderBufferL(CHuiVisual *aVisual)
+ {
+ CHuiCanvasVisual *canvasvisual = dynamic_cast<CHuiCanvasVisual*>(aVisual);
+ if (canvasvisual && canvasvisual->Layout())
+ {
+ canvasvisual->StoreRenderBufferL();
+ }
+
+ TInt c = aVisual->Count();
+ for(int i=0;i<c;i++)
+ {
+ CHuiVisual &vis = aVisual->Visual(i);
+ RecursiveStoreRenderBufferL(&vis);
+ }
+ }
+
+void StoreRenderBufferStartL(CHuiLayout *aLayout)
+ {
+ // assumes that the layout takes full screen area.
+ CHuiRenderPlugin& renderplugin = CHuiStatic::Renderer();
+ CHuiCanvasGc *canvasGc = renderplugin.CreateCanvasGcL();
+ CleanupStack::PushL(canvasGc);
+
+ CHuiCanvasRenderBuffer *renderBuffer;
+ renderBuffer = canvasGc->CreateRenderBufferL(TSize(0,0));
+ CleanupStack::PushL(renderBuffer);
+ renderBuffer->InitializeL(CHuiStatic::Env().Display(0).VisibleArea().Size());
+ renderBuffer->Copy(TPoint(0,0));
+ CleanupStack::Pop(renderBuffer);
+ aLayout->SetStoredRenderBuffer(renderBuffer); // moves ownership
+
+ CleanupStack::PopAndDestroy();
+ }
+TBool NeedsStoredBuffers(CHuiFxEngine *aEngine, const TDesC &aFileName)
+ {
+ return aEngine->FxmlUsesInput1(aFileName);
+ }
+
+TBool CAlfBridge::HandleGfxEventL(CFullScreenEffectState& aEvent, CHuiLayout* aToLayout, CHuiLayout *aFromLayout)
+ {
+ TInt err = KErrNone;
+ TBool failed = EFalse;
+
+ // Check if there is an effects engine in HuiEnv
+ CHuiFxEffect* effect = NULL;
+ // We need to pass the filenamerta from the transeffect plugin that handles the controls
+ // that define which effect is used for the selected skin or the selected application
+ // For full screen effects the skin should determine the effect, or there should be
+ // some default effects.
+
+ CHuiFxEngine* engine = NULL;
+ // engine is not owned by us, it is a member of HuiEnv
+ engine = iHuiEnv->EffectsEngine();
+
+ if ( engine )
+ {
+ switch(aEvent.iOperation)
+ {
+ case MAlfGfxEffectPlugin::EBeginFullscreen:
+ {
+ aToLayout->SetStoredRenderBufferModificationsEnabled(ETrue);
+ TBool needStoredBuffers = NeedsStoredBuffers(engine, *aEvent.iEffectName);
+ if (needStoredBuffers)
+ {
+ TRAP(err,StoreRenderBufferStartL(aToLayout));
+ if (err == KErrNone)
+ {
+ aToLayout->SetFreezeState(ETrue);
+ }
+ else
+ {
+ return ETrue; // failed, effect will be canceled
+ }
+ }
+
+ switch(aEvent.iAction)
+ {
+ case AknTransEffect::EApplicationStart:
+ case AknTransEffect::EApplicationStartRect:
+ {
+ aToLayout->iOpacity.Set(0.0f); // these are meant for applications that yet dont have anything to show
+ FreezeLayoutUntilEffectDestroyedL(aFromLayout, aEvent.iHandle);
+ break;
+ }
+ case AknTransEffect::EApplicationStartSwitch:
+ case AknTransEffect::EApplicationStartSwitchRect:
+ {
+ aToLayout->iOpacity.Set(0.0f); // this is meant for applications that are in the background.
+ FreezeLayoutUntilEffectDestroyedL(aFromLayout, aEvent.iHandle);
+ break;
+ }
+
+ case AknTransEffect::EApplicationExit:
+ {
+ // The effect should start when the new view is ready,
+ // but we have no signal telling us that, so we just have to do our best
+
+ // Effect end observer is given to engine in LoadEffectL
+ // It will be set to effect there and called when the effect ends or is deleted
+
+ // The layout should be visible at this time. if not, then this is assumed
+ // as effect to an background application and ignored.
+ if (aToLayout->Effect())
+ {
+ // effect on a layout must be an application start effect.
+ // External content visual is not used for that.
+ __ALFFXLOGSTRING2("CAlfBridge::HandleGfxEventL - Found effect on layout 0x%x. Removing effect 0x%x", aToLayout, aToLayout->Effect());
+ aToLayout->SetEffect(NULL);
+ }
+ if (!(aToLayout->Flags() & EHuiVisualFlagInactive))
+ {
+ // this will tag the visual, that they cannot be hidden by HandleVisualVisibility
+ // Initialize layout for the exit effect
+ iLayoutInitializedForExitEffect = SetupEffectLayoutContainerL(aEvent.iHandle, aToLayout, ETrue);
+ aEvent.iSetupDone = iLayoutInitializedForExitEffect;
+ }
+ else
+ {
+ iLayoutInitializedForExitEffect = EFalse;
+ }
+ return failed;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case MAlfGfxEffectPlugin::EEndFullscreen:
+ {
+ TBool layoutEffectable(EFalse);
+ if (aEvent.iAction != 5000)
+ {
+ if ( aEvent.iAction != AknTransEffect::EApplicationExit && aToLayout->Flags() & EHuiVisualFlagInactive)
+ {
+ aToLayout->iOpacity.Set(1.0f);
+ failed = ETrue;
+ return failed;
+ }
+
+ if (aToLayout)
+ {
+ aToLayout->iOpacity.Set(1.0f);
+ __ALFFXLOGSTRING1("HandleGfxEventL - loading effect, handle %d", aEvent.iHandle );
+ if (aEvent.iAction == AknTransEffect::EApplicationExit)
+ {
+ // Exit effect was initialized earlier with EBeginFullscreen event
+ layoutEffectable = iLayoutInitializedForExitEffect;
+ }
+ else
+ {
+ // add visuals to visual cleanupstack
+ aToLayout->SetStoredRenderBufferModificationsEnabled(EFalse);
+ layoutEffectable = SetupEffectLayoutContainerL(aEvent.iHandle,aToLayout, EFalse);
+ aEvent.iSetupDone = layoutEffectable;
+ aToLayout->SetStoredRenderBufferModificationsEnabled(ETrue);
+ }
+
+ if (layoutEffectable)
+ {
+ if (aEvent.iRect != TRect())
+ {
+ TRAP( err, engine->LoadGroupEffectL( *aEvent.iEffectName, effect, aToLayout->Effectable(), engine->ActiveGroupEffect(), &aEvent.iRect, this, aEvent.iHandle ) );
+ }
+ else
+ {
+ TRAP( err, engine->LoadGroupEffectL( *aEvent.iEffectName, effect, aToLayout->Effectable(), engine->ActiveGroupEffect(), NULL, this, aEvent.iHandle ) );
+ }
+ effect = NULL;
+ // only use the effect if the effect file was correctly parsed
+ if (err != KErrNone)
+ {
+ // visuals added to "active effect visual" stack, but they wont be used, because effect loading has failed. cleanup.
+ RemoveTemporaryPresenterVisual(NULL, aEvent.iHandle);
+ aToLayout->SetEffect(NULL);
+ failed = ETrue;
+ }
+ }
+ else
+ {
+ failed = ETrue;
+ __ALFFXLOGSTRING2("CAlfBridge::HandleGfxEventL - Effect layout initialization failed. Skipping effect handle: %d, Visual: 0x%x", aEvent.iHandle, aToLayout);
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ // just in case...
+ break;
+ }
+ }
+ }
+ iLastAction = aEvent.iAction; // TODO: useless?
+ return failed;
+ }
+
+void CAlfBridge::FreezeLayoutUntilEffectDestroyedL(CHuiLayout* aLayout, TInt aHandle)
+ {
+ if (aLayout)
+ {
+ TRAPD(err, StoreRenderBufferStartL(aLayout));
+ if (err == KErrNone)
+ {
+ // Freeze only, if buffer was reserved succesfully
+ aLayout->SetFreezeState(ETrue);
+ TBool itemsDestroyed;
+ AddEffectItemL(aHandle, aLayout, NULL, NULL, EFalse, itemsDestroyed, EFalse);
+ iFullScreenEffectData->iAppStartScreenshotItemHandle = aHandle;
+ }
+ }
+ }
+
+void CAlfBridge::HandleGfxStopEvent( TBool aClientRequest )
+ {
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxStopEvent BEGIN");
+ if (!iFullScreenEffectData)
+ {
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxStopEvent - END: none");
+ return;
+ }
+
+ CFullScreenEffectState* fxData = iFullScreenEffectData;
+ iFullScreenEffectData = NULL;
+ CleanupStack::PushL( fxData );
+
+ __ALFFXLOGSTRING2(" - handle: %d, toAppUid: 0x%x", fxData->iHandle, fxData->iToAppId);
+
+ // clean effects with this handle
+ RemoveTemporaryPresenterVisual(NULL, fxData->iHandle);
+ // this was abort, so we might have received earlier event hiding this window. Here we'll bring it
+ // back
+ if (fxData->iToAppId && fxData->iToAppId != KErrNotFound)
+ {
+ RemoveEffectFromApp(fxData->iToAppId);
+ RemoveEffectFromApp(fxData->iFromAppId);
+ }
+ else
+ {
+ // abort ALL effects
+ RemoveAllTemporaryPresenterVisuals();
+ }
+
+ iHuiEnv->ContinueRefresh();
+
+ if ( !aClientRequest )
+ {
+ // Aborted errornously, signal client side
+ RProperty::Set( KPSAlfDomain, KAlfTransitionStatus, fxData->iCompletionHandle );
+ }
+
+ CleanupStack::PopAndDestroy( fxData );
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxStopEvent - END");
+ }
+
+void CAlfBridge::RemoveEffectFromApp(TInt aAppUid)
+ {
+ if(aAppUid <= 0)
+ {
+ return;
+ }
+ CHuiControlGroup* group = FindControlGroupByAppId(aAppUid);
+ if (group)
+ {
+ CHuiControl& control = group->Control(0);
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+
+ TInt handle = FindEffectHandle(layout);
+ if (handle != KErrNotFound)
+ {
+ __ALFFXLOGSTRING2("CAlfBridge::HandleGfxStopEvent - layout visual: 0x%x ; handle: %d ", layout, handle);
+ RemoveTemporaryPresenterVisual(NULL, handle);
+ }
+ layout->iOpacity.Set(1.0f);
+ }
+ }
+
+CAlfBridge::CEffectState::CEffectState()
+ {
+ // CBase clears all variables
+ }
+
+CAlfBridge::CEffectState::~CEffectState()
+ {
+ delete iEffectName;
+ }
+
+void CAlfBridge::CEffectState::ResolveFileNameL(RMemReadStream& aStream)
+ {
+ HBufC* effectDirectory = HBufC::NewLC(aStream, 256);
+ HBufC* effectFile = HBufC::NewLC(aStream, 256);
+
+ // Add one extra because we want to be able to append a number to the filename
+ HBufC* effectFullName = HBufC::NewL(effectDirectory->Des().Length()
+ + effectFile->Des().Length() + 1);
+ CleanupStack::PushL(effectFullName);
+
+ effectFullName->Des().Copy(*(effectDirectory));
+ effectFullName->Des().Append(*(effectFile));
+ delete iEffectName;
+ iEffectName = effectFullName; // ownership transferred
+ CleanupStack::Pop(effectFullName);
+ CleanupStack::PopAndDestroy(2, effectDirectory);
+ }
+
+void CAlfBridge::CFullScreenEffectState::ConstructL(
+ TInt aAction,
+ RMemReadStream& aStream)
+ {
+ iAction = aAction;
+
+ iHandle = aStream.ReadInt32L();
+
+ iType = aStream.ReadInt32L();
+ iWg1 = aStream.ReadInt32L();
+ iWg2 = aStream.ReadInt32L();
+ iToAppId = aStream.ReadInt32L();
+ iFromAppId = aStream.ReadInt32L();
+
+ if (iType == AknTransEffect::EParameterType)
+ {
+ /*screen1 =*/aStream.ReadInt32L();
+ /*screen2 =*/aStream.ReadInt32L();
+ }
+ /*TInt flags =*/
+ aStream.ReadInt32L();
+ iRect.iTl.iX = aStream.ReadInt32L();
+ iRect.iTl.iY = aStream.ReadInt32L();
+ iRect.iBr.iX = aStream.ReadInt32L();
+ iRect.iBr.iY = aStream.ReadInt32L();
+
+ ResolveFileNameL(aStream);
+
+ iCompletionHandle = iHandle;
+ }
+
+void CAlfBridge::CControlEffectState::ConstructL(TInt aAction,
+ RMemReadStream& aStream)
+ {
+ iAction = aAction;
+ TInt operation = aStream.ReadInt32L();
+ iHandle = aStream.ReadInt32L();
+ iClientHandle = aStream.ReadInt32L();
+ iClientGroupHandle = aStream.ReadInt32L();
+ TInt screenNumber = aStream.ReadInt32L(); // this has always value 0
+ // Are Symbian full filename+directory combinations still max 256 characters long?
+ ResolveFileNameL(aStream);
+ }
+
+// ---------------------------------------------------------------------------
+// HandleGfxEffectsL
+// ---------------------------------------------------------------------------
+//
+
+void CAlfBridge::HandleGfxEffectsL( TAlfBridgerData data )
+ {
+ // This method is called when "Begin fullscreen" and "End fullscreen" are
+ // invoked. Data in "Begin fullscreen" is used, "End fullscreen" and
+ // "Abort fullscreen" (HandleStopGfxEffectsL) are just signals.
+ // As a general limitation, there can be exactly one fullscreen effect
+ // ongoing at once.
+
+ TInt action = data.iInt1;
+ TInt length = data.iInt2;
+ __ALFFXLOGSTRING1("CAlfBridge::HandleGfxEffectsL - BEGIN (bridge data %d)", (TInt)data.iPtr);
+ void* bridgeBuffer = (void*) (*iHost)->GetEffectsDataL( (TInt)data.iPtr );
+ RMemReadStream stream( bridgeBuffer, length );
+
+ // operation tells if this is begin full screen or end full screen
+ TInt operation = stream.ReadInt32L();
+
+ if ( operation == MAlfGfxEffectPlugin::EBeginFullscreen )
+ {
+ if ( !iFullScreenEffectData || !iFullScreenEffectData->iSetupDone )
+ {
+ // No fullsceen effect ongoing or fullscreen effect hasn't yet been set up,
+ // so we can initialize iFullScreenEffectData from stream.
+
+ __ALFFXLOGSTRING("HandleGfxEffectsL - fresh start");
+
+ CFullScreenEffectState* fxData = new (ELeave) CFullScreenEffectState;
+ CleanupStack::PushL( fxData );
+ fxData->ConstructL( action, stream );
+ CleanupStack::Pop( fxData );
+
+ // the effect handle of freezed layout (iAppStartScreenshotItemHandle) must match the actual
+ // effect handle that is run. Only then frozen application can be freed at the end of the effect
+ if (iFullScreenEffectData)
+ {
+ for (TInt i = 0; i < iEffectCleanupStack.Count(); i++)
+ {
+ TEffectCleanupStruct& effectItem = iEffectCleanupStack[i];
+ if (iFullScreenEffectData->iAppStartScreenshotItemHandle == effectItem.iHandle)
+ {
+ effectItem.iHandle = fxData->iHandle;
+ }
+ }
+ }
+
+ if (iFullScreenEffectData && iFullScreenEffectData->iToAppId != fxData->iToAppId)
+ {
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxEffectsL - WARNING - Another fullscreen effect to different app. Deleting the previous ongoing effect");
+ RemoveEffectFromApp(iFullScreenEffectData->iToAppId);// Fullscreen effect for another app has arrived, and the previous has not finished and abort effect was not called.
+ RemoveEffectFromApp(iFullScreenEffectData->iFromAppId);
+ // Fullscreen effect for another
+ }
+
+ delete iFullScreenEffectData;
+ iFullScreenEffectData = fxData;
+ iFullScreenEffectData->iAppStartScreenshotItemHandle = fxData->iHandle;
+
+ stream.Release();
+ }
+ else
+ {
+ // Fullscreen effect is ongoing. We could either use new data
+ // and abort the ongoing effect, or just continue ongoing.
+ // For now, we continue ongoing.
+
+ __ALFFXLOGSTRING("HandleGfxEffectsL - END: ongoing");
+
+ // Client expects completion to be signalled with this handle.
+ iFullScreenEffectData->iCompletionHandle = stream.ReadInt32L();
+
+ stream.Release();
+ return ;
+ }
+ }
+ else // MAlfGfxEffectPlugin::EEndFullscreen
+ {
+ stream.Release();
+
+ // End fullscreen signal received. We proceed only if there is really
+ // effect ongoing and "end fullscreen" hasn't already been processed.
+
+ if ( !iFullScreenEffectData || iFullScreenEffectData->iEndFullScreen )
+ {
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxEffectsL - END: fx ready");
+ return;
+ }
+
+ __ALFFXLOGSTRING("HandleGfxEffectsL - process end");
+ iFullScreenEffectData->iEndFullScreen = ETrue;
+ }
+
+ CFullScreenEffectState* fxData = iFullScreenEffectData;
+ fxData->iOperation = operation;
+ fxData->iWaitingWindowGroup = EFalse;
+
+ __ALFFXLOGSTRING3("Operation: %d, handle: %d, type: %d", operation, fxData->iHandle, fxData->iType);
+ __ALFFXLOGSTRING2("wg1: %d, wg2: %d", fxData->iWg1, fxData->iWg2);
+
+ // find root nodes and attach effects to them
+ // First we need a windowgroup node id. So far we have a list of window ids
+
+ // wg2 is the window group that is supposed to disappear from view
+ // when a new application starts. We don't have any use for it now...
+
+ // This is the group that is disappearing
+ // Currently we don't add an effect to it.
+
+ // TODO: when ids available from wserv...
+ // if ( appUid2 )
+ //{
+ // group2 = FindControlGrouAppUId( appUid2, screen2, &alfGroup );
+ // }
+ //if ( toAppId2 )
+ // {
+ // group2 = FindControlGroupByAppId(toAppId2);
+ // }
+ //if ( wg2 && wg2 != KErrNotFound )
+ // {
+ // group2 = FindControlGroupByWindowGroupId( wg2, screen2 );
+ // }
+ // if ( group2 )
+ // {
+ // CHuiControl& control = group2->Control(0);
+ // layout2 = (CHuiLayout*)&control.Visual(0);
+ // }
+
+ // This effect is triggered either by BeginFullScreen or by EndFullScreen
+ // depending on if we have an application that is already running or not
+
+ // TAlfControlGroupEntry* alfGroup = NULL;
+ // TODO:
+ //wg1 = (*iHost)->FindWgForAppUid(TUid::Uid(toAppId1));
+ //if (!wg1 && action != AknTransEffect::EApplicationExit )
+ // {
+ // // window group is not available yet, but it will be created in short while.
+ // iEffectWaitingWindowgroup.Append(toAppId1);
+ // }
+ // TODO: when ids available from wserv...
+ // if ( appUid1 )
+ //{
+ // group1 = FindControlGrouAppUId( appUid1, screen1, &alfGroup );
+ // }
+
+ TBool failed = EFalse;
+ if (fxData->iToAppId && fxData->iToAppId != KErrNotFound)
+ {
+ CHuiControlGroup* toGroup = NULL;
+ CHuiLayout* toLayout = NULL;
+ toGroup = FindControlGroupByAppId(fxData->iToAppId);
+
+ CHuiControlGroup* fromGroup = NULL;
+ CHuiLayout* fromLayout = NULL;
+ fromGroup = FindControlGroupByAppId(fxData->iFromAppId);
+
+ if (!toGroup) // group has been destroyed and moved to effectControlGroup for waiting the application exit effect EndFullScreen trigger
+ {
+ toLayout = FindLayoutByEffectHandle(fxData->iHandle);
+ }
+ else
+ {
+ CHuiControl& control = toGroup->Control(0);
+ toLayout = (CHuiLayout*)&control.Visual(0);
+ }
+ if (fromGroup)
+ {
+ CHuiControl& control2 = fromGroup->Control(0);
+ fromLayout = (CHuiLayout*)&control2.Visual(0);
+ }
+
+ if (toLayout)
+ {
+ failed = HandleGfxEventL(*fxData, toLayout, fromLayout);
+ }
+ else
+ {
+ __ALFFXLOGSTRING("HandleGfxEffectsL - waiting window group");
+ fxData->iWaitingWindowGroup = ETrue;
+ }
+ }
+
+ if ( failed )
+ {
+ // Effect failed, reset state
+ HandleGfxStopEvent( EFalse ); // destroys iFullScreenEffectData
+ }
+
+ for (TInt i = 0; i < iAlfScreens.Count(); i++)
+ {
+ iAlfScreens[i]->iDisplay->SetDirty();
+ }
+ iAlfScreens[0]->iVisualTreeVisibilityChanged = ETrue;
+ iHuiEnv->ContinueRefresh();
+
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxEffectsL - END");
+ }
+
+// TODO: add effect type to effect struct. remove all fullscreen effects. currently some might hang around
+void CAlfBridge::HandleGfxStopEffectsL(TAlfBridgerData data)
+ {
+ // Fullscreen effect is aborted. Clear the state.
+
+ //TInt action = data.iInt1;
+ TInt length = data.iInt2;
+ __ALFFXLOGSTRING1("CAlfBridge::HandleGfxStopEffectsL - Reading bridge data %d", (TInt)data.iPtr);
+ void* bridgeBuffer = (void*) (*iHost)->GetEffectsDataL( (TInt)data.iPtr );
+ RMemReadStream stream( bridgeBuffer, length );
+
+ TInt operation = stream.ReadInt32L();
+ TInt handle = stream.ReadInt32L();
+ TInt type = stream.ReadInt32L();
+ TInt wg1 = stream.ReadInt32L();
+ TInt wg2 = stream.ReadInt32L();
+ TInt toAppUi = stream.ReadInt32L();
+ stream.Release();
+
+ // operation tells if this is abort full screen or something else
+ // When this function is used to abort control transitions, all data is 0s
+ if ( iFullScreenEffectData )
+ {
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxStopEffectsL - kill fullscreen");
+ HandleGfxStopEvent( ETrue );
+ }
+
+ if ( !toAppUi )
+ {
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxStopEffectsL - kill all");
+ RemoveAllTemporaryPresenterVisuals();
+ iHuiEnv->ContinueRefresh();
+ }
+ __ALFFXLOGSTRING("CAlfBridge::HandleGfxStopEffectsL - end");
+ }
+
+void CAlfBridge::HandleRegisterEffectL( TAlfBridgerData data )
+ {
+ TInt action = data.iInt1;
+ TInt length = data.iInt2;
+
+ void* bridgeBuffer = (void*) (*iHost)->GetEffectsDataL( (TInt)data.iPtr );
+ RMemReadStream stream( bridgeBuffer, length );
+
+
+ HBufC* effectDirectory = HBufC::NewL( stream, 256 );
+ CleanupStack::PushL( effectDirectory );
+ HBufC* effectFile = HBufC::NewL( stream, 256 );
+ CleanupStack::PushL( effectFile );
+ HBufC* effectFullName = HBufC::NewL( effectDirectory->Des().Length() + effectFile->Des().Length() );
+ CleanupStack::PushL( effectFullName );
+ effectFullName->Des().Copy( *effectDirectory );
+ effectFullName->Des().Append( *effectFile );
+
+ stream.Release();
+ __ALFFXLOGSTRING2("CAlfBridge::HandleRegisterEffectL - dir: %S, file: %S", effectDirectory, effectFile);
+ DoRegisterEffectL(*effectFullName, action);
+
+ if (action == KFadeAction)
+ {
+ DoSetCachedFadeEffectL();
+ }
+
+ CleanupStack::PopAndDestroy(effectFullName);
+ CleanupStack::PopAndDestroy(effectFile);
+ CleanupStack::PopAndDestroy(effectDirectory);
+ }
+
+void CAlfBridge::DoRegisterEffectL(const TDesC& aFilename, TInt aAction)
+ {
+ TRegisteredEffectsStruct newEntry;
+ newEntry.iAction = aAction;
+ newEntry.iEffectFile = HBufC::NewL(aFilename.Length());
+ newEntry.iEffectFile->Des().Append(aFilename);
+ iAlfRegisteredEffects.AppendL(newEntry);
+
+ CHuiFxEngine* engine = NULL;
+ engine = iHuiEnv->EffectsEngine();
+ if (engine)
+ {
+ engine->RegisterEffectL(aFilename);
+ }
+ }
+
+CHuiCanvasVisual* CAlfBridge::AddEffectItemL(
+ TInt aEffectHandle,
+ CHuiVisual* aSourceVisual,
+ CHuiLayout* aTargetLayout,
+ CHuiControl* aEffectControl,
+ TBool aInsertTemporaryVisual,
+ TInt& aItemDestroyed,
+ TBool aIsExitEffect)
+ {
+ CHuiCanvasVisual* temporaryPresenterVisual = NULL;
+ TInt enableEffect = ETrue;
+
+ aSourceVisual->ClearFlags(EHuiVisualFlagShouldBeInactive | EHuiVisualFlagShouldBeUnderOpaqueHint);
+ if (aIsExitEffect)
+ {
+ aSourceVisual->SetFlag(EHuiVisualFlagAlwaysDraw); // forces drawing during exit effect. handlevisualvisibility will set the EShouldbeInactive flag, if visual is determined inactive while this flag is set
+ }
+
+ if (HasActiveEffect(aSourceVisual))
+ {
+ // this visual is having effect and we are closing down the layout this visual inhabits.
+ // Propably this is the case, when application is closed while the options menu is
+ // still having effect animation.
+
+ // removes the effect, and the visual (if EShouldDestroy flag enabled). Removes from effect
+ // cleanup stack iEffectCleanupStack
+ enableEffect = aSourceVisual->Flags() & EHuiVisualFlagShouldDestroy ? 0 : 1;
+ __ALFFXLOGSTRING2("CAlfBridge::SetupEffectLayoutContainerL - visual 0x%x is having effect. EShouldBeDestroyed flag state %d", &aSourceVisual, enableEffect );
+ RemoveTemporaryPresenterVisual(aSourceVisual);
+ if (!enableEffect)
+ {
+ aItemDestroyed++;
+ }
+ }
+ if ( enableEffect )
+ {
+ // RDebug::Print(_L("CAlfBridge::SetupEffectLayoutContainerL - binding visual 0x%x (source)--> 0x%x (presenter) layout 0x%x (presenter layout)"), &sourceVisual, temporaryPresenterVisual, temporaryPresenterLayout);
+ if (aInsertTemporaryVisual)
+ {
+ temporaryPresenterVisual = CHuiCanvasVisual::AddNewL(*aEffectControl, aTargetLayout);
+
+ temporaryPresenterVisual->SetExternalContentL(aSourceVisual);
+ temporaryPresenterVisual->SetSize(THuiRealSize(640, 640));
+ temporaryPresenterVisual->SetPos(aSourceVisual->Pos().Target());
+ aSourceVisual->SetFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ temporaryPresenterVisual->SetChanged();
+ TEffectCleanupStruct item = TEffectCleanupStruct(
+ aEffectHandle,
+ aSourceVisual,
+ temporaryPresenterVisual,
+ ETrue,
+ EFalse);
+ iEffectCleanupStack.AppendL(item);
+ }
+ else
+ {
+ // this will be a child of another visual, and draw by its parent external content visual
+ // aSourceVisual->SetFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ TEffectCleanupStruct item = TEffectCleanupStruct(aEffectHandle,
+ aSourceVisual, NULL, EFalse,
+ EFalse);
+ iEffectCleanupStack.AppendL(item);
+ }
+ }
+ return temporaryPresenterVisual;
+ }
+
+void CAlfBridge::AddToEffectLayoutContainerL(
+ TInt aEffectHandle,
+ CHuiLayout* aSourceLayout,
+ CHuiLayout* aTargetLayout,
+ CHuiControl* aEffectControl,
+ TInt& aItemsDestroyed,
+ TBool aAddLayout,
+ TBool aIsExitEffect)
+ {
+ __ALFFXLOGSTRING2("CAlfBridge::AddToEffectLayoutContainerL 0x%x is having %d children", aSourceLayout, aSourceLayout->Count());
+ if (aAddLayout)
+ {
+ AddEffectItemL(aEffectHandle, aSourceLayout, aTargetLayout, aEffectControl, EFalse, aItemsDestroyed, aIsExitEffect);
+ }
+
+ for (TInt i = 0; i < aSourceLayout->Count(); i++)
+ {
+ CHuiCanvasVisual& sourceVisual = static_cast<CHuiCanvasVisual&> (aSourceLayout->Visual(i));
+
+ if (sourceVisual.Count())
+ {
+ CHuiLayout& layout = static_cast<CHuiLayout&> (aSourceLayout->Visual(i));
+ AddToEffectLayoutContainerL(aEffectHandle, &layout, NULL, aEffectControl, aItemsDestroyed, EFalse,aIsExitEffect );
+ }
+ AddEffectItemL(aEffectHandle, &sourceVisual, aTargetLayout, aEffectControl, EFalse, aItemsDestroyed, aIsExitEffect);
+ }
+ __ALFFXLOGSTRING2("CAlfBridge::AddToEffectLayoutContainerL 0x%x end of children", aSourceLayout, aSourceLayout->Count());
+ }
+
+TBool CAlfBridge::SetupEffectLayoutContainerL(TInt aHandle,CHuiLayout* aSourceLayout, TBool aIsExitEffect)
+ {
+ if (aSourceLayout->Flags() & EHuiVisualFlagDrawOnlyAsExternalContent)
+ {
+ // the requested visual is already having an effect.
+ __ALFFXLOGSTRING("CAlfBridge::SetupEffectLayoutContainerL - WE ARE ALREADY HAVING EFFECT! WHAT TO DO??");
+ // layout is having already effect. this is tricky. This might be place to panic. Resolve later.
+ }
+ // duplicate the layout to effect window group
+ CHuiControl& effectControlGroup = iAlfScreens[0]->iFullscreenEffectControlGroup->Control(0);
+ CHuiLayout& effectControlGroupLayout = (CHuiLayout&) effectControlGroup.Visual(0);
+
+ // CHuiCanvasVisual* temporaryPresenterLayout = CHuiCanvasVisual::AddNewL( effectControlGroup, &effectControlGroupLayout);
+ // create presenter visual and set bindings
+ TInt itemsDestroyed(0);
+ AddToEffectLayoutContainerL(aHandle, aSourceLayout, NULL, &effectControlGroup, itemsDestroyed, EFalse, aIsExitEffect);
+
+ if (aIsExitEffect)
+ {
+ CHuiCanvasVisual* temporaryPresenterVisual = AddEffectItemL(aHandle, aSourceLayout, &effectControlGroupLayout, &effectControlGroup, ETrue, itemsDestroyed, aIsExitEffect);
+ aSourceLayout->SetFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ __ALFFXLOGSTRING3("CAlfBridge::SetupEffectLayoutContainerL - adding handle: %d, 0x%x (source layout)-> 0x%x (presenter layout) to iEffectCleanupStack", aHandle, aSourceLayout, temporaryPresenterVisual);
+ }
+ else
+ {
+ AddEffectItemL(aHandle, aSourceLayout, NULL, &effectControlGroup, ETrue, itemsDestroyed, EFalse);
+ __ALFFXLOGSTRING2("CAlfBridge::SetupEffectLayoutContainerL - adding handle: %d, 0x%x (source layout), NO presenter layout) to iEffectCleanupStack", aHandle, aSourceLayout);
+ }
+ iAlfScreens[0]->iVisualTreeVisibilityChanged = ETrue;
+ iAlfScreens[0]->iDisplay->SetDirty();
+ if (itemsDestroyed)
+ {
+ __ALFFXLOGSTRING3("CAlfBridge::SetupEffectLayoutContainerL - trying to put effect on destroyed visuals. Skipping effect visual: 0x%x, handle %d, %d items destroyed", aSourceLayout, aHandle, itemsDestroyed);
+ }
+ __ALFFXLOGSTRING("CAlfBridge::SetupEffectLayoutContainerL");
+ return ETrue; // TBool(!itemsDestroyed);
+ }
+
+void CAlfBridge::SetupEffectContainerL(TInt aHandle,
+ CHuiCanvasVisual* aSourceVisual, TBool aIsExitEffect)
+ {
+ // if the original visual is having an effect, then remove it.
+ if (HasActiveEffect(aSourceVisual))
+ {
+ RemoveTemporaryPresenterVisual(aSourceVisual);
+ }
+
+ // Create new temporary presenter visual for the effect
+ CHuiControl& effectControlGroup =
+ iAlfScreens[0]->iFullscreenEffectControlGroup->Control(0);
+ CHuiLayout* layout = (CHuiLayout*) &effectControlGroup.Visual(0);
+ CHuiCanvasVisual* temporaryPresenterVisual = NULL;
+ temporaryPresenterVisual = CHuiCanvasVisual::AddNewL(effectControlGroup, layout);
+ // attach the source to the presenter visual
+ temporaryPresenterVisual->SetExternalContentL(aSourceVisual);
+ aSourceVisual->SetFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ temporaryPresenterVisual->ClearFlag(EHuiVisualFlagInactive);
+ aSourceVisual->SetChanged();
+ // append to cleanup stack. this is cleaned in RemoveTemporaryVisuals after effect has finished
+ iEffectCleanupStack.AppendL(TEffectCleanupStruct(aHandle, aSourceVisual, temporaryPresenterVisual, EFalse /*iIsLayout*/, aIsExitEffect));
+ __ALFFXLOGSTRING3("CAlfBridge::SetupEffectContainerL - adding handle: %d, 0x%x (source visual)-> 0x%x (presenter visual)", aHandle, aSourceVisual, temporaryPresenterVisual);
+ }
+
+void CAlfBridge::HandleGfxControlEffectsL( TAlfBridgerData data )
+ {
+ TInt err = KErrNone;
+ TInt action = data.iInt1;
+ TInt length = data.iInt2;
+ __ALFFXLOGSTRING1("HandleGfxControlEffectsL - Reading bridge data %d", (TInt)data.iPtr);
+ void* bridgeBuffer = (void*) (*iHost)->GetEffectsDataL((TInt) data.iPtr);
+ RMemReadStream stream(bridgeBuffer, length);
+ if (iControlEffectData)
+ {
+ delete iControlEffectData;
+ iControlEffectData = NULL;
+ }
+ CControlEffectState* fxData = new (ELeave) CControlEffectState;
+ CleanupStack::PushL(fxData);
+ fxData->ConstructL(action, stream);
+ iControlEffectData = fxData;
+ CleanupStack::Pop(fxData);
+
+ // We now have all the data sent to us.
+ stream.Release();
+
+ // We need to pass the filename from the transeffect plugin that handles the controls
+ // that define which effect is used for the selected skin or the selected application
+ // For full screen effects the skin should determine the effect, or there should be
+ // some default effects.
+
+ CHuiCanvasVisual* visual = FindVisualByClientSideIds(fxData->iClientHandle, fxData->iClientGroupHandle);
+
+ if (visual)
+ {
+ HandleGfxControlEventL(*iControlEffectData, visual);
+ }
+ else
+ {
+ __ALFFXLOGSTRING2("CAlfBridge::HandleGfxControlEffectsL - Control not found. iClientHandle 0x%x, iClientGroupHandle 0x%x",
+ iControlEffectData->iClientHandle,
+ iControlEffectData->iClientGroupHandle);
+ return;
+ }
+ iAlfScreens[0]->iDisplay->SetDirty();
+
+ iHuiEnv->ContinueRefresh();
+
+ if (visual && err != KErrNone)
+ {
+ // if the effect loading failed too soon, we must call our callback ourselves
+ // RDebug::Print(_L("HandleGfxControlEffectsL - effect not set - going directly to callback"));
+ AlfGfxEffectEndCallBack(fxData->iHandle);
+ }
+
+ delete iControlEffectData;
+ iControlEffectData = NULL;
+
+ __ALFFXLOGSTRING("HandleGfxControlEffectsL - end");
+ }
+
+void CAlfBridge::HandleGfxControlEventL(CControlEffectState& aEvent,
+ CHuiCanvasVisual* aCanvasVisual)
+ {
+ TInt err = KErrNone;
+ // Check if there is an effects engine in HuiEnv
+ CHuiFxEffect* effect = NULL;
+ CHuiFxEngine* engine = NULL;
+ // engine is not owned by us, it is a member of HuiEnv
+ engine = iHuiEnv->EffectsEngine();
+ if (NeedsStoredBuffers(engine, *aEvent.iEffectName))
+ {
+ RecursiveStoreRenderBufferL(aCanvasVisual);
+ }
+
+ if (engine)
+ {
+ // clear out old effect if this visual has one
+ __ALFFXLOGSTRING1("HandleGfxControlEffectsL - loading effect %S", &aEvent.iEffectName );
+ __ALFFXLOGSTRING1("HandleGfxControlEffectsL - loading control effect, handle %d", aEvent.iHandle );
+ if (HasActiveEffect(aCanvasVisual))
+ {
+ __ALFFXLOGSTRING1("HandleGfxControlEffectsL - 0x%x has active effect. Requesting removal.", aCanvasVisual);
+ // another effect coming to already effected visual. E.g. close options menu, while opening effect still ongoing
+ RemoveTemporaryPresenterVisual(aCanvasVisual);
+ }
+ TBool layoutEffectable(EFalse);
+ aCanvasVisual->iOpacity.Set(KAlfVisualDefaultOpacity);
+ if (aEvent.iAction == KGfxControlDisappearAction)
+ { // TODO: revise
+ // The control stays visible because the inactive flag is not set
+ // if the window is reserved.
+ /*if (aCanvasVisual->iOpacity.Target() == 0.0f)
+ {
+ // this visual was hidden, before the effect arrived. sounds like trouble.
+ // Lets make it visible again, and ask it to be hidden in the end of the effect
+ // this enables at least the notes disappear effects
+ aCanvasVisual->iOpacity.Set(KAlfVisualDefaultOpacity);
+ // visual->SetFlag(EHuiVisualFlagShouldBeHidden);
+ }*/
+ layoutEffectable = SetupEffectLayoutContainerL(aEvent.iHandle, aCanvasVisual, ETrue);
+ }
+ else
+ {
+ layoutEffectable = SetupEffectLayoutContainerL(aEvent.iHandle, aCanvasVisual, EFalse);
+ }
+ if (layoutEffectable)
+ {
+ TRAP( err, engine->LoadGroupEffectL(*aEvent.iEffectName, effect, aCanvasVisual->Effectable(), engine->ActiveGroupEffect(), NULL, this, aEvent.iHandle ) );
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+ // RDebug::Print(_L("HandleGfxControlEffectsL - loading effect returned %d"), err );
+ // only use the effect if the effect file was correctly parsed
+ if (err == KErrNone)
+ {
+ iLastEffectHandle = aEvent.iHandle;
+
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ visual->SetTracking(ETrue);
+#endif
+ // HuiVisual takes ownership of the effect, but we save the value for reference
+ // add new visual to iFullscreenEffectControlGroup. This enables multiple effects in the group, and their
+ // destruction in any order
+ }
+ else
+ {
+ // visuals added to "active effect visual" stack, but they wont be used, because effect loading has failed. cleanup.
+ RemoveTemporaryPresenterVisual(NULL, aEvent.iHandle);
+ }
+ effect = NULL; // HuiVisual has taken ownership
+ }
+ }
+
+TBool CAlfBridge::RemoveTemporaryPresenterItem(TEffectCleanupStruct& aEffectItem)
+ {
+ CHuiVisual* sourceViz = aEffectItem.iEffectedVisual;
+ CHuiCanvasVisual* sourceViz2 = dynamic_cast<CHuiCanvasVisual*> (aEffectItem.iEffectedVisual);
+ // wserv has already hidden this window. Effect has finished, so lets do what
+ // was asked. Also hide, if this is supposed to be destroyed by now.
+ sourceViz->SetFreezeState(EFalse);
+ sourceViz->SetStoredRenderBuffer(NULL); // free render buffer from visual
+ if (sourceViz2 && sourceViz2->Layout())
+ {
+ sourceViz2->FreeRenderBuffer();
+ }
+ sourceViz->ClearFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ TBool hideVisual = sourceViz->Flags() & EHuiVisualFlagShouldBeHidden;
+ TBool showVisual = sourceViz->Flags() & EHuiVisualFlagShouldBeShown;
+ TBool destroyVisual = sourceViz->Flags() & EHuiVisualFlagShouldDestroy;
+ TBool shouldInactivate = sourceViz->Flags() & EHuiVisualFlagShouldBeInactive;
+ TBool shouldBeUnderOpaqueHint = sourceViz->Flags() & EHuiVisualFlagShouldBeUnderOpaqueHint;
+ __ALFFXLOGSTRING3("CAlfBridge::RemoveTemporaryPresenterItem - cleaning handle: %d, 0x%x -> 0x%x", aEffectItem.iHandle, aEffectItem.iEffectedVisual, aEffectItem.iTemporaryPresenterVisual);
+ __ALFFXLOGSTRING3("CAlfBridge::RemoveTemporaryPresenterItem - hide %d, destroy %d, should inactivate: %d", TBool(hideVisual), TBool(destroyVisual), TBool(shouldInactivate));
+
+ sourceViz->ClearFlag(EHuiVisualFlagAlwaysDraw);
+ if (hideVisual)
+ {
+ // this was exit effect, and window was not really destroyed.
+ sourceViz->iOpacity.Set(0.0f);
+ sourceViz->ClearFlag(EHuiVisualFlagShouldBeHidden); // it is now hidden
+ }
+ else
+ {
+ // visual may be transparent after manipulation of the effect
+ sourceViz->iOpacity.Set(KAlfVisualDefaultOpacity);
+ }
+ if (showVisual)
+ {
+ sourceViz->iOpacity.Set(KAlfVisualDefaultOpacity);
+ sourceViz->ClearFlag(EHuiVisualFlagShouldBeShown); // it is now hidden
+ }
+
+ if (destroyVisual)
+ {
+ sourceViz->iOpacity.Set(0.0f);
+ }
+ if (shouldInactivate)
+ {
+ sourceViz->SetFlag(EHuiVisualFlagInactive);
+
+ if (sourceViz2)
+ {
+ sourceViz2->ClearCache();
+ }
+ sourceViz->ClearFlags(EHuiVisualFlagShouldBeInactive);
+ }
+ if (shouldBeUnderOpaqueHint)
+ {
+ sourceViz->SetFlag(EHuiVisualFlagUnderOpaqueHint);
+ if (sourceViz2)
+ {
+ sourceViz2->ClearCache();
+ }
+ sourceViz->ClearFlags(EHuiVisualFlagShouldBeUnderOpaqueHint);
+ }
+ if (sourceViz->Effect())
+ {
+ sourceViz->SetEffect(NULL);
+ }
+
+ // first delete the temporary presenter visual, because this will unbind the external content
+ if (aEffectItem.iTemporaryPresenterVisual)
+ {
+ CHuiVisual* viz = aEffectItem.iTemporaryPresenterVisual;
+
+ if (viz)
+ {
+ if (viz->Effect())
+ {
+ // temporary presenter visual should not have effect, because the effect is
+ // applied to the original visual. However, if somebody misuses this API, it
+ // is good to cleap up the effect here.
+ viz->SetEffect(NULL);
+ }
+ if (viz->Layout())
+ {
+ viz->Layout()->Remove(viz);
+ }
+ viz->Owner().Remove(viz);
+ delete viz;
+ aEffectItem.iTemporaryPresenterVisual = NULL;
+ }
+ }
+ // although layout does not support EHuiVisualFlagDrawOnlyAsExternalContent flag, it is being used to indicate a layout that has effect. flag must be cleared, that the layout can be drawn normally after the effect.
+ if (aEffectItem.iIsLayout)
+ {
+ aEffectItem.iEffectedVisual->ClearFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ // sourceViz->iOpacity.Set(1.0f);
+ }
+
+ if (destroyVisual)
+ {
+ // window has been destroyed during effect. Kill it once and for all
+ // DeleteControlGroupL and DestroyWindow can do their duty, when this flag is cleared
+ sourceViz->ClearFlags(EHuiVisualFlagShouldDestroy | EHuiVisualFlagDrawOnlyAsExternalContent);
+ if (aEffectItem.iIsLayout)
+ {
+ if (sourceViz->Layout())
+ {
+ sourceViz->Layout()->Remove(sourceViz);
+ }
+ sourceViz->Owner().Remove(sourceViz);
+
+ delete sourceViz;
+ __ALFFXLOGSTRING1("CAlfBridge::RemoveTemporaryPresenterItem - Destroying sourceViz: 0x%x", sourceViz);
+ aEffectItem.iEffectedVisual = NULL;
+ }
+ else
+ {
+ TLex8 lex(sourceViz->Tag());
+ TInt nodeId;
+ lex.Val(nodeId);
+ DestroyWindow(sourceViz, ETrue);
+ }
+ }
+ return TBool(destroyVisual);
+ }
+
+// RemoveTemporaryPresenterVisual removes the temporary presenter visual, and unbinds it from the source.
+TBool CAlfBridge::RemoveTemporaryPresenterVisual(CHuiVisual* aVisual,
+ TInt aHandle)
+ {
+ __ALFFXLOGSTRING2("CAlfBridge::RemoveTemporaryPresenterVisual - cleaning handle: %d, 0x%x", aHandle, aVisual);
+ TInt visualsRemoved = 0;
+ for (TInt i = 0; i < iEffectCleanupStack.Count(); i++)
+ {
+ TEffectCleanupStruct& effectItem = iEffectCleanupStack[i];
+ if (aVisual == effectItem.iEffectedVisual ||
+ aHandle == effectItem.iHandle)
+ {
+ if (RemoveTemporaryPresenterItem(effectItem))
+ {
+ visualsRemoved++;
+ }
+ // must remove from finished effects to keep it in sync
+ for(TInt k = 0; k < iFinishedCleanupStackEffects.Count(); k++)
+ {
+ if (iFinishedCleanupStackEffects[k] == effectItem.iHandle)
+ {
+ iFinishedCleanupStackEffects.Remove(k);
+ k--;
+ }
+ }
+ iEffectCleanupStack.Remove(i);
+ i--;
+ }
+ }
+ return TBool(visualsRemoved);
+ }
+
+CHuiLayout* CAlfBridge::FindTemporaryPresenterLayout(CHuiVisual* aVisual)
+ {
+ for (TInt i = 0; i < iEffectCleanupStack.Count(); i++)
+ {
+ if (aVisual == iEffectCleanupStack[i].iEffectedVisual)
+ {
+ ASSERT(iEffectCleanupStack[i].iIsLayout);
+ return (CHuiLayout*)iEffectCleanupStack[i].iTemporaryPresenterVisual;
+ }
+ }
+ return NULL;
+ }
+
+TBool CAlfBridge::HasActiveEffect(CHuiVisual* aVisual)
+ {
+ for (TInt i = 0; i < iEffectCleanupStack.Count(); i++)
+ {
+ if (aVisual == iEffectCleanupStack[i].iEffectedVisual)
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+TInt CAlfBridge::FindEffectHandle(CHuiVisual* aVisual)
+ {
+ for (TInt i = 0; i < iEffectCleanupStack.Count(); i++)
+ {
+ if (aVisual == iEffectCleanupStack[i].iEffectedVisual)
+ {
+ return iEffectCleanupStack[i].iHandle;
+ }
+ }
+ __ALFFXLOGSTRING1(" CAlfBridge::SetupEffectLayoutContainerL - Could not find handle for 0x%x", aVisual);
+ return KErrNotFound;
+ }
+
+CHuiLayout* CAlfBridge::FindLayoutByEffectHandle(TInt aHandle)
+ {
+ for (TInt i = 0; i < iEffectCleanupStack.Count(); i++)
+ {
+ if (aHandle == iEffectCleanupStack[i].iHandle && iEffectCleanupStack[i].iIsLayout)
+ {
+ return (CHuiLayout*)iEffectCleanupStack[i].iEffectedVisual;
+ }
+ }
+ return NULL;
+ }
+
+
+TBool CAlfBridge::RemoveTemporaryPresenterVisuals()
+ {
+ if (!iFinishedCleanupStackEffects.Count())
+ {
+ return 0;
+ }
+ TInt itemsRemoved(0);
+ CHuiControl& effectControlGroup = iAlfScreens[0]->iFullscreenEffectControlGroup->Control(0);
+ CHuiLayout* effectControlGroupLayout = (CHuiLayout*) &effectControlGroup.Visual(0);
+ __ALFFXLOGSTRING1("CAlfBridge::RemoveTemporaryPresenterVisuals - BEGIN - effects in layout %d", effectControlGroupLayout->Count());
+
+ while (iFinishedCleanupStackEffects.Count())
+ {
+ for (TInt i = 0; i < iEffectCleanupStack.Count() && iFinishedCleanupStackEffects.Count(); i++)
+ {
+ __ALFFXLOGSTRING2("CAlfBridge::RemoveTemporaryPresenterVisuals - looping, finished count: %d, index in active effecs: %d", iFinishedCleanupStackEffects.Count(), i );
+
+ TEffectCleanupStruct& effectItem = iEffectCleanupStack[i];
+ if (iFinishedCleanupStackEffects[0] == effectItem.iHandle)
+ {
+ if (RemoveTemporaryPresenterItem(effectItem))
+ {
+ itemsRemoved++;
+ }
+ iEffectCleanupStack.Remove(i);
+ iFinishedCleanupStackEffects.Remove(0);
+ i--;
+ }
+ }
+ }
+ iAlfScreens[0]->iVisualTreeVisibilityChanged = ETrue; // TODO: Check if really changed
+ iAlfScreens[0]->iDisplay->SetDirty();
+ __ALFFXLOGSTRING1("CAlfBridge::RemoveTemporaryPresenterVisuals - END - effects in layout %d", effectControlGroupLayout->Count());
+ return itemsRemoved;
+ }
+
+void CAlfBridge::RemoveAllTemporaryPresenterVisuals()
+ {
+ CHuiControl& effectControlGroup = iAlfScreens[0]->iFullscreenEffectControlGroup->Control(0);
+ CHuiLayout* effectControlGroupLayout = (CHuiLayout*) &effectControlGroup.Visual(0);
+ __ALFFXLOGSTRING1("CAlfBridge::RemoveAllTemporaryPresenterVisuals - BEGIN - effects in layout %d", effectControlGroupLayout->Count());
+
+ while(iEffectCleanupStack.Count())
+ {
+ TEffectCleanupStruct& effectItem = iEffectCleanupStack[0];
+ RemoveTemporaryPresenterItem(effectItem);
+ iEffectCleanupStack.Remove(0);
+ }
+
+ while(iFinishedCleanupStackEffects.Count())
+ {
+ iFinishedCleanupStackEffects.Remove(0);
+ }
+ }
+
+void CAlfBridge::AlfGfxEffectEndCallBack(TInt aHandle)
+ {
+ // We need a delay to prevent the refresh from being messed up
+ // We try a short delay before clearing everything up.
+ __ALFFXLOGSTRING1("AlfGfxEffectEndCallBack, append handle %d", aHandle );
+ // RDebug::Print(_L("AlfGfxEffectEndCallBack, append handle %d"), aHandle );
+ // If the handle cannot be appended, the function returns an error.
+ // However, if the memory is low, there is nothing we can do about it.
+ // We try to handle the transition finish anyway.
+ // If there are already other handles in the queue, the handler will not
+ // be called for this handle, but all handles that have been left hanging
+ // around will be cleared when HandleGfxStopEffectsL is called
+
+
+ iFinishedEffects.Append(aHandle);
+
+ // iFinishedCleanupStackEffects.Append(aHandle);
+ if (!iEffectEndTimer->IsActive())
+ {
+ iEffectEndTimer->Start( 10000, aHandle );
+ }
+
+ // We should do visual visibility scan after effect is ended
+ iAlfScreens[0]->SetVisualTreeVisibilityChanged(ETrue);
+ }
+
+void CAlfBridge::TransitionFinishedHandlerL(TInt aHandle)
+ {
+ for (TInt i=0;i<iEffectCleanupStack.Count();i++)
+ {
+ if(aHandle==iEffectCleanupStack[i].iHandle)
+ {
+ // effect might have been cleaned even without this callback. e.g. closing of applicaion while option menu disappear
+ // effect is running, would cause it. There is no need to request cleaning again.
+ iFinishedCleanupStackEffects.Append(aHandle);
+ }
+ }
+ // If the finish request comes from the plugin, the plugin is not interested
+ // in getting a notification of the transition end.
+ __ALFFXLOGSTRING1("Gfx transition finished, handle %d", aHandle );
+ if ( aHandle == KErrNotFound )
+ {
+ __ALFFXLOGSTRING("invalid handle");
+ }
+ // alftranstion plugin may cancel end timers connected to this effect
+ TBool fsEffectDone = iFullScreenEffectData && aHandle == iFullScreenEffectData->iHandle;
+ if ( fsEffectDone )
+ {
+ aHandle = iFullScreenEffectData->iCompletionHandle;
+ }
+ RProperty::Set( KPSAlfDomain, KAlfTransitionStatus, aHandle );
+
+ // Effect finished
+ if ( fsEffectDone )
+ {
+ delete iFullScreenEffectData;
+ iFullScreenEffectData = NULL;
+ }
+ }
+
+
+void CAlfBridge::PrintAllocMem()
+ {
+#ifdef _ALF_LOGGING
+ TInt allocCells = 0;
+ TInt allocSpace = 0;
+ TInt freeSpace = 0;
+ TInt largestFreeBlock = 0;
+ allocCells = User::AllocSize( allocSpace );
+ freeSpace = User::Available( largestFreeBlock );
+ __ALFLOGSTRING2("CAlfBridge::PrintAllocMem - alloc cells %d, alloc space %d", allocCells, allocSpace );
+ __ALFLOGSTRING2("CAlfBridge::PrintAllocMem - free space %d, largest free block %d", freeSpace, largestFreeBlock );
+#endif
+ }
+
+// ---------------------------------------------------------------------------
+// DebugPrintControlGroupOrder
+//
+// Note, that HUI_DEBUG_TRACK_DRAWING must be enabled if you want to see the
+// real process names
+// ---------------------------------------------------------------------------
+//
+
+#ifdef ALF_DEBUG_PRINT_WINDOWGROUP_ORDER
+void CAlfBridge::DebugPrintControlGroupOrder(CAlfScreen& aScreen, CHuiRoster& aRoster, CHuiControlGroup& aGroup)
+ {
+ __ALFLOGSTRING(">> ---AFTER-----");
+ for (TInt i=0; i<aRoster.Count();i++)
+ {
+ CHuiControlGroup& indexedGroup = aRoster.ControlGroup(i);
+
+ if (&indexedGroup == &aGroup)
+ {
+ __ALFLOGSTRING("<<");
+ }
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ TInt clientWindowGroupId = FindClientWindowGroupId( aScreen.iScreenNum, indexedGroup );
+
+ TFileName processName = iCommandDebug->WServClientFileName( clientWindowGroupId, CHuiStatic::WsSession() );
+#endif
+ if (indexedGroup.Control(0).Role() == EAlfWindowGroupContainer)
+ {
+ if (aRoster.ControlGroup(i).ResourceId() == iAlfWindowGroupNodeId)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ __ALFLOGSTRING2(">> %d WINDOW GROUP (ALF), %d", i, clientWindowGroupId);
+#endif
+ }
+ else
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ __ALFLOGSTRING3(">> %d WINDOW GROUP %S, %d", i, &processName, clientWindowGroupId);
+#else
+ __ALFLOGSTRING1(">> %d WINDOW GROUP", i);
+#endif
+ }
+ }
+ else if (indexedGroup.Control(0).Role() == EAlfSessionContainer)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ __ALFLOGSTRING2(">> %d ALF GROUP, %d", i, clientWindowGroupId);
+#endif
+ }
+ else if (indexedGroup.Control(0).Role() == EAlfWindowFloatingSpriteContainer)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ __ALFLOGSTRING3(">> %d FLOATING SPRITE GROUP %S, %d", i, &processName, clientWindowGroupId);
+#else
+ __ALFLOGSTRING1(">> %d FLOATING SPRITE GROUP", i);
+#endif
+ }
+ else if (indexedGroup.Control(0).Role() == EAlfFullScreenEffectContainer)
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ __ALFLOGSTRING3(">> %d EFFECT GROUP %S, %d", i, &processName, clientWindowGroupId );
+#else
+ __ALFLOGSTRING1(">> %d EFFECT GROUP", i);
+#endif
+ }
+ else
+ {
+#ifdef HUI_DEBUG_TRACK_DRAWING
+ __ALFLOGSTRING3(">> %d UNKNOWN GROUP ?!!? %S, %d", i, &processName, clientWindowGroupId );
+#endif
+ }
+
+ if (&indexedGroup == &aGroup)
+ {
+ __ALFLOGSTRING("<<");
+ }
+ }
+
+ // Print the group that has keyboard focus
+ TInt focusWindowGroupId = CHuiStatic::WsSession().GetFocusWindowGroup();
+ TFileName processName;
+ TThreadId threadId;
+ TInt error = CHuiStatic::WsSession().GetWindowGroupClientThreadId( focusWindowGroupId, threadId );
+ RThread thread;
+ TInt err = thread.Open( threadId );
+ if( !err )
+ {
+ RProcess process;
+ err = thread.Process( process );
+ if( !err )
+ {
+ processName = process.FileName();
+ __ALFLOGSTRING2( ">> Keyboard focus group: %S, %d", &processName, focusWindowGroupId );
+ }
+ process.Close();
+ thread.Close();
+ }
+ __ALFLOGSTRING(">> ---------------");
+ }
+#else
+void CAlfBridge::DebugPrintControlGroupOrder(CAlfScreen& /*aScreen*/, CHuiRoster& /*aRoster*/, CHuiControlGroup& /*aGroup*/)
+ {
+ }
+#endif
+
+#ifdef ALF_DEBUG_VISUALIZE_WINDOWGROUP_ORDER
+void CAlfBridge::VisualizeControlGroupOrderL(CHuiRoster& aRoster, CHuiControlGroup& /*aGroup*/)
+ {
+ TInt nbrofcolums = 3;
+ TInt nbrofrows = 3;
+ TInt gridIndex = 0;
+ TBool skipEmpty = EFalse;
+ if (aRoster.Count() > 3)
+ {
+ for (TInt i=aRoster.Count() - 3; i>0; i--)
+ {
+ CHuiControl& control = aRoster.ControlGroup(i).Control(0);
+ if (skipEmpty)
+ {
+ TBool empty = ETrue;
+ CHuiLayout* layout = (CHuiLayout*)&control.Visual(0);
+ for (TInt j=layout->Count()-1; j >= 0; j--)
+ {
+ CHuiCanvasVisual* canvasVisual = (CHuiCanvasVisual*) &layout->Visual(j);
+ if (canvasVisual && canvasVisual->DisplayRect().Size().Round() != TSize(0,0) && canvasVisual->PaintedAreaCount())
+ {
+ empty = EFalse;
+ break;
+ }
+ }
+
+ if (empty && skipEmpty)
+ {
+ continue;
+ }
+ }
+
+ TSize screensize = HuiUtil::ScreenSize();
+ CHuiTransformation::TTransform& step = aRoster.ControlGroup(i).Transformation().Step(0);
+ step.iParams[EHuiTransformParamTranslateX].Set((gridIndex % nbrofcolums) * (screensize.iWidth/nbrofcolums), 500);
+ step.iParams[EHuiTransformParamTranslateY].Set((gridIndex / nbrofrows) * (screensize.iHeight/nbrofrows), 500);
+ gridIndex++;
+ }
+ }
+ iAlfScreens[0]->iDisplay->SetClearBackgroundL(CHuiDisplay::EClearWithSkinBackground);
+ }
+#else
+void CAlfBridge::VisualizeControlGroupOrderL(CHuiRoster& /*aRoster*/, CHuiControlGroup& /*aGroup*/)
+ {
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+// PostQTCommandBufferL
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::PostQTCommandBufferL( TAlfQtCommandBufferParams params )
+ {
+ CHuiCanvasVisual* huiVisual = NULL;
+ if ((*iHost))
+ {
+ if( (*iHost)->StreamerServer() )
+ {
+ if ((*iHost)->StreamerServer()->WindowMgr())
+ {
+ RArray<TAlfWServInfo> winInfoList;
+
+ (*iHost)->StreamerServer()->WindowMgr()->GetWinInfoListL( params.iWsWgId,
+ params.iWsClientId, winInfoList );
+
+ for ( TInt i= 0; i<winInfoList.Count(); i++ )
+ {
+ if( winInfoList[i].iClientSideId.iWindowIdentifer == params.iWsClientId )
+ {
+ huiVisual = FindVisual( winInfoList[i].iRefId.iWindowIdentifer );
+ break;
+ }
+ }
+ winInfoList.Close();
+ }
+ }
+ }
+
+ if ( huiVisual )
+ {
+ TPtrC8 commands( (TUint8 *)params.iPtr, params.iLength );
+ TAlfCommandBufferStatus bufferStatus = params.iBufferStatus;
+ huiVisual->SetCommandType( 1 ); // set to ECommandBufferWs should it be some QT specific?
+ if ( bufferStatus == EComplete )
+ {
+ huiVisual->ClearCommandSet();
+ huiVisual->AddCommandSetL(commands);
+ }
+ else if ( bufferStatus == EPartial )
+ {
+ huiVisual->AddPartialCommandSetL( commands, EFalse );
+ }
+ else if ( bufferStatus == ELastPart )
+ {
+ huiVisual->AddPartialCommandSetL( commands, ETrue );
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// SetClientWindowForDrawingL
+//
+// Note: One external content visual can exist in one canvas visual at the
+// time. When external content visual is deleted, in destructor, it removes
+// pointers to it from all canvas visuals. So canvasVisual->ExternalContent()
+// always returns a valid pointer, or NULL. The parameter aRootVisual can
+// be NULL, which means that the external content is removed from the canvas
+// visual
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::SetClientWindowForDrawingL(TInt aWindowGroupId, TInt aClientWindowHandle,
+ CHuiVisual* aExternalContentVisual)
+ {
+ RArray<TAlfWServInfo> winInfoList;
+ CleanupClosePushL(winInfoList);
+
+ // Find canvas visual for the RWindow
+
+ (*iHost)->StreamerServer()->WindowMgr()->GetWinInfoListL(aWindowGroupId, aClientWindowHandle, winInfoList );
+ if(winInfoList.Count() != 1)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ CHuiCanvasVisual* canvasVisual = (CHuiCanvasVisual*)FindVisual(winInfoList[0].iRefId.iWindowIdentifer);
+ if (!canvasVisual)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Current external content
+ CHuiVisual* currentContent = canvasVisual->ExternalContent();
+
+ if (!aExternalContentVisual)
+ {
+ // Do not draw external content any more.
+
+ // Disable external content for the canvas visual
+ canvasVisual->SetExternalContentL(NULL);
+ // For the current content, enable drawing it in the original visual tree.
+ if (currentContent)
+ {
+ currentContent->ClearFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ }
+ }
+ else if (!(aExternalContentVisual->Flags() & EHuiVisualFlagDrawOnlyAsExternalContent))
+ {
+ // The visual is not yet used by other canvas visual
+
+ // Enable external content for the canvas visual
+ canvasVisual->SetExternalContentL(aExternalContentVisual);
+ // For the current content, enable drawing it in the original visual tree.
+ if (currentContent)
+ {
+ currentContent->ClearFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ }
+ // Disable normal drawing and start using as external content
+ aExternalContentVisual->SetFlag(EHuiVisualFlagDrawOnlyAsExternalContent);
+ }
+ else
+ {
+ // aExternalContentVisual is already used as an external content for some visual
+ User::Leave(KErrAlreadyExists);
+ }
+
+ CleanupStack::PopAndDestroy(); // winInfoList
+ }
+
+void CAlfBridge::SetVisualTreeVisibilityChanged(TBool aChanged)
+ {
+ for (TInt i=0; i<iAlfScreens.Count();i++)
+ {
+ iAlfScreens[i]->iVisualTreeVisibilityChanged = aChanged;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::EnableSwRenderingL(TBool aEnable)
+ {
+ if (aEnable == iSwRenderingEnabled)
+ {
+ return;
+ }
+
+ iSwRenderingEnabled = aEnable;
+ for (TInt i=0; i<iAlfScreens.Count();i++)
+ {
+ PrepareSwRenderingTarget(iAlfScreens[i]);
+
+ if (iSwRenderingEnabled)
+ {
+ CHuiTexture* texture = CHuiTexture::NewL();
+ CleanupStack::PushL(texture);
+ iAlfScreens[i]->iDisplay->SetForegroundBitmapL( iAlfScreens[i]->iSwRenderingTarget );
+ CleanupStack::Pop(texture);
+ iAlfScreens[i]->iDisplay->SetForegroundTexture(texture);
+ iAlfScreens[i]->iDisplay->iRosterObservers.AppendL(*this);
+ }
+ else
+ {
+ iAlfScreens[i]->iDisplay->SetForegroundBitmapL(NULL);
+ iAlfScreens[i]->iDisplay->SetForegroundTexture(NULL);
+ iAlfScreens[i]->iDisplay->iRosterObservers.Remove(*this);
+ }
+
+ // SetCapturingBufferL is called from HandleVisualVisibility.
+ iAlfScreens[i]->SetVisualTreeVisibilityChanged(ETrue);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::UploadSwRenderingTargetL(CAlfScreen* aScreen)
+ {
+ if (iSwRenderingEnabled)
+ {
+ CHuiTexture* texture = aScreen->iDisplay->ForegroundTexture();
+ if (texture && aScreen->iSwRenderingTarget)
+ {
+ texture->UploadL(*aScreen->iSwRenderingTarget, NULL);
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TBool CAlfBridge::PrepareSwRenderingTarget( CAlfScreen* aScreen )
+ {
+ TBool modified = EFalse;
+
+ // Check ultra low memory mode here
+ if (iHuiEnv->MemoryLevel() <= EHuiMemoryLevelLowest)
+ {
+ if (!aScreen->iSwRenderingTarget)
+ {
+ // screen owns this bitmap
+ aScreen->iSwRenderingTarget = new CFbsBitmap;
+ if (aScreen->iSwRenderingTarget)
+ {
+ aScreen->iSwRenderingTarget->Create(aScreen->Size(), EColor16MA);
+ modified = ETrue;
+ }
+ }
+
+ if (aScreen->iSwRenderingTarget)
+ {
+ if (aScreen->iSwRenderingTarget->SizeInPixels() != aScreen->Size())
+ {
+ aScreen->iSwRenderingTarget->Resize(aScreen->Size());
+ modified = ETrue;
+ }
+ // For tests
+ //TUint32* data = aScreen->iSwRenderingTarget->DataAddress();
+ }
+ }
+ else
+ {
+ delete aScreen->iSwRenderingTarget;
+ aScreen->iSwRenderingTarget = NULL;
+ modified = ETrue;
+ }
+
+ return modified;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::SetMemoryLevel(THuiMemoryLevel aMemoryLevel)
+ {
+ iCurrentMemoryLevel = aMemoryLevel;
+ DoUpdateMemoryLevel();
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::SetLowMemory(TBool aEnabled)
+ {
+ iLowMemoryMode = aEnabled;
+ DoUpdateMemoryLevel();
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+TInt CAlfBridge::ForceSwRendering(TBool aEnabled)
+ {
+ iForcedSwRendering = aEnabled;
+ DoUpdateMemoryLevel();
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// This decides memory level for core toolkit. This should the only place
+// where core toolkit memory level is modified.
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::DoUpdateMemoryLevel()
+ {
+ THuiMemoryLevel memoryLevel = iCurrentMemoryLevel;
+ if ( iLowMemoryMode && ( memoryLevel > EHuiMemoryLevelLow ) )
+ {
+ memoryLevel = EHuiMemoryLevelLow;
+ }
+ if ( iForcedSwRendering && ( memoryLevel > EHuiMemoryLevelLowest ) )
+ {
+ // For now, we use memory level to force SW rendering
+ // to be used.
+ memoryLevel = EHuiMemoryLevelLowest;
+ }
+
+ if ( memoryLevel != iHuiEnv->MemoryLevel() )
+ {
+ __ALFLOGSTRING1("CAlfBridge::DoUpdateMemoryLevel -> %d", memoryLevel);
+ if ( memoryLevel <= EHuiMemoryLevelLowest)
+ {
+ LowMemoryCancelAllEffects();
+ }
+
+ iHuiEnv->NotifyMemoryLevel(memoryLevel);
+ if (memoryLevel <= EHuiMemoryLevelLowest)
+ {
+ TRAP_IGNORE(EnableSwRenderingL(ETrue));
+ }
+ else
+ {
+ TRAP_IGNORE(EnableSwRenderingL(EFalse));
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::LowMemoryCancelAllEffects()
+ {
+ __ALFLOGSTRING("CAlfBridge::LowMemoryCancelAllEffects");
+ iLayoutSwitchEffectCoordinator->Cancel();
+ HandleGfxStopEvent( EFalse );
+ __ALFLOGSTRING("CAlfBridge::LowMemoryCancelAllEffects done");
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::NotifyRosterDrawStart(CHuiDisplay& /*aDisplay*/)
+ {
+ // Do nothing
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CAlfBridge::NotifyRosterDrawEnd(CHuiDisplay& aDisplay)
+ {
+ TInt screenNumber = ResolveScreenNumber(aDisplay);
+ TRAP_IGNORE(UploadSwRenderingTargetL(iAlfScreens[screenNumber]));
+ }
+
+// end of file