|
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 /** |
|
17 @file |
|
18 */ |
|
19 |
|
20 #include "wsgcedebugsession.h" |
|
21 |
|
22 RWsDebugSession::RWsDebugSession(TInt aScreenNo /*= -1*/): |
|
23 iScreenNo(aScreenNo), |
|
24 iSurfaceUpdateSerial(-1) |
|
25 { |
|
26 iSurfaceListBuffer.CreateMax(48); |
|
27 } |
|
28 |
|
29 RWsDebugSession::~RWsDebugSession() |
|
30 { |
|
31 iSurfaceListBuffer.Close(); |
|
32 |
|
33 } |
|
34 |
|
35 TBool RWsDebugSession::ResetUpdated() |
|
36 { |
|
37 TInt surfaceUpdateSerial=DebugInfo(EWsDebugSerialSurfacesUpdated,iScreenNo); |
|
38 TBool retVal=(iSurfaceUpdateSerial!=surfaceUpdateSerial); |
|
39 iSurfaceUpdateSerial=surfaceUpdateSerial; |
|
40 return retVal; |
|
41 } |
|
42 |
|
43 TInt RWsDebugSession::ResetUpdatedAndGetSurfaceWindowList(const TWsDebugWindowId * & aWinList) |
|
44 { |
|
45 iSurfaceUpdateSerial=DebugInfo(EWsDebugSerialSurfacesUpdated,iScreenNo); |
|
46 TInt reqSize=DebugInfo(EWsDebugSurfaceWindowList,iSurfaceListBuffer,iScreenNo); |
|
47 while (reqSize>iSurfaceListBuffer.MaxLength()) |
|
48 { |
|
49 iSurfaceListBuffer.Close(); |
|
50 iSurfaceListBuffer.CreateMax(reqSize); |
|
51 iSurfaceUpdateSerial=DebugInfo(EWsDebugSerialSurfacesUpdated,iScreenNo); |
|
52 reqSize=DebugInfo(EWsDebugSurfaceWindowList,iSurfaceListBuffer,iScreenNo); |
|
53 } |
|
54 if (reqSize==KErrCancel) |
|
55 { |
|
56 aWinList=NULL; |
|
57 return 0; |
|
58 } |
|
59 else |
|
60 { |
|
61 aWinList=(TWsDebugWindowId*)iSurfaceListBuffer.Ptr(); |
|
62 return reqSize/sizeof(TWsDebugWindowId); |
|
63 } |
|
64 } |
|
65 /** |
|
66 * Stream data into the provided buffer and point the return object pointer to it. |
|
67 * The pointer is left null if the method returns an error code or the buffer is too small. |
|
68 * The ret5urn code reports |
|
69 * |
|
70 **/ |
|
71 TInt RWsDebugSession::DebugInfo(TWsDebugInfoFunc aFunction, TInt aParam, TDes8& aHostBuffer,const void*&aReturnedObject,TInt aObjectSize)const |
|
72 { |
|
73 aHostBuffer.SetMax(); |
|
74 TInt reqSize=DebugInfo(aFunction,aHostBuffer,aParam); |
|
75 aReturnedObject=NULL; |
|
76 if (reqSize<0) |
|
77 { |
|
78 return reqSize; //Error code is transmitted unmolested |
|
79 } |
|
80 if (reqSize==0) //Size 0 is transformed to max |
|
81 reqSize=aHostBuffer.MaxLength(); |
|
82 if ((reqSize%aObjectSize)!=0) |
|
83 { //Size not multiple of object --> error |
|
84 return KErrCorrupt; |
|
85 } |
|
86 if (reqSize<=aHostBuffer.MaxLength()) |
|
87 { //Pointer is only set if data fits buffer |
|
88 aReturnedObject=(const void*)aHostBuffer.Ptr(); |
|
89 } |
|
90 reqSize/=aObjectSize; //Return the exact number of objects filled |
|
91 return reqSize; |
|
92 } |
|
93 /** |
|
94 * Stream the reply data via the buffer associated with the region. |
|
95 * Some protected accessor optimisation used to manage the reported size of the region after streaming. |
|
96 * |
|
97 **/ |
|
98 TInt RWsDebugSession::DebugInfo(TWsDebugInfoFunc aFunction, TInt aParam, TRegion& aPreAllocatedReturnedRegion)const |
|
99 { |
|
100 //Attempt to fit the received data in the preexisting region buffer... |
|
101 class XRegion:public TRegion |
|
102 { |
|
103 public: |
|
104 using TRegion::AppendRect; |
|
105 // using TRegion::SetListSize; |
|
106 using TRegion::RectangleListW; |
|
107 TInt MaxSize() |
|
108 { return iAllocedRects; } |
|
109 void SetListSize(TInt aNewSize) //DANGER no error checking!!! |
|
110 { iCount=aNewSize; } |
|
111 }& preAllocatedReturnedRegion=(XRegion&)aPreAllocatedReturnedRegion; |
|
112 typedef TRect TElt; |
|
113 TInt reqSize=preAllocatedReturnedRegion.MaxSize(); |
|
114 const TElt* elements=preAllocatedReturnedRegion.RectangleListW(); |
|
115 TInt lenBytes=reqSize*sizeof(TElt); |
|
116 TPtr8 pBuff((TUint8*)elements,lenBytes,lenBytes); |
|
117 reqSize=DebugInfo(aFunction,aParam,pBuff,elements); |
|
118 |
|
119 if (elements) |
|
120 { |
|
121 if (reqSize==0) |
|
122 { |
|
123 reqSize=preAllocatedReturnedRegion.MaxSize(); |
|
124 } |
|
125 preAllocatedReturnedRegion.SetListSize(reqSize); |
|
126 return reqSize; |
|
127 } |
|
128 //If data does not fit in preexisting buffer |
|
129 //Use a temp array instead |
|
130 //Still try to block copy into the existing capacity |
|
131 //I think this use of region copy is more efficient than appending, |
|
132 //and definitely better than unioning the elements. |
|
133 if (reqSize>=0) |
|
134 { |
|
135 TInt breakLoop=10; |
|
136 do { |
|
137 TElt* tempbuff=new TElt[reqSize]; |
|
138 if (tempbuff==NULL) |
|
139 { |
|
140 reqSize=KErrNoMemory; |
|
141 break; |
|
142 } |
|
143 elements=tempbuff; |
|
144 TInt lenBytes=reqSize*sizeof(TElt); |
|
145 TPtr8 pBuff((TUint8*)elements,lenBytes,lenBytes); |
|
146 TInt reqSize2=DebugInfo(aFunction,aParam,pBuff,elements); |
|
147 if (reqSize2!=0) |
|
148 reqSize=reqSize2; |
|
149 if (elements) |
|
150 { |
|
151 RRegion r(reqSize,tempbuff); //note this region does not own its memory so should not be closed! |
|
152 aPreAllocatedReturnedRegion.Copy(r); |
|
153 if (aPreAllocatedReturnedRegion.CheckError()) |
|
154 reqSize=KErrNoMemory; |
|
155 } |
|
156 delete[] tempbuff; |
|
157 }while (reqSize>0 && elements==NULL && --breakLoop); |
|
158 } |
|
159 if (reqSize>=0 && elements==NULL) |
|
160 { |
|
161 preAllocatedReturnedRegion.ForceError(); |
|
162 reqSize=KErrTimedOut; |
|
163 } |
|
164 if (reqSize<0) |
|
165 { |
|
166 if (reqSize==KErrCancel) |
|
167 { |
|
168 preAllocatedReturnedRegion.Clear(); |
|
169 } |
|
170 else |
|
171 { |
|
172 preAllocatedReturnedRegion.ForceError(); |
|
173 } |
|
174 |
|
175 } |
|
176 return reqSize; |
|
177 } |