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