src/screensaverctrlplugin.cpp
changeset 0 040fcad49f44
child 1 35d9bdabf175
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/screensaverctrlplugin.cpp	Thu Dec 17 08:46:04 2009 +0200
@@ -0,0 +1,638 @@
+/*
+* Copyright (c) 2009 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:   Implementation of screensaver plugin display object class.
+*
+*/
+
+
+
+#include <AknDef.h>
+#include <power_save_display_mode.h>
+
+#include "ScreensaverpluginIntDef.h"
+#include "screensaverctrlplugin.h"
+#include "screensaverview.h"
+#include "screensaverappui.h"
+#include "screensaverutility.h"
+#include "ScreensaverUtils.h"
+#include "screensavershareddatai.h"
+
+// If plugin refresh rate is lower than this threshold, wserv heartbeat
+// is stopped between redraws
+const TInt KStopWsHbPluginRefreshThreshold = 1000000; // 1 sec
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::NewL
+// -----------------------------------------------------------------------------
+//
+CScreensaverCtrlPlugin* CScreensaverCtrlPlugin::NewL()
+    {
+    CScreensaverCtrlPlugin* self = new( ELeave ) CScreensaverCtrlPlugin();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::~CScreensaverCtrlPlugin
+// -----------------------------------------------------------------------------
+//
+CScreensaverCtrlPlugin::~CScreensaverCtrlPlugin()
+    {
+    DeleteTimer( iPluginRefreshTimer );
+    DeleteTimer( iPluginTimeoutTimer );
+    DeletePlugin();
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::StartTimer
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::StartTimer()
+    {
+    // Notify plugin that screensaver is starting
+    SendPluginEvent( EScreensaverEventStarting );
+    
+    
+    StartPluginRefreshTimer();
+
+    if ( RefreshTimerValue() >= KStopWsHbPluginRefreshThreshold )
+        {
+        StartCaptureScreenTimer();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::CancelTimer
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::CancelTimer()
+    {
+    DeleteTimer( iPluginRefreshTimer );
+    DeleteTimer( iPluginTimeoutTimer );
+    
+    SendPluginEvent( EScreensaverEventStopping );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::DrawObject
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::DrawObject()
+    {
+    CScreensaverBase::DrawObject();
+
+    if( iPluginFlag.IsSet( EPluginFlagSuspend ) )
+    	{
+    	Suspend( -1 );
+    	iPluginFlag.Clear( EPluginFlagSuspend );
+    	}
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::ClearScreen
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::ClearScreen()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::Refresh
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::Refresh()
+    {
+    SCRLOGGER_WRITEF( _L("SCR:CScreensaverCtrlPlugin::Refresh start") );
+    // Currently only keylock indicator is updated, because
+    // thats the only indicator whose state may change while screensaver
+    // is displaying. Other indicators' state changing also dismisses
+    // screensaver. Once redisplaying, the indicators are updated anyway.
+    // Key lock indicator depends on status of key guard.
+    Array().SetDependencyStatus( ESsKeyLockInd, !Model().SharedDataInterface()->IsKeyguardOn() );
+    Array().SetVisibilityForIndicators();
+
+    SCRLOGGER_WRITEF( _L("SCR:CScreensaverCtrlPlugin::Refresh DrawObject") );
+    // Cause a redraw
+    DrawObject();
+
+    SCRLOGGER_WRITEF( _L("SCR:CScreensaverCtrlPlugin::Refresh finish") );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::SendPluginEvent
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::SendPluginEvent( TScreensaverEvent aEvent )
+    {
+    if ( iPlugin )
+        {
+        TRAPD( err, iPlugin->HandleScreensaverEventL( aEvent, NULL ) );
+        return err;
+        }
+
+    return KErrNone;
+    }
+
+// From MScreensaverPluginHost
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::UseStandardIndicators
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::UseStandardIndicators()
+    {
+    SCRLOGGER_WRITE("Host: UseStandardIndicators()");
+
+    iPluginFlag.Clear( EPluginFlagOverrideIndicators );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::OverrideStandardIndicators
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::OverrideStandardIndicators()
+    {
+    SCRLOGGER_WRITE("Host: OverrideStandardIndicators()");
+
+    iPluginFlag.Set( EPluginFlagOverrideIndicators );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::StandardIndicatorsUsed
+// -----------------------------------------------------------------------------
+//
+TBool CScreensaverCtrlPlugin::StandardIndicatorsUsed() const
+    {
+    SCRLOGGER_WRITE("Host: StandardIndicatorsUsed()");
+
+    return iPluginFlag.IsClear( EPluginFlagOverrideIndicators );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::SetRefreshTimerValue
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::SetRefreshTimerValue( TInt aValue )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: SetRefreshTimerValue(%d)"), aValue );
+
+    iPluginRefreshRate = aValue;
+    iPluginFlag.Clear( EPluginFlagTimerNotUsed );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::RefreshTimerValue
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::RefreshTimerValue() const
+    {
+    SCRLOGGER_WRITE("Host: RefreshTimerValue()");
+
+    return iPluginRefreshRate;
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::GetIndicatorPayload
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::GetIndicatorPayload( 
+    TScreensaverIndicatorIndex aIndex, TIndicatorPayload& aResult ) const
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: GetIndicatorPayload(%d, %x)"),
+        aIndex, &aResult );
+
+    return Model().IndicatorArray().GetIndicatorPayload( ( TScreensaverIndicatorId ) aIndex, aResult );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::SetActiveDisplayArea
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::SetActiveDisplayArea( 
+    TRect& aRect, const TScreensaverPartialMode& aMode )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: SetActiveDisplayArea(<rect>, %d)"), aMode );
+    SCRLOGGER_WRITEF( _L("    -> rect: (%d, %d, %d, %d)"),
+        aRect.iTl.iX, aRect.iTl.iY, aRect.iBr.iX, aRect.iBr.iY );
+    // Make sure everything is in display memory
+    ScreensaverUtility::FlushDrawBuffer();
+
+    // Save the active area
+    TInt err = SetPowerSaveDisplayActiveArea( aRect );
+    if ( err == KErrNone )
+        {
+        // And activate power save display. Full mode = full colors
+//        err = ActivatePowerSaveDisplay( aMode.iType
+//            == EPartialModeTypeFull );
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::SetActiveDisplayArea
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::SetActiveDisplayArea( 
+    TInt aStartRow, TInt aEndRow, const TScreensaverPartialMode& aMode )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: SetActiveDisplayArea(%d, %d, %d)"),
+        aStartRow, aEndRow, aMode );
+    
+    TRect psRect( 0, aStartRow, 1, aEndRow);
+    return SetActiveDisplayArea( psRect, aMode );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::ExitPartialMode
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::ExitPartialMode()
+    {
+    SCRLOGGER_WRITE("Host: ExitPartialMode()");
+
+    LcdPartialMode()->Exit();
+    // Make sure the partial area is empty
+    // Make this less idiotic
+    TRect psRect( 0, 0, 0, 0);
+    SetPowerSaveDisplayActiveArea( psRect );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::GetColorModel
+// -----------------------------------------------------------------------------
+//
+const TScreensaverColorModel& CScreensaverCtrlPlugin::GetColorModel() const
+    {
+    SCRLOGGER_WRITE("Host / Own use: GetColorModel()");
+
+    return Model().GetColorModel();
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::Suspend
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::Suspend( TInt aTime )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: Suspend(%d)"), aTime );
+
+    View()->SetDisplayObject( Model().SharedDataInterface()->DefaultScreensaverType() );
+
+    View()->ShowDisplayObject();
+    
+    if ( aTime >= 0 )
+        {
+        CScreensaverEngine& model = MUTABLE_CAST( CScreensaverEngine&, Model() );
+        
+        model.StartSuspendTimer( aTime );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::RequestLights
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::RequestLights( TInt aSecs )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: RequestLights(%d)"), aSecs );
+
+    if ( aSecs <= 0 )
+        {
+        // Turn lights off, kill lights timer
+        Model().SharedDataInterface()->SetSSForcedLightsOn( 0 );
+        }
+    else
+        {
+        // Make sure nobody tries to overextend our hospitality
+        TInt secs = (aSecs > KMaxLightsOnTime) ? KMaxLightsOnTime : aSecs;
+
+        // Turn lights on, start lights timer
+        Model().SharedDataInterface()->SetSSForcedLightsOn( secs );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::DisplayInfo
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::DisplayInfo( TScreensaverDisplayInfo* aInfo )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: DisplayInfo(%x)"), aInfo );
+
+    if ( !aInfo )
+        {
+        return KErrArgument;
+        }
+    // Sanity check: the indicated size of the info struct should be
+    // same or less than the actual size (allows for extensibility)
+    if ( aInfo->iSize > sizeof( TScreensaverDisplayInfo ) )
+        {
+        ASSERT( EFalse );
+        return KErrArgument;
+        }
+
+    // Fill our own perception of the info structure
+    TScreensaverDisplayInfo info;
+
+    info.iSize = aInfo->iSize;
+
+    // Currently whole screen
+    info.iRect = CCoeEnv::Static()->ScreenDevice()->SizeInPixels();
+    info.iParent = this;
+
+    // Copy only the size of the caller struct
+    Mem::Copy( aInfo, &info, aInfo->iSize );
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::UseRefreshTimer
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::UseRefreshTimer( TBool aOn )
+    {
+    SCRLOGGER_WRITEF( _L("SCR: Host: UseRefreshTimer(%d)"), aOn );
+
+    if ( aOn )
+        {
+        // Use normal timer, plugin timer allowed
+        iPluginFlag.Clear( EPluginFlagTimerNotUsed );
+        }
+    else
+        {
+        // Plugin does not want Draw() calls, let timer tick the usual way
+        iPluginFlag.Set( EPluginFlagTimerNotUsed );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::RequestTimeout
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::RequestTimeout( TInt aSecs )
+    {
+    StartPluginTimeoutTimer( aSecs );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::RevertToDefaultSaver
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::RevertToDefaultSaver()
+    {
+    SCRLOGGER_WRITE("Host: RevertToDefaultSaver()");
+
+    Model().SharedDataInterface()->SetDisplayObjectType( 
+        Model().SharedDataInterface()->DefaultScreensaverType() );
+    }
+
+// --- end MScreensaverPluginHost ---
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::CScreensaverCtrlPlugin
+// -----------------------------------------------------------------------------
+//
+CScreensaverCtrlPlugin::CScreensaverCtrlPlugin()
+    :iPluginFlag()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::ConstructL()
+    {
+    iPluginFlag.ClearAll();
+
+    
+    CreateWindowL();
+    
+    SetRect( iCoeEnv->ScreenDevice()->SizeInPixels() );
+    ConstructAndConnectLCDL();
+    LoadPluginL( this );
+    ActivateL();
+    
+    // Notify plugin that display control has changed
+    SendPluginEvent( EScreensaverEventDisplayChanged );
+    
+    if( Model().ScreenSaverIsPreviewing() )
+        {
+        SendPluginEvent( EScreensaverEventPreview );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::HandleResourceChange
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::HandleResourceChange( TInt aType )
+    {
+    if ( aType == KEikDynamicLayoutVariantSwitch )
+        {
+        // Screen layout has changed - resize
+        SetRect( iCoeEnv->ScreenDevice()->SizeInPixels() );
+        // Notify plugin that the display has changed
+        SendPluginEvent( EScreensaverEventDisplayChanged );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::SizeChanged
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::SizeChanged()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::Draw
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::Draw( const TRect& /*aRect*/ ) const
+    {
+    
+    if ( !Model().ScreenSaverIsOn() && !Model().ScreenSaverIsPreviewing() )
+        {
+        return;
+        }
+
+    // Graphics context to draw on.
+    CWindowGc& gc = SystemGc();
+    
+    // Fix for error ESMG-74Y4PE - S60 3.2 wk26, Power Saver: 
+    // Flickering when power saver is deactivated.
+    // We now clear the screen with a black brush so the screensaver 
+    // background is changed to black. There will no longer be a white
+    // intermediate screen and this will reduce the "flicker" effect.
+    gc.SetBrushColor( KRgbBlack );
+
+    // Start with a clear screen
+    // If there is no plugin module, indicator view overrides plugin module or
+    // plugin drawing is suspended then the standard screensaver bar is shown,
+    // let's draw it.
+
+        // Let plugin module handle the drawing, unless not requested
+    
+    TInt err = KErrNone;
+    if ( iPluginFlag.IsClear( EPluginFlagTimerNotUsed ) )
+        {
+        err = iPlugin->Draw( gc );
+        }
+	
+	if( err != KErrNone )
+		{
+		iPluginFlag.Set( EPluginFlagSuspend );
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::LoadPluginL
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::LoadPluginL(  MScreensaverPluginHost* /*aPluginHost*/ )
+    {
+    DeletePlugin();
+    LoadPluginModuleL();
+    User::LeaveIfNull( iPlugin );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::LoadPluginModule
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::LoadPluginModuleL()
+    {
+    TFileName pluginName;
+        
+    Model().SharedDataInterface()->GetPluginName( pluginName );
+    
+    // Create plugin object in the DLL
+    // Convert the UID of the given screensaver plugin from text to integer
+    // The string format of the UID: [12345678]
+    // The number inside the brackets in hexadecimal format
+    TLex lex( pluginName );
+    
+    // Skip the first character: '['
+    lex.Get();
+    
+    TUint screenSaverPluginImpUid;
+    
+    // Get the UID
+    TInt err = lex.Val( screenSaverPluginImpUid, EHex );
+    
+    // Bail out, if the UID is not parseable
+    if ( err != KErrNone )
+        {
+        iPlugin = NULL;
+        }
+    //codescanner will crib if leaving function inside trap is called
+    //after line break within the macro. Hence the following trap call
+    //is made in a single line
+    TRAP(err, iPlugin = STATIC_CAST( MScreensaverPlugin*, 
+        CScreensaverPluginInterfaceDefinition::NewL( 
+            TUid::Uid( screenSaverPluginImpUid ) ) ) );
+    
+    if( err != KErrNone )
+        return;
+    
+    TRAP( err, err = iPlugin->InitializeL( this ) );
+    
+    if( err != KErrNone )
+        {
+        // Loaded OK, but failed to initialize - cannot use plugin
+        delete iPlugin;
+        iPlugin = NULL;
+        }
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::DeletePlugin
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::DeletePlugin()
+    {
+    if( iPlugin )
+        {
+        delete iPlugin;
+        iPlugin = NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::StartPluginRefreshTimer
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::StartPluginRefreshTimer()
+    {
+    DeleteTimer( iPluginRefreshTimer );
+
+    if( ( iPluginRefreshRate != 0 ) )
+        {
+        TRAP_IGNORE( iPluginRefreshTimer = CPeriodic::NewL( CActive::EPriorityStandard ) );
+        
+        iPluginRefreshTimer->Start( iPluginRefreshRate, iPluginRefreshRate,
+            TCallBack( HandleRefreshTimerExpiry, this ) );
+        SCRLOGGER_WRITEF( _L("SCR: iRefreshTimer->Start(%d, %d, HandleRefreshTimerExpiry)"),
+            iPluginRefreshRate,iPluginRefreshRate );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::StartPluginTimeoutTimer
+// -----------------------------------------------------------------------------
+//
+void CScreensaverCtrlPlugin::StartPluginTimeoutTimer( TInt aSecs )
+    {
+    // Cancel pending timeouts
+    DeleteTimer( iPluginTimeoutTimer );
+
+    TRAP_IGNORE( iPluginTimeoutTimer = CPeriodic::NewL( CActive::EPriorityStandard ) );
+    
+    // Nothing more to do?
+    if( ( aSecs <= 0 ) || ( aSecs > ( 35 * 60 ) ) ) // 35 mins max
+        {
+        return;
+        }
+
+    TInt timeOut = aSecs * 1000000; // uSecs
+
+    iPluginTimeoutTimer->Start( timeOut, timeOut, TCallBack(
+        HandlePluginTimeoutTimerExpiry, this ) );
+    SCRLOGGER_WRITEF( _L("SCR: iPluginTimeoutTimer->Start(%d, %d, HandlePluginTimeoutTimerTimeout)"),
+        timeOut, timeOut );
+    }
+
+// -----------------------------------------------------------------------------
+// CScreensaverCtrlPlugin::HandlePluginTimeoutTimerExpiry
+// -----------------------------------------------------------------------------
+//
+TInt CScreensaverCtrlPlugin::HandlePluginTimeoutTimerExpiry( TAny* aPtr )
+    {
+    CScreensaverCtrlPlugin *plugin= STATIC_CAST( CScreensaverCtrlPlugin*, aPtr );
+    SCRLOGGER_WRITEF( _L("SCR: Inside CScreensaverView::HandlePluginTimeoutTimerTimeout()") );
+    if ( plugin )
+        {
+        plugin->DeleteTimer( plugin->iPluginRefreshTimer );
+        plugin->DeleteTimer( plugin->iPluginTimeoutTimer );
+        plugin->SendPluginEvent( EScreensaverEventTimeout );
+        }
+
+    return KErrNone;
+    }
+//End of file