uiacceltk/hitchcock/plugins/openwfcrs/src/screencaptureutil.cpp
changeset 0 15bf7259bb7c
--- /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 <e32std.h>
+#include <e32base.h>
+#include "panic.h"
+#include <fbs.h>
+#include <graphics/wsgraphicscontext.h>
+#include <graphics/wsdisplaycontrol.h>
+#include <graphics/wsscene.h>
+#include <graphics/wsdisplaymapping.h>
+//#include <graphics/testscreencapture.h>
+//#include <graphics/wsscreendeviceutils.h>
+#include <graphics/wsscreendevice.h>
+
+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<MWsScene>();
+	STD_ASSERT_ALWAYS(iScene, EPluginPanicSceneMissing);
+	
+	iScreenDevice = aOwner->ObjectInterface<MWsScreenDevice>();
+	STD_ASSERT_ALWAYS(iScreenDevice, EPluginPanicSceneMissing);
+	
+	iDisplayMapping = aOwner->ObjectInterface<MWsDisplayMapping>();
+	
+	// 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<info.iSize.iHeight; y++)
+		{
+		Mem::Copy(bitmapPtr,surfacePtr,copyBytes);
+		surfacePtr += info.iStride;
+		bitmapPtr += aCopyToBitmap.DataStride();
+		}
+	CleanupStack::PopAndDestroy(&chunk);
+	return KErrNone;
+	}