diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/plugins/openwfcrs/src/screencaptureutil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/plugins/openwfcrs/src/screencaptureutil.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,225 @@ +// Copyright (c) 2008-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: +// + +#include "screencaptureutil.h" +#include +#include +#include "panic.h" +#include +#include +#include +#include +#include +//#include +//#include +#include + +CScreenCaptureUtil* CScreenCaptureUtil::NewL(CWsRenderStage* aOwner) + { + CScreenCaptureUtil * util = new(ELeave) CScreenCaptureUtil; + CleanupStack::PushL(util); + util->ConstructL(aOwner); + + CleanupStack::Pop(util); + return util; + } + +void CScreenCaptureUtil::ConstructL(CWsRenderStage* aOwner) + { + // initialise the references to the interfaces of interest + iScene = aOwner->ObjectInterface(); + STD_ASSERT_ALWAYS(iScene, EPluginPanicSceneMissing); + + iScreenDevice = aOwner->ObjectInterface(); + STD_ASSERT_ALWAYS(iScreenDevice, EPluginPanicSceneMissing); + + iDisplayMapping = aOwner->ObjectInterface(); + + // create the local surface + User::LeaveIfError(iSurfaceManager.Open()); + User::LeaveIfError(iSurfaceUpdateSession.Connect()); + } + +CScreenCaptureUtil::CScreenCaptureUtil() + { + } + +CScreenCaptureUtil::~CScreenCaptureUtil() + { + iScene->UnregisterSurface(iLocalSurface); + iSurfaceManager.CloseSurface(iLocalSurface); + iSurfaceManager.Close(); + iSurfaceUpdateSession.Close(); + } + +void CScreenCaptureUtil::ComposeScreenL(TInt aHandle) + { + TInt ret = KErrNone; + + //Let's duplicate the bitmap + CFbsBitmap* bitmap=new(ELeave) CFbsBitmap(); + CleanupStack::PushL(bitmap); + + TInt r = bitmap->Duplicate(aHandle); + + if (r == KErrNoMemory) + { + User::Leave(KErrNoMemory); + } + + ret = KErrBadHandle; + if (r == KErrNone) + { + CreateLocalSurfaceL(); + + // check that the bitmap format is matching our requirements + if (VerifyBitmapFormatL(*bitmap)) + { + ret = iScene->RegisterSurface(iLocalSurface); + if (ret == KErrNone) + { + TRequestStatus cRs = KErrNone; + iScene->ComposePendingScene(iLocalSurface, &cRs); + User::WaitForRequest(cRs); + ret = CopySurfaceToBitmapL(*bitmap); + } + } + else + { + // we accept only matching bitmap formats + ret = KErrArgument; + } + } + + CleanupStack::PopAndDestroy(bitmap); + } +/* +void CScreenCaptureUtil::TranslateExtentL(const TWsScsComposeScreenCommand& aMessage) + { + TPoint srcTopLeft(aMessage.iParameter.iExtent.iTl.iX, aMessage.iParameter.iExtent.iTl.iY); + TPoint srcBottomRight(aMessage.iParameter.iExtent.iBr.iX, aMessage.iParameter.iExtent.iBr.iY); + TRect rectSrc(srcTopLeft, srcBottomRight); + TRect rectRes; + TInt ret = iDisplayMapping->MapCoordinates(EApplicationSpace, rectSrc, ECompositionSpace, rectRes); + aUtils.ReplyBuf(&rectRes, sizeof(TRect)); + aUtils.SetReply(ret); + } +*/ +TSurfaceId CScreenCaptureUtil::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride) + { + RSurfaceManager::TSurfaceCreationAttributesBuf bf; + RSurfaceManager::TSurfaceCreationAttributes& b = bf(); + b.iSize.iWidth = aSize.iWidth; + b.iSize.iHeight = aSize.iHeight; + b.iBuffers = 1; // number of buffers in the surface + b.iPixelFormat = aPixelFormat; + b.iStride = aStride; // Number of bytes between start of one line and start of next + b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned + b.iContiguous=EFalse; + b.iMappable = ETrue; + + TSurfaceId surface = TSurfaceId::CreateNullId(); + User::LeaveIfError(iSurfaceManager.CreateSurface(bf, surface)); + return surface; + } + +void CScreenCaptureUtil::CreateLocalSurfaceL() + { + TSize surfaceSize; + GetCompositionAreaSize(surfaceSize); + + if (!iLocalSurface.IsNull()) + { + RSurfaceManager::TInfoBuf infoBuf; + RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); + if ((KErrNone != iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)) || + (info.iSize != surfaceSize)) + { + iScene->UnregisterSurface(iLocalSurface); + iSurfaceManager.CloseSurface(iLocalSurface); + iLocalSurface = TSurfaceId::CreateNullId(); + } + } + + if (iLocalSurface.IsNull()) + { + iLocalSurface = CreateSurfaceL(surfaceSize, KSurfacePixelFormat, KSurfaceBytesPerPixel*surfaceSize.iWidth); + } + } + +TBool CScreenCaptureUtil::VerifyBitmapFormatL(const CFbsBitmap& aBitmap) + { + RSurfaceManager::TInfoBuf infoBuf; + RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); + User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)); + + return ((info.iSize == aBitmap.SizeInPixels()) && (EColor16MU == aBitmap.DisplayMode())); + } + +void CScreenCaptureUtil::GetCompositionAreaSize(TSize& aSize) const + { + TSize uiSize; + uiSize = iScreenDevice->SizeInPixels(); + TRect uiRect(TPoint(0,0), uiSize); + TRect compositionRect; + iDisplayMapping->MapCoordinates(EFullScreenSpace, uiRect, ECompositionSpace, compositionRect); + aSize = compositionRect.Size(); + } + +TInt CScreenCaptureUtil::CopySurfaceToBitmapL(CFbsBitmap& aCopyToBitmap) + { + RSurfaceManager::TInfoBuf infoBuf; + RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); + + User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)); + + TInt bytesPerPixel=0; + TDisplayMode bitmapMode = ENone; + + switch (info.iPixelFormat) + { + case EUidPixelFormatXRGB_8888: + { + bitmapMode = EColor16MU; + bytesPerPixel = 4; + break; + } + default: + { + return KErrCorrupt; + } + } + + if ((aCopyToBitmap.SizeInPixels() != info.iSize) || (aCopyToBitmap.DisplayMode() != bitmapMode)) + { + return KErrCorrupt; + } + + RChunk chunk; + CleanupClosePushL(chunk); + User::LeaveIfError(iSurfaceManager.MapSurface(iLocalSurface, chunk)); + TUint8* surfacePtr = chunk.Base(); + TUint8* bitmapPtr = (TUint8*)aCopyToBitmap.DataAddress(); + TInt copyBytes=info.iSize.iWidth*bytesPerPixel; + for (TInt y=0; y