sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include "wsgcedebugsession.h" sl@0: sl@0: RWsDebugSession::RWsDebugSession(TInt aScreenNo /*= -1*/): sl@0: iScreenNo(aScreenNo), sl@0: iSurfaceUpdateSerial(-1) sl@0: { sl@0: iSurfaceListBuffer.CreateMax(48); sl@0: } sl@0: sl@0: RWsDebugSession::~RWsDebugSession() sl@0: { sl@0: iSurfaceListBuffer.Close(); sl@0: sl@0: } sl@0: sl@0: TBool RWsDebugSession::ResetUpdated() sl@0: { sl@0: TInt surfaceUpdateSerial=DebugInfo(EWsDebugSerialSurfacesUpdated,iScreenNo); sl@0: TBool retVal=(iSurfaceUpdateSerial!=surfaceUpdateSerial); sl@0: iSurfaceUpdateSerial=surfaceUpdateSerial; sl@0: return retVal; sl@0: } sl@0: sl@0: TInt RWsDebugSession::ResetUpdatedAndGetSurfaceWindowList(const TWsDebugWindowId * & aWinList) sl@0: { sl@0: iSurfaceUpdateSerial=DebugInfo(EWsDebugSerialSurfacesUpdated,iScreenNo); sl@0: TInt reqSize=DebugInfo(EWsDebugSurfaceWindowList,iSurfaceListBuffer,iScreenNo); sl@0: while (reqSize>iSurfaceListBuffer.MaxLength()) sl@0: { sl@0: iSurfaceListBuffer.Close(); sl@0: iSurfaceListBuffer.CreateMax(reqSize); sl@0: iSurfaceUpdateSerial=DebugInfo(EWsDebugSerialSurfacesUpdated,iScreenNo); sl@0: reqSize=DebugInfo(EWsDebugSurfaceWindowList,iSurfaceListBuffer,iScreenNo); sl@0: } sl@0: if (reqSize==KErrCancel) sl@0: { sl@0: aWinList=NULL; sl@0: return 0; sl@0: } sl@0: else sl@0: { sl@0: aWinList=(TWsDebugWindowId*)iSurfaceListBuffer.Ptr(); sl@0: return reqSize/sizeof(TWsDebugWindowId); sl@0: } sl@0: } sl@0: /** sl@0: * Stream data into the provided buffer and point the return object pointer to it. sl@0: * The pointer is left null if the method returns an error code or the buffer is too small. sl@0: * The ret5urn code reports sl@0: * sl@0: **/ sl@0: TInt RWsDebugSession::DebugInfo(TWsDebugInfoFunc aFunction, TInt aParam, TDes8& aHostBuffer,const void*&aReturnedObject,TInt aObjectSize)const sl@0: { sl@0: aHostBuffer.SetMax(); sl@0: TInt reqSize=DebugInfo(aFunction,aHostBuffer,aParam); sl@0: aReturnedObject=NULL; sl@0: if (reqSize<0) sl@0: { sl@0: return reqSize; //Error code is transmitted unmolested sl@0: } sl@0: if (reqSize==0) //Size 0 is transformed to max sl@0: reqSize=aHostBuffer.MaxLength(); sl@0: if ((reqSize%aObjectSize)!=0) sl@0: { //Size not multiple of object --> error sl@0: return KErrCorrupt; sl@0: } sl@0: if (reqSize<=aHostBuffer.MaxLength()) sl@0: { //Pointer is only set if data fits buffer sl@0: aReturnedObject=(const void*)aHostBuffer.Ptr(); sl@0: } sl@0: reqSize/=aObjectSize; //Return the exact number of objects filled sl@0: return reqSize; sl@0: } sl@0: /** sl@0: * Stream the reply data via the buffer associated with the region. sl@0: * Some protected accessor optimisation used to manage the reported size of the region after streaming. sl@0: * sl@0: **/ sl@0: TInt RWsDebugSession::DebugInfo(TWsDebugInfoFunc aFunction, TInt aParam, TRegion& aPreAllocatedReturnedRegion)const sl@0: { sl@0: //Attempt to fit the received data in the preexisting region buffer... sl@0: class XRegion:public TRegion sl@0: { sl@0: public: sl@0: using TRegion::AppendRect; sl@0: // using TRegion::SetListSize; sl@0: using TRegion::RectangleListW; sl@0: TInt MaxSize() sl@0: { return iAllocedRects; } sl@0: void SetListSize(TInt aNewSize) //DANGER no error checking!!! sl@0: { iCount=aNewSize; } sl@0: }& preAllocatedReturnedRegion=(XRegion&)aPreAllocatedReturnedRegion; sl@0: typedef TRect TElt; sl@0: TInt reqSize=preAllocatedReturnedRegion.MaxSize(); sl@0: const TElt* elements=preAllocatedReturnedRegion.RectangleListW(); sl@0: TInt lenBytes=reqSize*sizeof(TElt); sl@0: TPtr8 pBuff((TUint8*)elements,lenBytes,lenBytes); sl@0: reqSize=DebugInfo(aFunction,aParam,pBuff,elements); sl@0: sl@0: if (elements) sl@0: { sl@0: if (reqSize==0) sl@0: { sl@0: reqSize=preAllocatedReturnedRegion.MaxSize(); sl@0: } sl@0: preAllocatedReturnedRegion.SetListSize(reqSize); sl@0: return reqSize; sl@0: } sl@0: //If data does not fit in preexisting buffer sl@0: //Use a temp array instead sl@0: //Still try to block copy into the existing capacity sl@0: //I think this use of region copy is more efficient than appending, sl@0: //and definitely better than unioning the elements. sl@0: if (reqSize>=0) sl@0: { sl@0: TInt breakLoop=10; sl@0: do { sl@0: TElt* tempbuff=new TElt[reqSize]; sl@0: if (tempbuff==NULL) sl@0: { sl@0: reqSize=KErrNoMemory; sl@0: break; sl@0: } sl@0: elements=tempbuff; sl@0: TInt lenBytes=reqSize*sizeof(TElt); sl@0: TPtr8 pBuff((TUint8*)elements,lenBytes,lenBytes); sl@0: TInt reqSize2=DebugInfo(aFunction,aParam,pBuff,elements); sl@0: if (reqSize2!=0) sl@0: reqSize=reqSize2; sl@0: if (elements) sl@0: { sl@0: RRegion r(reqSize,tempbuff); //note this region does not own its memory so should not be closed! sl@0: aPreAllocatedReturnedRegion.Copy(r); sl@0: if (aPreAllocatedReturnedRegion.CheckError()) sl@0: reqSize=KErrNoMemory; sl@0: } sl@0: delete[] tempbuff; sl@0: }while (reqSize>0 && elements==NULL && --breakLoop); sl@0: } sl@0: if (reqSize>=0 && elements==NULL) sl@0: { sl@0: preAllocatedReturnedRegion.ForceError(); sl@0: reqSize=KErrTimedOut; sl@0: } sl@0: if (reqSize<0) sl@0: { sl@0: if (reqSize==KErrCancel) sl@0: { sl@0: preAllocatedReturnedRegion.Clear(); sl@0: } sl@0: else sl@0: { sl@0: preAllocatedReturnedRegion.ForceError(); sl@0: } sl@0: sl@0: } sl@0: return reqSize; sl@0: }