taskswitcher/contextengine/tsfswpreviewprovider/wsplugin/src/previewprovidercrp.cpp
changeset 4 4d54b72983ae
child 15 ff572dfe6d86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/taskswitcher/contextengine/tsfswpreviewprovider/wsplugin/src/previewprovidercrp.cpp	Tue Jan 26 11:48:23 2010 +0200
@@ -0,0 +1,436 @@
+/*
+* 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:  Preview provider ECOM plugin
+*
+*/
+
+
+#include <bldvariant.hrh>
+#ifdef SYMBIAN_BUILD_GCE
+#define NGA
+#endif
+
+#include "previewprovidercrp.h"
+#include "previewmsg.h"
+#include "previewprovidercrplogging.h"
+#include <ecom/implementationproxy.h>
+#include <s32mem.h> //RDesReadStream
+
+#ifdef NGA
+#include <graphics/wsscreendevice.h>
+#endif
+
+// CONSTANTS
+const TInt KImpId( 0x20016BEC );
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::CreateL
+// --------------------------------------------------------------------------
+//
+CWsGraphicDrawer* CPreviewProviderCRP::CreateL()
+    {
+    CPreviewProviderCRP* crp = new (ELeave) CPreviewProviderCRP();
+    CleanupStack::PushL( crp );
+    crp->ConstructL();
+    CleanupStack::Pop( crp );
+    return crp;
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::ConstructL
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::ConstructL()
+    { 
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::~CPreviewProviderCRP
+// --------------------------------------------------------------------------
+//    
+CPreviewProviderCRP::~CPreviewProviderCRP()    
+    {
+    Env().UnregisterEventHandler( this );
+    iScreenshots.ResetAndDestroy();
+    iWgIds.Close();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::DoDraw
+// --------------------------------------------------------------------------
+//
+void CPreviewProviderCRP::DoDraw( MWsGc& /*aGc*/, const TRect& /*aRect*/, 
+    const TDesC8& /*aData*/) const
+    {
+    //draws nothing
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::HandleMessage
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::HandleMessage( const TDesC8& aData )
+    {
+    TRAP_IGNORE( DoHandleMessageL( aData ) );
+    }
+    
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::DoHandleMessageL
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::DoHandleMessageL( const TDesC8& aData )
+    {  
+    TSLOG_CONTEXT( DoHandleMessageL, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    RDesReadStream in( aData );
+    switch( in.ReadInt32L() )
+        {
+        case NPreviewMsg::ERegister:
+            {
+            const TInt id = in.ReadInt32L();
+            Register( id );
+            }
+            break;
+        case NPreviewMsg::EUnregister:
+            {
+            const TInt id = in.ReadInt32L();
+            Unregister( id );
+            }
+            break;
+        case NPreviewMsg::EChangeScreen:
+            {
+            const TInt screen = in.ReadInt32L();
+            if ( Env().ScreenCount() )
+                {
+                iScreen = screen;
+                }
+            }
+            break;
+        case NPreviewMsg::ESetPreviewParam:
+            iScreenshotSize.iWidth = in.ReadInt32L();
+            iScreenshotSize.iHeight = in.ReadInt32L();
+            iScreenshotMode = static_cast<TDisplayMode>( in.ReadInt32L() );
+            break;
+        case NPreviewMsg::ETakePreview:
+            ScreenshotL();
+            break;
+        case NPreviewMsg::EAckPreviewReady:
+            RemoveScreenshot( in.ReadInt32L() );
+            break;
+        }
+    
+    TSLOG_OUT();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::ConstructL
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::ConstructL( MWsGraphicDrawerEnvironment& aEnv,
+    const TGraphicDrawerId& aId, MWsClient& aOwner, const TDesC8& /*aData*/ )
+    {
+    TSLOG_CONTEXT( ConstructL, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    BaseConstructL( aEnv, aId, aOwner );
+    aEnv.RegisterEventHandler( this, this, TWservCrEvent::EWindowGroupChanged );
+    
+    TSLOG_OUT();
+    }
+    
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::DoHandleEvent
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::DoHandleEvent( const TWservCrEvent& aEvent )
+    {
+    TSLOG_CONTEXT( DoHandleEvent, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    if ( aEvent.Type() == TWservCrEvent::EWindowGroupChanged )
+        {
+        const TInt wgId = aEvent.WindowGroupIdentifier();
+        if ( iWgIds.FindInOrder( iPrevId ) >= 0 ||
+            ( iPrevId == 0 &&  iPrevReg != 0 ) )
+            {
+            TRAP_IGNORE( ScreenshotL() );
+            iPrevReg = 0;
+            }
+        iPrevId = wgId;
+        }
+    
+    TSLOG_OUT();
+    }
+    
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::ScaleComplete
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::ScaleCompleteL( const CFbsBitmap& aBitmap )
+    {
+    TSLOG_CONTEXT( ScaleComplete, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    const TInt msg[] = {
+            NPreviewMsg::EPreviewReady,
+            iPrevId?iPrevId:iPrevReg,
+            aBitmap.Handle()
+            };
+    TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg);
+    User::LeaveIfError( SendMessage( buf ) );
+    TSLOG3( TSLOG_INFO, "size = %dx%d handle = %d",
+        aBitmap.SizeInPixels().iWidth,
+        aBitmap.SizeInPixels().iHeight,
+        aBitmap.Handle() );
+    TSLOG_OUT();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::UnregisterComplete
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::UnregisterComplete( TInt aWgId )
+    {
+    TSLOG_CONTEXT( UnregisterComplete, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    const TInt msg[] = {
+            NPreviewMsg::EUnregisterReady,
+            aWgId,
+            0
+            };
+    TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg);
+    SendMessage(buf);
+    
+    TSLOG_OUT();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::Register
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::Register( TInt aWgId )
+    {
+    TSLOG_CONTEXT( Register, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    iPrevReg = aWgId;
+    iWgIds.InsertInOrder( aWgId );
+    
+    TSLOG_OUT();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::Unregister
+// --------------------------------------------------------------------------
+//
+void CPreviewProviderCRP::Unregister( TInt aWgId )
+    {
+    TSLOG_CONTEXT( Unregister, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    const TInt index = iWgIds.FindInOrder( aWgId );
+    if ( index >= 0 )
+        {
+        iWgIds.Remove( index );
+        }
+    
+    UnregisterComplete( aWgId );
+    
+    TSLOG_OUT();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::ScreenShotL
+// --------------------------------------------------------------------------
+//
+void CPreviewProviderCRP::ScreenshotL()
+    {
+    CFbsBitmap* screenshot = new (ELeave)CFbsBitmap();
+    CleanupStack::PushL( screenshot );
+    ScreenshotL( *screenshot );
+    ScaleCompleteL( *screenshot );
+    iScreenshots.InsertL( screenshot, iScreenshots.Count() );
+    CleanupStack::Pop( screenshot );
+    CheckOverflow();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::ScreenShotL
+// --------------------------------------------------------------------------
+//
+void CPreviewProviderCRP::ScreenshotL(CFbsBitmap& aBitmap)
+    {
+    TSLOG_CONTEXT( ScreenShot, TSLOG_LOCAL );
+    TSLOG_IN();
+
+    if( 0 > iScreen || Env().ScreenCount() <= iScreen )
+        {
+        //screen offset out of range. skip request
+        User::Leave(KErrArgument);
+        }
+    // Find the screen resolution
+    MWsScreenConfig* screenConfig = 
+        Env().Screen( iScreen )->ObjectInterface<MWsScreenConfig>();    
+    
+    const TSize sz = screenConfig->ScreenModeSizeInPixels();
+
+    // Get the screen buffer (containing screenshot data)
+    MWsFrontBuffer* screenFront = 
+        Env().Screen( iScreen )->ObjectInterface<MWsFrontBuffer>();
+    
+    // With NGA we do not support downscaling of the screenshots.
+    // So use the size of the screen if no screenshot size has been explicitly
+    // set or if the old method for taking screenshots is not available.
+    if ( iScreenshotSize.iWidth == 0 || 
+         iScreenshotSize.iHeight == 0 || 
+         !screenFront )
+        {
+        iScreenshotSize = sz;
+        }
+    // Use the the same DisplayMode as for the source image
+    // so override the display mode, ignoring any requests.
+    iScreenshotMode = screenConfig->DisplayMode();
+    
+    TSLOG3( TSLOG_INFO, "iShotSize: %dx%d mode: %d",
+        iScreenshotSize.iWidth, iScreenshotSize.iHeight, iScreenshotMode );
+    
+    aBitmap.Reset();
+    User::LeaveIfError( aBitmap.Create( iScreenshotSize, iScreenshotMode ) );
+  
+    // Check if front buffer is available.
+    // Will always be NULL with NGA.
+    if ( screenFront )
+        {
+        TSLOG0( TSLOG_INFO, "non-NGA, using front buffer" );
+        FrontBufferScreenShot( aBitmap, *screenFront, sz, screenConfig->Stride() );
+        }
+#ifdef NGA
+    else
+        {
+        TSLOG0( TSLOG_INFO, "NGA, using CopyScreenToBitmapL" );
+        MWsScreenDevice* screenDevice = static_cast<MWsScreenDevice*>(
+            Env().Screen( iScreen )->ResolveObjectInterface(
+                MWsScreenDevice::EWsObjectInterfaceId ) );
+        User::LeaveIfNull( screenDevice );
+        screenDevice->CopyScreenToBitmapL( &aBitmap, iScreenshotSize );
+        }
+#endif
+    TSLOG_OUT();
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::RemoveScreenshot
+// --------------------------------------------------------------------------
+//
+void CPreviewProviderCRP::RemoveScreenshot( TInt aBitmapHandle )
+    {
+    for( int iter(0); iter < iScreenshots.Count(); ++iter )
+        {
+        if( iScreenshots[iter]->Handle() == aBitmapHandle )
+            {
+            delete iScreenshots[iter];
+            iScreenshots.Remove(iter);
+            break;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::CheckOverflow
+// --------------------------------------------------------------------------
+//
+void CPreviewProviderCRP::CheckOverflow()
+    {
+    TInt overflow( iScreenshots.Count() - KMaxShots);
+    while( 0 < overflow-- )
+        {
+        delete iScreenshots[0];
+        iScreenshots.Remove(0);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPreviewProviderCRP::FrontBufferScreenShot
+// --------------------------------------------------------------------------
+//    
+void CPreviewProviderCRP::FrontBufferScreenShot( CFbsBitmap& aBitmap, 
+                                                 MWsFrontBuffer& aFront, 
+                                                 const TSize& aSrcSize, 
+                                                 TInt aSrcStride )
+    {
+    TSLOG_CONTEXT( CPreviewProviderCRP::FrontBufferScreenShot, TSLOG_LOCAL );
+    TSLOG_IN();
+    
+    const TUint8* src = static_cast<const TUint8*> ( aFront.GetBits() );
+    TSLOG1( TSLOG_INFO, "src address = [%d]", src );
+        
+    TInt srcstride( aSrcStride );
+    TInt srcwidth( aSrcSize.iWidth );
+    TInt srcheight( aSrcSize.iHeight ); 
+    TInt dststride( aBitmap.DataStride() );
+    TInt dstheight( iScreenshotSize.iHeight );
+    TInt dstwidth( iScreenshotSize.iWidth );
+    TInt stepdst( dststride / dstwidth );
+    TInt stepsrc( srcstride / srcwidth );
+    // scale must be TInt type
+    TInt scaleX( aSrcSize.iWidth / iScreenshotSize.iWidth );
+    TInt scaleY( aSrcSize.iHeight / iScreenshotSize.iHeight );
+    
+    aBitmap.LockHeap();
+    
+    TUint8* dst = ( TUint8* ) aBitmap.DataAddress();
+    
+    TInt minWidth = Min( srcwidth, dstwidth );
+    TInt minHeight = Min( srcheight, dstheight );
+    TInt minStep = Min( stepsrc, stepdst );
+    
+    for ( TInt y = minHeight; y > 0; y-- )
+         {
+         for ( TInt x = minWidth; x > 0; x-- )
+             {
+             Mem::Copy( dst, src, minStep );
+             dst += stepdst;
+             src += scaleX*stepdst;
+             }
+         src += srcstride - scaleX * stepdst * minWidth;
+         src += ( scaleY - 1 ) * srcstride;
+         }
+         
+    aBitmap.UnlockHeap();
+    TSLOG_OUT();
+    }
+    
+// --------------------------------------------------------------------------
+// KImplementationTable
+// --------------------------------------------------------------------------
+//    
+LOCAL_C const TImplementationProxy KImplementationTable[] = 
+    {
+    IMPLEMENTATION_PROXY_ENTRY(KImpId, CPreviewProviderCRP::CreateL)
+    };
+
+// --------------------------------------------------------------------------
+// ImplementationGroupProxy
+// --------------------------------------------------------------------------
+//    
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = (sizeof(KImplementationTable) / sizeof(TImplementationProxy));
+    return KImplementationTable;
+    }
+
+
+// End of file