diff -r fb3763350a08 -r 4d54b72983ae taskswitcher/contextengine/tsfswpreviewprovider/wsplugin/src/previewprovidercrp.cpp --- /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 +#ifdef SYMBIAN_BUILD_GCE +#define NGA +#endif + +#include "previewprovidercrp.h" +#include "previewmsg.h" +#include "previewprovidercrplogging.h" +#include +#include //RDesReadStream + +#ifdef NGA +#include +#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( 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 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 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(); + + const TSize sz = screenConfig->ScreenModeSizeInPixels(); + + // Get the screen buffer (containing screenshot data) + MWsFrontBuffer* screenFront = + Env().Screen( iScreen )->ObjectInterface(); + + // 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( + 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 ( 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