Purpose

Screensaver application monitors the system for user inactivity and displays graphical objects in case of prolonged inactivity. Screensaver immediately stops displaying these objects when user activity resumes. In addition, the display is partially shut down during inactivity.

The graphical object displayed by the Screensaver application can be one of the following:

  • Text

  • Time

  • User-supplied plug-in with arbitrary graphical content

Screensaver plug-ins are used by Screensaver and Themes applications.

  • Screensaver application uses selected plug-in to show graphical objects

  • Themes application allows the user

    • viewing the list of available screensavers

    • activating the selected screensaver

    • previewing screensavers

    • configuring plug-in specific settings

System Context


System Context

Screen Saver API allows third party developers to create screensaver plug-ins. These plug-ins only need to implement code for displaying the custom graphical object. All other functionalities (user activity monitoring, management of screensaver settings, preview functionality, etc.) are already available in Screensaver and Themes applications.

Screensaver plug-ins are implemented as ECom plug-ins and can be installed from SIS packages.

This document describes how to use Screen Saver API to create custom screensaver plug-ins.

Constraints

This API is valid for all platforms running on Symbian OS v9.1 or later.

Classification and release information

Screen Saver API is an SDK API and was first published in S60 3rd Edition.

API description

Screensaver plug-in architecture is based on two main classes. The Screensaver application (and all underlying services) is represented by the abstract interface MScreensaverPluginHost . Screensaver plug-in objects are ECom-plug-ins, implementing the MScreensaverPlugin interface. The plug-in only need to provide code for drawing the custom graphical object. MScreensaverPluginHost provides the default screensaver behavior and data.

There is a two-way communication between the Screensaver plug-in module and the host. The host knows when to activate Screensaver and update the screen. It calls the Draw() function of the plug-in module with graphics context as a parameter. The plug-in module can adjust certain attributes through its host interface such as timeout value of the refresh timer.

Plug-in host (MScreensaverPluginHost)

The plug-in host is represented by interface MScreensaverPluginHost . Plug-ins receive a pointer to the host during initialization. The host has the following responsibilities:

  • creating, initializing, owning and deleting the plug-in

  • providing data for Screensaver indicators (new messages, missed calls, etc.)

  • providing display information

  • activating partial display mode (power saving)

  • redrawing the plug-in object on a regular basis

  • sending Screensaver events to the currently active plug-in

Related APIs
  • MScreensaverPluginHost

Plug-in (MScreensaverPlugin)

Screensaver plug-ins implement the MScreensaverPlugin interface.

Plug-ins are installed as ECom plug-ins, implementing the KCScreensaverPluginInterfaceDefinitionUid (0x101F87F8) interface. For convenience reasons, the class CScreensaverPluginInterfaceDefinition is provided. CScreensaverPluginInterfaceDefinition derives from MScreenSaverPlugin and implements ECom plug-in instantiation. Concrete plug-in implementations should derive from CScreensaverPluginInterfaceDefinition .

Plug-ins implement specific functions in the method PluginFunction() . The host invokes a given function if the plug-in capabilities indicate the support for that particular function. Plug-ins advertise their capabilities by implementing Capabilities() . The same capabilities also need to be defined in the ECom registration file as well.

Related APIs
  • CScreensaverPluginInterfaceDefinition
  • Capabilities()
  • MScreenSaverPlugin
  • MScreensaverPlugin
  • PluginFunction()

Preview mode

Screensavers may be run in preview mode. Preview displays the screensaver shortly, for 10 seconds or until the first user activity. The Themes application calls the plug-in function EScpCapsPreviewNotification before activating preview. The plug-in must have the EScpCapsPreviewNotification capability to receive this notification.

Related APIs
  • EScpCapsPreviewNotification

Partial display mode

For power saving purposes, partial display mode may be available. Availability of this mode depends on the display hardware.

It is possible that the display hardware supports only a limited number of colors when the partial mode is activated. The host provides a method for the plug-in modules to query a color model supported by the display hardware.

The maximum amount of lines active in partial display mode is display specific. There is no function to query the supported value. See Limitations of the API for limitations.

Plug-ins should always use partial display mode. See Section Power saving considerations .

Use cases

  • Implementing custom plug-in

  • Overriding standard indicators

  • Getting indicator data

  • Setting refresh timer

  • Disabling refresh

  • Querying display info

  • Configuring the plug-in

  • Suspending drawing

  • Entering partial display mode

  • Exiting partial display mode

API class structure

Figure 2 shows the main classes of Screen Saver API. Minor data structures are omitted for clarity.

The main classes are MScreenSaverPluginHost and MScreenSaverPlugin , representing the host application and the screensaver plug-in, respectively.

The class CScreenSaverPluginInterfaceDefinition is the convenience class, to be used as a base to the actual screen saver plug-in. It uses REcomSession to load the plug-in.

CExampleScreenSaverPlugin is included for clarity. It is not part of Screen Saver API.

Screen Saver API


Screen Saver API

Related APIs
  • CExampleScreenSaverPlugin
  • CScreenSaverPluginInterfaceDefinition
  • MScreenSaverPlugin
  • MScreenSaverPluginHost
  • REcomSession
Related APIs
  • Draw()
  • MScreensaverPlugin
  • MScreensaverPluginHost

Using Screen Saver API

Using Screen Saver API means implementing a plug-in, which uses services of the host.

Implementing custom plug-in

Plug-ins derive from CScreensaverPluginInterfaceDefinition .

             
              class CExampleScreenSaverPlugin:
              
    public CScreensaverPluginInterfaceDefinition
    {    

    public: 

        static CExampleScreenSaverPlugin* NewL();
        virtual ~CExampleScreenSaverPlugin();     

    public: // from CScreensaverPluginInterfaceDefinition        

        virtual TInt InitializeL( MScreensaverPluginHost *aHost );
        virtual TInt Draw( CWindowGc& aGc );
        virtual const TDesC16& Name() const;
        virtual TInt Capabilities();
        virtual TInt PluginFunction(
            TScPluginCaps aFunction,
            TAny* aParam );
        virtual TInt HandleScreensaverEventL(
            TScreensaverEvent aEvent,
            TAny* aData );                           

    private: // data

        MScreensaverPluginHost* iHost; // Host, not owned.
        TRect iRect; // Rect of display area.

    };

MMP file fragment.

             
              TARGET          ExampleScreenSaverPlugin.dll
              
TARGETTYPE      PLUGIN 
UID             0x10009D8D 0xE000ABCD
CAPABILITY      NetworkServices LocalServices Location ReadUserData WriteUserData
ReadDeviceData WriteDeviceData SwEvent UserEnvironment PowerMgmt

START RESOURCE ..\data\10207447.rss 
TARGET          ExampleScreenSaverPlugin.rsc
END

SOURCE          ExampleScreenSaverPlugin.cpp

SYSTEMINCLUDE   \epoc32\include
SYSTEMINCLUDE   \epoc32\include\ecom

LIBRARY         ecom.lib 
LIBRARY         euser.lib

ECom registration resource file fragment.

The opaque_data contains the plug-in capabilities in string format. Same capability values must be returned in numeric format by MScreensaverPlugin::Capabilities() .

MScreensaverPlugin::Name() or display_name provide the string displayed to the user in Screensaver settings view in the Themes application. display_name is not used unless MScreensaverPlugin::Name() returns an empty string. This way the plug-in registration file need not contain localizable information.

Note that in S60 3rd Edition, display_name was used instead of MScreensaverPlugin::Name() .

             
              #include <RegistryInfo.rh>
              
#include "ScreensaverPluginIntDef.hrh"

RESOURCE REGISTRY_INFO theInfo
    {
    dll_uid = 0xE000ABCD;
    interfaces =
        {
        INTERFACE_INFO
            {
            interface_uid = KCScreensaverPluginInterfaceDefinitionUid;
            implementations =
                {
                IMPLEMENTATION_INFO
                    {
                    implementation_uid = 0xE0001234;
                    version_no = 1;
                    display_name = "Example plugin";
                    default_data = "";
                    opaque_data = "07";
                    }
                };
            }
        };
    }

The ECom plug-in must export its implementation proxy table:

             
              #include    <e32Std.h>
              
#include    <ImplementationProxy.h>

const TImplementationProxy ImplementationTable[] =
    {
    IMPLEMENTATION_PROXY_ENTRY( 0xE0001234, CExampleScreenSaverPlugin::NewL )
    };

EXPORT_C const TImplementationProxy*
    ImplementationGroupProxy( TInt& aTableCount )
    {
    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
    return ImplementationTable;
    }

Instance creation through ECom should be light. It is possible that plug-ins are created but never initialized and drawn. For example, if the plug-in supports the configure function, the Themes application creates an instance and calls plug-in function EScpCapsConfigure , without initializing the plug-in.

The Screensaver application will call InitializeL() to prepare the plug-in for drawing. Initialization for drawing-related resources should be implemented in InitializeL() instead of ConstructL() .

             
              void CExampleScreenSaverPlugin::ConstructL()
              
    {
    }

TInt CExampleScreenSaverPlugin::InitializeL
( MScreensaverPluginHost *aHost )
    {     
    iScreenSaverHost = aHost;
    // Prepare for drawing: load resources, etc.
    // ...
    return KErrNone;
    }

Capabilities must match the supported plug-in functions. Capabilities are read by, and the plug-in functions are called from the Themes application.

             
              TInt CExampleScreenSaverPlugin::Capabilities()
              
    {
    return EScpCapsConfigure |
           EScpCapsSelectionNotification |
           EScpCapsPreviewNotification;
    }

TInt CExampleScreenSaverPlugin::PluginFunction(
            TScPluginCaps aFunction,
            TAny* /*aParam*/)
    { 
    switch ( aFunction )
        {
        case EScpCapsConfigure:
            {
            // Called from Themes.
            // Options->Settings selected.
            // Launch dialog to configure plug-in settings.
            // InitializeL() may not have been called.
            // ...
            break;
            }
        case EScpCapsSelectionNotification:
            {
            // Called from Themes.
            // Options->Apply selected.
            // ...
            break;
            }
        case EScpCapsPreviewNotification:
            {
            // Called from Themes.
            // Options->Preview selected.
            // Prepare for preview.
            // ...
            break;
            }
        }
    return KErrNone;                                                
    }

The plug-in responds to screensaver events, sent by the host.

             
              TInt CExampleScreenSaverPlugin::HandleScreensaverEventL(
              
        TScreensaverEvent aEvent,
        TAny* /*aData*/ )
    {
    switch ( aEvent )
        {
        case EScreensaverEventNothing:
            {
            // This event should never be delivered.
            break;
            }

        case EScreensaverEventStarting:
            {
            // This event is delivered when screensaver is about to start.
            break;
            }

        case EScreensaverEventStopping:
            {
            // This event is delivered when screensaver is stopped.
            // In case plug-in has internal timers while screensaver
            // is displayed, here you can stop those.
            break;
            }

        case EScreensaverEventDisplayChanged:
            {
            // This event needs to be handled when display resolution
            // or orientation is changed.
            // You can refresh information about display using
            // MScreensaverPluginHost::DisplayInfo method.
            break;
            }

        case EScreensaverEventTimeout:
            {
            // This event is delivered when plug-in requested
            // timeout expires. 
            // See MScreensaverPluginHost::RequestTimeout.
            break;
            }

        case EScreensaverEventPreview:
            {
            // This event is delivered by screensaver application
            // when plug-in started to be used in preview mode.
            // Note that themes application
            // informs of preview  activation through PluginFunction.
            break;
            }

        default:
            {
            // Ignore any new events.
            }
            break;
        }

    return KErrNone;
    }

Plug-ins implement the drawing code in the Draw() method. Based on the refresh timer, the host calls Draw() periodically. Draw() receives the window context to be used for drawing as parameter

Related APIs
  • CScreensaverPluginInterfaceDefinition
  • ConstructL()
  • Draw()
  • EScpCapsConfigure
  • InitializeL()
  • MScreensaverPlugin::Capabilities()
  • MScreensaverPlugin::Name()
  • display_name
  • opaque_data

Overriding standard indicators

By default, Screensaver draws the indicators and the plug-in only draws the custom graphical object. It is possible to turn standard indicators off.

             
              iHost->OverrideStandardIndicators();
             
            

Typical uses of this feature include:

  • the plug-in draws custom indicators

  • the plug-in displays animation, and does not want the animation be obscured by the standard indicators.

Getting indicator data

The following code snippet gets the number of missed calls from the host. This is typically used if the plug-in draws custom indicators.

             
              TInt missedCalls = 0;
              
TIndicatorPayload payload;
TInt err = iHost->GetIndicatorPayload
    ( EScreensaverIndicatorIndexNewMissedCalls, payload );
if ( KErrNone == err )
    {
    missedCalls = payload.iInteger;
    }

Setting refresh timer

Plug-ins can adjust the refresh timer. See Power saving considerations .

             
              iHost->SetRefreshTimerValue( 10000000 ); // 10 seconds
             
            

Disabling refresh

If refresh timer is disabled, the host does not call the Draw() method of the plug-in.

             
              iHost->UseRefreshTimer( EFalse );
             
            
Related APIs
  • Draw()

Querying display info

The following example demonstrates screensaver event handling. In response to the EScreensaverEventDisplayChanged event, a display info is queried from the host.

Note that TScreensaverDisplayInfo::iSize must be set by the caller.

In this example, the plug-in copies the display TRect to a member variable.

             
              TInt CExampleScreenSaverPlugin::HandleScreensaverEventL(
              
            TScreensaverEvent aEvent,
            TAny* /*aData*/ )
    {
    if ( EScreensaverEventDisplayChanged == aEvent )
        {
        // Display Changed is called when there is a change in the size
        // of the window and when the parent control is set for the 
        // first time.        
        TScreensaverDisplayInfo displayInfo;
        displayInfo.iSize = sizeof( TScreensaverDisplayInfo );
        User::LeaveIfError( iHost->DisplayInfo( &displayInfo ) );
        iRect = displayInfo->iRect; // Save display rect.
        }
    //...
    return KErrNone;
    }
Related APIs
  • EScreensaverEventDisplayChanged
  • TRect
  • TScreensaverDisplayInfo::iSize

Configuring the plug-in

Configurable plug-ins must advertise capability EScpCapsConfigure . Plug-in function EScpCapsConfigure can be used to display the configuration UI to the user.

Note that plug-in function EScpCapsConfigure may be called without InitializeL() being called first.

Management and persistence of the plug-in specific settings are beyond the scope of this document. One possible implementation is using Central Repository.

Related APIs
  • EScpCapsConfigure
  • InitializeL()

Suspending drawing

Plug-ins can suspend drawing for a requested period of time, or indefinitely. During this standard screensaver view is drawn.

             
              iHost->Suspend( -1 ); // Value in microsecods.
              
                      // Negative value: suspend indefinitely.

Entering partial display mode

The following code snippet demonstrates using the partial display mode.

             
              TInt CExampleScreenSaverPlugin::Draw( CWindowGc& aGc )
              
    {
    TRect rect = TRect( 0, 0, 240, 40 );
    aGc.Clear( rect );
    aGc.SetPenColor( KRgbBlack );
    aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
    aGc.SetPenStyle( CGraphicsContext::ESolidPen );
    aGc.UseFont( iEikonEnv->TitleFont() );
    aGc.DrawText( _L("hello world"), TPoint( 0, 30 ) );
    TScreensaverPartialMode partialMode;
    partialMode.iBpp = 0; 
    partialMode.iType = EPartialModeTypeMostPowerSaving;
    // Call SetActiveDisplayArea last - it may cause flush.
    (void)iHost->SetActiveDisplayArea( rect, partialMode );
    return KErrNone;
    }

Exiting partial display mode

The following code snippet cancels the effect of the SetActiveDisplayArea() method. The whole display area is activated.

             
              iHost->ExitPartialMode ();
             
            
Related APIs
  • SetActiveDisplayArea()

Error handling

Screen Saver API uses standard Symbian platform error reporting mechanism and standard error codes.

In certain error situations plug-ins may detect unrecoverable errors. The plug-in may choose to disable itself and revert back to the default screensaver, by calling MScreensaverPluginHost::RevertToDefaultSaver() . This causes the plug-in to be unloaded. An example for such a situation could be if the plug-in’s graphical object is digitally protected, and the client Rights Object to render the graphical object has expired.

It should be noted, however, that the plug-in host also has a fallback mechanism. If the plug-in fails to load, the host activates a default screensaver.

Related APIs
  • MScreensaverPluginHost::RevertToDefaultSaver()

Memory overhead

Memory consumption of screensaver depends on the actual plug-in implementation.

Power saving considerations

Reducing power consumption is one of the primary considerations in Screensaver. When writing plug-ins, prefer low power consumption over fancy graphics. Screensaver runs when nobody is watching.

  • Partial display mode should always be used. Full screen mode should only be used temporarily, as it reduces standby time significantly.

  • Using own timers in plug-in code is not recommended. The refresh timer (provided by the plug-in host) should be sufficient for most uses.

  • Refresh rate should be kept low.

  • Unnecessary computations should be avoided.

  • Overriding screen backlight handling should be avoided.

Limitations of the API

There is no function to query the maximum number of lines supported by the display hardware in partial display mode. As a rule of thumb, support for 50 lines could be assumed.

Glossary

Abbreviations

Screensaver API abbreviations

API Application Programming Interface

OS

Operating System

SDK

Software Development Kit

Definitions

Screensaver API definitions

Plug-in module A piece of program, which is loaded and executed by request at runtime. Implements a certain interface. Plug-in modules are used for dynamically customizing and expanding the existing applications without needing to recompile and re-install the whole application.