uiacceltk/hitchcock/ServerCore/Src/alfeffectutils.cpp
branchRCL_3
changeset 7 433cbbb6a04b
child 8 10534483575f
child 14 83d2d132aa58
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/ServerCore/Src/alfeffectutils.cpp	Fri Mar 12 15:47:04 2010 +0200
@@ -0,0 +1,505 @@
+/*
+* 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:   AlfEffectUtils contains small classes that enable layout switch and transition effects.
+*
+*/
+#include <e32cmn.h>
+#include <s32mem.h>
+#include "alfeffectutils.h"
+#include <akntransitionutils.h>
+
+
+const TInt KRosterFreezeEndTimeoutInMs = 400;
+const TInt KFirstTimeoutForApplicationEndFullScreenInMs = 50;
+
+// ---------------------------------------------------------
+// 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::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);    
+    }
+
+// ---------------------------------------------------------
+// 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();
+    }
+
+
+CEffectState::CEffectState()
+    {
+    // CBase clears all variables
+    }
+
+CEffectState::~CEffectState()
+    {
+    delete iEffectName;
+    }
+
+void 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);
+    }
+
+
+CFullScreenEffectState::~CFullScreenEffectState()
+    {
+    iPaintedRegion.Close();
+    if (iDrawingCompleteTimer)
+        {
+        iDrawingCompleteTimer->Cancel();
+        delete iDrawingCompleteTimer;
+        iDrawingCompleteTimer = NULL;
+        }
+    }
+
+
+void 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;
+    }
+
+TInt doNotifyDrawingTimeout( TAny* aPtr )
+    {
+    ((CFullScreenEffectState*)aPtr)->NotifyDrawingTimeout();
+    return 0; // must return something
+    }
+
+TBool CFullScreenEffectState::ResetTimerL(CAlfBridge* aBridge)
+    {
+    iBridge = aBridge;
+    if (!iDrawingCompleteTimer)
+        {
+        iDrawingCompleteTimer = CPeriodic::NewL( EPriorityNormal );
+        iDrawingCompleteTimer->Start( 
+                KFirstTimeoutForApplicationEndFullScreenInMs * 1000 , 
+                KFirstTimeoutForApplicationEndFullScreenInMs * 1000 , TCallBack( doNotifyDrawingTimeout, this ));
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+void CFullScreenEffectState::NotifyDrawingTimeout()
+    {
+    TRect b = iPaintedRegion.BoundingRect();
+    if ( (b.Width() * b.Height()) > 0.75 * (iDisplaySize.iWidth * iDisplaySize.iHeight))
+        {
+        iBridge->HandleGfxEndFullScreenTimeout(this);
+        delete iDrawingCompleteTimer;
+        iDrawingCompleteTimer = NULL;
+        }
+    }
+
+void 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);
+    }
+