uiacceltk/hitchcock/plugins/openwfcrs/src/screencaptureutil.cpp
changeset 0 15bf7259bb7c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "screencaptureutil.h"
       
    17 #include <e32std.h>
       
    18 #include <e32base.h>
       
    19 #include "panic.h"
       
    20 #include <fbs.h>
       
    21 #include <graphics/wsgraphicscontext.h>
       
    22 #include <graphics/wsdisplaycontrol.h>
       
    23 #include <graphics/wsscene.h>
       
    24 #include <graphics/wsdisplaymapping.h>
       
    25 //#include <graphics/testscreencapture.h>
       
    26 //#include <graphics/wsscreendeviceutils.h>
       
    27 #include <graphics/wsscreendevice.h>
       
    28 
       
    29 CScreenCaptureUtil* CScreenCaptureUtil::NewL(CWsRenderStage* aOwner)
       
    30 	{
       
    31 	CScreenCaptureUtil * util = new(ELeave) CScreenCaptureUtil;
       
    32 	CleanupStack::PushL(util);
       
    33 	util->ConstructL(aOwner);
       
    34 	
       
    35 	CleanupStack::Pop(util);
       
    36 	return util;
       
    37 	}
       
    38 	
       
    39 void CScreenCaptureUtil::ConstructL(CWsRenderStage* aOwner)
       
    40 	{
       
    41 	// initialise the references to the interfaces of interest
       
    42 	iScene = aOwner->ObjectInterface<MWsScene>();
       
    43 	STD_ASSERT_ALWAYS(iScene, EPluginPanicSceneMissing);
       
    44 	
       
    45 	iScreenDevice = aOwner->ObjectInterface<MWsScreenDevice>();
       
    46 	STD_ASSERT_ALWAYS(iScreenDevice, EPluginPanicSceneMissing);
       
    47 	
       
    48 	iDisplayMapping = aOwner->ObjectInterface<MWsDisplayMapping>();
       
    49 	
       
    50 	// create the local surface
       
    51 	User::LeaveIfError(iSurfaceManager.Open());
       
    52 	User::LeaveIfError(iSurfaceUpdateSession.Connect());
       
    53 	}
       
    54 	
       
    55 CScreenCaptureUtil::CScreenCaptureUtil()
       
    56 	{
       
    57 	}
       
    58 	
       
    59 CScreenCaptureUtil::~CScreenCaptureUtil()
       
    60 	{
       
    61 	iScene->UnregisterSurface(iLocalSurface);
       
    62 	iSurfaceManager.CloseSurface(iLocalSurface);
       
    63 	iSurfaceManager.Close();
       
    64 	iSurfaceUpdateSession.Close();
       
    65 	}
       
    66 
       
    67 void CScreenCaptureUtil::ComposeScreenL(TInt aHandle)
       
    68 	{
       
    69 	TInt ret = KErrNone;
       
    70 
       
    71 	//Let's duplicate the bitmap
       
    72 	CFbsBitmap* bitmap=new(ELeave) CFbsBitmap();
       
    73 	CleanupStack::PushL(bitmap);
       
    74 	
       
    75 	TInt r = bitmap->Duplicate(aHandle);
       
    76 	
       
    77 	if (r == KErrNoMemory)
       
    78 		{
       
    79 		User::Leave(KErrNoMemory);
       
    80 		}
       
    81 	
       
    82 	ret = KErrBadHandle;
       
    83 	if (r == KErrNone)
       
    84 		{
       
    85 		CreateLocalSurfaceL();
       
    86 		
       
    87 		// check that the bitmap format is matching our requirements
       
    88 		if (VerifyBitmapFormatL(*bitmap))
       
    89 		    {
       
    90 	        ret = iScene->RegisterSurface(iLocalSurface);
       
    91 	        if (ret == KErrNone)
       
    92 	            {
       
    93 	            TRequestStatus cRs = KErrNone;
       
    94 	            iScene->ComposePendingScene(iLocalSurface, &cRs);
       
    95 	            User::WaitForRequest(cRs);
       
    96 	            ret = CopySurfaceToBitmapL(*bitmap);
       
    97 	            }
       
    98 			}
       
    99 		else
       
   100 			{
       
   101 			// we accept only matching bitmap formats
       
   102 			ret = KErrArgument;
       
   103 			}
       
   104 		}
       
   105 	
       
   106 	CleanupStack::PopAndDestroy(bitmap);
       
   107 	}
       
   108 /*
       
   109 void CScreenCaptureUtil::TranslateExtentL(const TWsScsComposeScreenCommand& aMessage)
       
   110 	{
       
   111 	TPoint srcTopLeft(aMessage.iParameter.iExtent.iTl.iX, aMessage.iParameter.iExtent.iTl.iY);
       
   112 	TPoint srcBottomRight(aMessage.iParameter.iExtent.iBr.iX, aMessage.iParameter.iExtent.iBr.iY);
       
   113 	TRect rectSrc(srcTopLeft, srcBottomRight);
       
   114 	TRect rectRes;
       
   115 	TInt ret = iDisplayMapping->MapCoordinates(EApplicationSpace, rectSrc, ECompositionSpace, rectRes);
       
   116 	aUtils.ReplyBuf(&rectRes, sizeof(TRect));
       
   117 	aUtils.SetReply(ret);
       
   118 	}
       
   119 */
       
   120 TSurfaceId CScreenCaptureUtil::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride)
       
   121 	{
       
   122 	RSurfaceManager::TSurfaceCreationAttributesBuf bf;
       
   123 	RSurfaceManager::TSurfaceCreationAttributes& b = bf();
       
   124 	b.iSize.iWidth = aSize.iWidth;
       
   125 	b.iSize.iHeight = aSize.iHeight;
       
   126 	b.iBuffers = 1;				// number of buffers in the surface
       
   127 	b.iPixelFormat = aPixelFormat;
       
   128 	b.iStride = aStride;		// Number of bytes between start of one line and start of next
       
   129 	b.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
       
   130 	b.iAlignment = 4;			// alignment, 1,2,4,8 byte aligned
       
   131 	b.iContiguous=EFalse;
       
   132 	b.iMappable = ETrue;
       
   133 
       
   134 	TSurfaceId surface = TSurfaceId::CreateNullId();
       
   135 	User::LeaveIfError(iSurfaceManager.CreateSurface(bf, surface));
       
   136 	return surface;
       
   137 	}
       
   138 
       
   139 void CScreenCaptureUtil::CreateLocalSurfaceL()
       
   140 	{
       
   141 	TSize surfaceSize;
       
   142 	GetCompositionAreaSize(surfaceSize);
       
   143 	
       
   144 	if (!iLocalSurface.IsNull())
       
   145 		{
       
   146         RSurfaceManager::TInfoBuf infoBuf;
       
   147     	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   148         if ((KErrNone != iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)) || 
       
   149         	(info.iSize != surfaceSize))
       
   150             {
       
   151             iScene->UnregisterSurface(iLocalSurface);
       
   152     		iSurfaceManager.CloseSurface(iLocalSurface);
       
   153     		iLocalSurface = TSurfaceId::CreateNullId();
       
   154             }
       
   155 		}
       
   156 	
       
   157 	if (iLocalSurface.IsNull())
       
   158 		{
       
   159 		iLocalSurface = CreateSurfaceL(surfaceSize, KSurfacePixelFormat, KSurfaceBytesPerPixel*surfaceSize.iWidth);
       
   160 		}
       
   161 	}
       
   162 
       
   163 TBool CScreenCaptureUtil::VerifyBitmapFormatL(const CFbsBitmap& aBitmap)
       
   164 	{
       
   165   RSurfaceManager::TInfoBuf infoBuf;
       
   166 	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   167   User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf));
       
   168     		
       
   169 	return ((info.iSize == aBitmap.SizeInPixels()) && (EColor16MU == aBitmap.DisplayMode()));
       
   170 	}
       
   171 
       
   172 void CScreenCaptureUtil::GetCompositionAreaSize(TSize& aSize) const
       
   173 	{
       
   174 	TSize uiSize;
       
   175 	uiSize = iScreenDevice->SizeInPixels();
       
   176 	TRect uiRect(TPoint(0,0), uiSize);
       
   177 	TRect compositionRect;
       
   178 	iDisplayMapping->MapCoordinates(EFullScreenSpace, uiRect, ECompositionSpace, compositionRect);
       
   179 	aSize = compositionRect.Size();
       
   180 	}
       
   181 
       
   182 TInt CScreenCaptureUtil::CopySurfaceToBitmapL(CFbsBitmap& aCopyToBitmap)
       
   183 	{
       
   184 	RSurfaceManager::TInfoBuf infoBuf;
       
   185 	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   186 
       
   187 	User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf));
       
   188 	
       
   189 	TInt bytesPerPixel=0;
       
   190 	TDisplayMode	bitmapMode = ENone;
       
   191 	
       
   192 	switch (info.iPixelFormat)
       
   193 		{
       
   194 		case EUidPixelFormatXRGB_8888:
       
   195 			{
       
   196 			bitmapMode = EColor16MU;
       
   197 			bytesPerPixel = 4;
       
   198 			break;
       
   199 			}
       
   200 		default:
       
   201 			{
       
   202 			return KErrCorrupt;
       
   203 			}
       
   204 		}
       
   205 	
       
   206 	if ((aCopyToBitmap.SizeInPixels() != info.iSize) || (aCopyToBitmap.DisplayMode() != bitmapMode))
       
   207 		{
       
   208 		return KErrCorrupt;
       
   209 		}
       
   210 	
       
   211 	RChunk chunk;
       
   212 	CleanupClosePushL(chunk);
       
   213 	User::LeaveIfError(iSurfaceManager.MapSurface(iLocalSurface, chunk));
       
   214 	TUint8* surfacePtr = chunk.Base();
       
   215 	TUint8* bitmapPtr = (TUint8*)aCopyToBitmap.DataAddress();
       
   216 	TInt copyBytes=info.iSize.iWidth*bytesPerPixel;
       
   217 	for (TInt y=0; y<info.iSize.iHeight; y++)
       
   218 		{
       
   219 		Mem::Copy(bitmapPtr,surfacePtr,copyBytes);
       
   220 		surfacePtr += info.iStride;
       
   221 		bitmapPtr += aCopyToBitmap.DataStride();
       
   222 		}
       
   223 	CleanupStack::PopAndDestroy(&chunk);
       
   224 	return KErrNone;
       
   225 	}