1 /* |
|
2 * ============================================================================== |
|
3 * Name : %name: previewprovidercrp.cpp % |
|
4 * Part of : Hg fast swap preview provider plugin |
|
5 * Description : Preview provider ECOM plugin |
|
6 * Version : %version: sa1spcx1#8 % |
|
7 * |
|
8 * Copyright (c) 2008 Nokia Corporation. |
|
9 * This material, including documentation and any related |
|
10 * computer programs, is protected by copyright controlled by |
|
11 * Nokia Corporation. All rights are reserved. Copying, |
|
12 * including reproducing, storing, adapting or translating, any |
|
13 * or all of this material requires the prior written consent of |
|
14 * Nokia Corporation. This material also contains confidential |
|
15 * information which may not be disclosed to others without the |
|
16 * prior written consent of Nokia Corporation. |
|
17 * ============================================================================== |
|
18 */ |
|
19 |
|
20 #include <bldvariant.hrh> |
|
21 #ifdef SYMBIAN_BUILD_GCE |
|
22 #define NGA |
|
23 #endif |
|
24 |
|
25 #include "previewprovidercrp.h" |
|
26 #include "previewmsg.h" |
|
27 #include "previewprovidercrplogging.h" |
|
28 #include <ecom/implementationproxy.h> |
|
29 #include <s32mem.h> //RDesReadStream |
|
30 |
|
31 #ifdef NGA |
|
32 #include <graphics/wsscreendevice.h> |
|
33 #endif |
|
34 |
|
35 // CONSTANTS |
|
36 const TInt KImpId( 0x20016BEC ); |
|
37 |
|
38 // -------------------------------------------------------------------------- |
|
39 // CPreviewProviderCRP::CreateL |
|
40 // -------------------------------------------------------------------------- |
|
41 // |
|
42 CWsGraphicDrawer* CPreviewProviderCRP::CreateL() |
|
43 { |
|
44 CPreviewProviderCRP* crp = new (ELeave) CPreviewProviderCRP(); |
|
45 CleanupStack::PushL( crp ); |
|
46 crp->ConstructL(); |
|
47 CleanupStack::Pop( crp ); |
|
48 return crp; |
|
49 } |
|
50 |
|
51 // -------------------------------------------------------------------------- |
|
52 // CPreviewProviderCRP::ConstructL |
|
53 // -------------------------------------------------------------------------- |
|
54 // |
|
55 void CPreviewProviderCRP::ConstructL() |
|
56 { |
|
57 } |
|
58 |
|
59 // -------------------------------------------------------------------------- |
|
60 // CPreviewProviderCRP::~CPreviewProviderCRP |
|
61 // -------------------------------------------------------------------------- |
|
62 // |
|
63 CPreviewProviderCRP::~CPreviewProviderCRP() |
|
64 { |
|
65 Env().UnregisterEventHandler( this ); |
|
66 iScreenshots.ResetAndDestroy(); |
|
67 iWgIds.Close(); |
|
68 } |
|
69 |
|
70 // -------------------------------------------------------------------------- |
|
71 // CPreviewProviderCRP::DoDraw |
|
72 // -------------------------------------------------------------------------- |
|
73 // |
|
74 void CPreviewProviderCRP::DoDraw( MWsGc& /*aGc*/, const TRect& /*aRect*/, |
|
75 const TDesC8& /*aData*/) const |
|
76 { |
|
77 //draws nothing |
|
78 } |
|
79 |
|
80 // -------------------------------------------------------------------------- |
|
81 // CPreviewProviderCRP::HandleMessage |
|
82 // -------------------------------------------------------------------------- |
|
83 // |
|
84 void CPreviewProviderCRP::HandleMessage( const TDesC8& aData ) |
|
85 { |
|
86 TRAP_IGNORE( DoHandleMessageL( aData ) ); |
|
87 } |
|
88 |
|
89 // -------------------------------------------------------------------------- |
|
90 // CPreviewProviderCRP::DoHandleMessageL |
|
91 // -------------------------------------------------------------------------- |
|
92 // |
|
93 void CPreviewProviderCRP::DoHandleMessageL( const TDesC8& aData ) |
|
94 { |
|
95 HGLOG_CONTEXT( DoHandleMessageL, HGLOG_LOCAL ); |
|
96 HGLOG_IN(); |
|
97 |
|
98 RDesReadStream in( aData ); |
|
99 switch( in.ReadInt32L() ) |
|
100 { |
|
101 case NPreviewMsg::ERegister: |
|
102 { |
|
103 const TInt id = in.ReadInt32L(); |
|
104 Register( id ); |
|
105 } |
|
106 break; |
|
107 case NPreviewMsg::EUnregister: |
|
108 { |
|
109 const TInt id = in.ReadInt32L(); |
|
110 Unregister( id ); |
|
111 } |
|
112 break; |
|
113 case NPreviewMsg::EChangeScreen: |
|
114 { |
|
115 const TInt screen = in.ReadInt32L(); |
|
116 if ( Env().ScreenCount() ) |
|
117 { |
|
118 iScreen = screen; |
|
119 } |
|
120 } |
|
121 break; |
|
122 case NPreviewMsg::ESetPreviewParam: |
|
123 iScreenshotSize.iWidth = in.ReadInt32L(); |
|
124 iScreenshotSize.iHeight = in.ReadInt32L(); |
|
125 iScreenshotMode = static_cast<TDisplayMode>( in.ReadInt32L() ); |
|
126 break; |
|
127 case NPreviewMsg::ETakePreview: |
|
128 ScreenshotL(); |
|
129 break; |
|
130 case NPreviewMsg::EAckPreviewReady: |
|
131 RemoveScreenshot( in.ReadInt32L() ); |
|
132 break; |
|
133 } |
|
134 |
|
135 HGLOG_OUT(); |
|
136 } |
|
137 |
|
138 // -------------------------------------------------------------------------- |
|
139 // CPreviewProviderCRP::ConstructL |
|
140 // -------------------------------------------------------------------------- |
|
141 // |
|
142 void CPreviewProviderCRP::ConstructL( MWsGraphicDrawerEnvironment& aEnv, |
|
143 const TGraphicDrawerId& aId, MWsClient& aOwner, const TDesC8& /*aData*/ ) |
|
144 { |
|
145 HGLOG_CONTEXT( ConstructL, HGLOG_LOCAL ); |
|
146 HGLOG_IN(); |
|
147 |
|
148 BaseConstructL( aEnv, aId, aOwner ); |
|
149 aEnv.RegisterEventHandler( this, this, TWservCrEvent::EWindowGroupChanged ); |
|
150 |
|
151 HGLOG_OUT(); |
|
152 } |
|
153 |
|
154 // -------------------------------------------------------------------------- |
|
155 // CPreviewProviderCRP::DoHandleEvent |
|
156 // -------------------------------------------------------------------------- |
|
157 // |
|
158 void CPreviewProviderCRP::DoHandleEvent( const TWservCrEvent& aEvent ) |
|
159 { |
|
160 HGLOG_CONTEXT( DoHandleEvent, HGLOG_LOCAL ); |
|
161 HGLOG_IN(); |
|
162 |
|
163 if ( aEvent.Type() == TWservCrEvent::EWindowGroupChanged ) |
|
164 { |
|
165 const TInt wgId = aEvent.WindowGroupIdentifier(); |
|
166 if ( iWgIds.FindInOrder( iPrevId ) >= 0 || |
|
167 ( iPrevId == 0 && iPrevReg != 0 ) ) |
|
168 { |
|
169 TRAP_IGNORE( ScreenshotL() ); |
|
170 iPrevReg = 0; |
|
171 } |
|
172 iPrevId = wgId; |
|
173 } |
|
174 |
|
175 HGLOG_OUT(); |
|
176 } |
|
177 |
|
178 // -------------------------------------------------------------------------- |
|
179 // CPreviewProviderCRP::ScaleComplete |
|
180 // -------------------------------------------------------------------------- |
|
181 // |
|
182 void CPreviewProviderCRP::ScaleCompleteL( const CFbsBitmap& aBitmap ) |
|
183 { |
|
184 HGLOG_CONTEXT( ScaleComplete, HGLOG_LOCAL ); |
|
185 HGLOG_IN(); |
|
186 |
|
187 const TInt msg[] = { |
|
188 NPreviewMsg::EPreviewReady, |
|
189 iPrevId?iPrevId:iPrevReg, |
|
190 aBitmap.Handle() |
|
191 }; |
|
192 TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg); |
|
193 User::LeaveIfError( SendMessage( buf ) ); |
|
194 HGLOG3( HGLOG_INFO, "size = %dx%d handle = %d", |
|
195 aBitmap.SizeInPixels().iWidth, |
|
196 aBitmap.SizeInPixels().iHeight, |
|
197 aBitmap.Handle() ); |
|
198 HGLOG_OUT(); |
|
199 } |
|
200 |
|
201 // -------------------------------------------------------------------------- |
|
202 // CPreviewProviderCRP::UnregisterComplete |
|
203 // -------------------------------------------------------------------------- |
|
204 // |
|
205 void CPreviewProviderCRP::UnregisterComplete( TInt aWgId ) |
|
206 { |
|
207 HGLOG_CONTEXT( UnregisterComplete, HGLOG_LOCAL ); |
|
208 HGLOG_IN(); |
|
209 |
|
210 const TInt msg[] = { |
|
211 NPreviewMsg::EUnregisterReady, |
|
212 aWgId, |
|
213 0 |
|
214 }; |
|
215 TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg); |
|
216 SendMessage(buf); |
|
217 |
|
218 HGLOG_OUT(); |
|
219 } |
|
220 |
|
221 // -------------------------------------------------------------------------- |
|
222 // CPreviewProviderCRP::Register |
|
223 // -------------------------------------------------------------------------- |
|
224 // |
|
225 void CPreviewProviderCRP::Register( TInt aWgId ) |
|
226 { |
|
227 HGLOG_CONTEXT( Register, HGLOG_LOCAL ); |
|
228 HGLOG_IN(); |
|
229 |
|
230 iPrevReg = aWgId; |
|
231 iWgIds.InsertInOrder( aWgId ); |
|
232 |
|
233 HGLOG_OUT(); |
|
234 } |
|
235 |
|
236 // -------------------------------------------------------------------------- |
|
237 // CPreviewProviderCRP::Unregister |
|
238 // -------------------------------------------------------------------------- |
|
239 // |
|
240 void CPreviewProviderCRP::Unregister( TInt aWgId ) |
|
241 { |
|
242 HGLOG_CONTEXT( Unregister, HGLOG_LOCAL ); |
|
243 HGLOG_IN(); |
|
244 |
|
245 const TInt index = iWgIds.FindInOrder( aWgId ); |
|
246 if ( index >= 0 ) |
|
247 { |
|
248 iWgIds.Remove( index ); |
|
249 } |
|
250 |
|
251 UnregisterComplete( aWgId ); |
|
252 |
|
253 HGLOG_OUT(); |
|
254 } |
|
255 |
|
256 // -------------------------------------------------------------------------- |
|
257 // CPreviewProviderCRP::ScreenShotL |
|
258 // -------------------------------------------------------------------------- |
|
259 // |
|
260 void CPreviewProviderCRP::ScreenshotL() |
|
261 { |
|
262 CFbsBitmap* screenshot = new (ELeave)CFbsBitmap(); |
|
263 CleanupStack::PushL( screenshot ); |
|
264 ScreenshotL( *screenshot ); |
|
265 ScaleCompleteL( *screenshot ); |
|
266 iScreenshots.InsertL( screenshot, iScreenshots.Count() ); |
|
267 CleanupStack::Pop( screenshot ); |
|
268 CheckOverflow(); |
|
269 } |
|
270 |
|
271 // -------------------------------------------------------------------------- |
|
272 // CPreviewProviderCRP::ScreenShotL |
|
273 // -------------------------------------------------------------------------- |
|
274 // |
|
275 void CPreviewProviderCRP::ScreenshotL(CFbsBitmap& aBitmap) |
|
276 { |
|
277 HGLOG_CONTEXT( ScreenShot, HGLOG_LOCAL ); |
|
278 HGLOG_IN(); |
|
279 |
|
280 if( 0 > iScreen || Env().ScreenCount() <= iScreen ) |
|
281 { |
|
282 //screen offset out of range. skip request |
|
283 User::Leave(KErrArgument); |
|
284 } |
|
285 // Find the screen resolution |
|
286 MWsScreenConfig* screenConfig = |
|
287 Env().Screen( iScreen )->ObjectInterface<MWsScreenConfig>(); |
|
288 |
|
289 const TSize sz = screenConfig->ScreenModeSizeInPixels(); |
|
290 |
|
291 // Get the screen buffer (containing screenshot data) |
|
292 MWsFrontBuffer* screenFront = |
|
293 Env().Screen( iScreen )->ObjectInterface<MWsFrontBuffer>(); |
|
294 |
|
295 // With NGA we do not support downscaling of the screenshots. |
|
296 // So use the size of the screen if no screenshot size has been explicitly |
|
297 // set or if the old method for taking screenshots is not available. |
|
298 if ( iScreenshotSize.iWidth == 0 || |
|
299 iScreenshotSize.iHeight == 0 || |
|
300 !screenFront ) |
|
301 { |
|
302 iScreenshotSize = sz; |
|
303 } |
|
304 // Use the the same DisplayMode as for the source image |
|
305 // so override the display mode, ignoring any requests. |
|
306 iScreenshotMode = screenConfig->DisplayMode(); |
|
307 |
|
308 HGLOG3( HGLOG_INFO, "iShotSize: %dx%d mode: %d", |
|
309 iScreenshotSize.iWidth, iScreenshotSize.iHeight, iScreenshotMode ); |
|
310 |
|
311 aBitmap.Reset(); |
|
312 User::LeaveIfError( aBitmap.Create( iScreenshotSize, iScreenshotMode ) ); |
|
313 |
|
314 // Check if front buffer is available. |
|
315 // Will always be NULL with NGA. |
|
316 if ( screenFront ) |
|
317 { |
|
318 HGLOG0( HGLOG_INFO, "non-NGA, using front buffer" ); |
|
319 FrontBufferScreenShot( aBitmap, *screenFront, sz, screenConfig->Stride() ); |
|
320 } |
|
321 #ifdef NGA |
|
322 else |
|
323 { |
|
324 HGLOG0( HGLOG_INFO, "NGA, using CopyScreenToBitmapL" ); |
|
325 MWsScreenDevice* screenDevice = static_cast<MWsScreenDevice*>( |
|
326 Env().Screen( iScreen )->ResolveObjectInterface( |
|
327 MWsScreenDevice::EWsObjectInterfaceId ) ); |
|
328 User::LeaveIfNull( screenDevice ); |
|
329 screenDevice->CopyScreenToBitmapL( &aBitmap, iScreenshotSize ); |
|
330 } |
|
331 #endif |
|
332 HGLOG_OUT(); |
|
333 } |
|
334 |
|
335 // -------------------------------------------------------------------------- |
|
336 // CPreviewProviderCRP::RemoveShot |
|
337 // -------------------------------------------------------------------------- |
|
338 // |
|
339 void CPreviewProviderCRP::RemoveScreenshot( TInt aBitmapHandle ) |
|
340 { |
|
341 for( int iter(0); iter < iScreenshots.Count(); ++iter ) |
|
342 { |
|
343 if( iScreenshots[iter]->Handle() == aBitmapHandle ) |
|
344 { |
|
345 delete iScreenshots[iter]; |
|
346 iScreenshots.Remove(iter); |
|
347 break; |
|
348 } |
|
349 } |
|
350 } |
|
351 |
|
352 // -------------------------------------------------------------------------- |
|
353 // CPreviewProviderCRP::CheckOverflow |
|
354 // -------------------------------------------------------------------------- |
|
355 // |
|
356 void CPreviewProviderCRP::CheckOverflow() |
|
357 { |
|
358 TInt overflow( iScreenshots.Count() - KMaxShots); |
|
359 while( 0 < overflow-- ) |
|
360 { |
|
361 delete iScreenshots[0]; |
|
362 iScreenshots.Remove(0); |
|
363 } |
|
364 } |
|
365 |
|
366 // -------------------------------------------------------------------------- |
|
367 // CPreviewProviderCRP::FrontBufferScreenShot |
|
368 // -------------------------------------------------------------------------- |
|
369 // |
|
370 void CPreviewProviderCRP::FrontBufferScreenShot( CFbsBitmap& aBitmap, |
|
371 MWsFrontBuffer& aFront, |
|
372 const TSize& aSrcSize, |
|
373 TInt aSrcStride ) |
|
374 { |
|
375 HGLOG_CONTEXT( CPreviewProviderCRP::FrontBufferScreenShot, HGLOG_LOCAL ); |
|
376 HGLOG_IN(); |
|
377 |
|
378 const TUint8* src = static_cast<const TUint8*> ( aFront.GetBits() ); |
|
379 HGLOG1( HGLOG_INFO, "src address = [%d]", src ); |
|
380 |
|
381 TInt srcstride( aSrcStride ); |
|
382 TInt srcwidth( aSrcSize.iWidth ); |
|
383 TInt srcheight( aSrcSize.iHeight ); |
|
384 TInt dststride( aBitmap.DataStride() ); |
|
385 TInt dstheight( iScreenshotSize.iHeight ); |
|
386 TInt dstwidth( iScreenshotSize.iWidth ); |
|
387 TInt stepdst( dststride / dstwidth ); |
|
388 TInt stepsrc( srcstride / srcwidth ); |
|
389 // scale must be TInt type |
|
390 TInt scaleX( aSrcSize.iWidth / iScreenshotSize.iWidth ); |
|
391 TInt scaleY( aSrcSize.iHeight / iScreenshotSize.iHeight ); |
|
392 |
|
393 aBitmap.LockHeap(); |
|
394 |
|
395 TUint8* dst = ( TUint8* ) aBitmap.DataAddress(); |
|
396 |
|
397 TInt minWidth = Min( srcwidth, dstwidth ); |
|
398 TInt minHeight = Min( srcheight, dstheight ); |
|
399 TInt minStep = Min( stepsrc, stepdst ); |
|
400 |
|
401 for ( TInt y = minHeight; y > 0; y-- ) |
|
402 { |
|
403 for ( TInt x = minWidth; x > 0; x-- ) |
|
404 { |
|
405 Mem::Copy( dst, src, minStep ); |
|
406 dst += stepdst; |
|
407 src += scaleX*stepdst; |
|
408 } |
|
409 src += srcstride - scaleX * stepdst * minWidth; |
|
410 src += ( scaleY - 1 ) * srcstride; |
|
411 } |
|
412 |
|
413 aBitmap.UnlockHeap(); |
|
414 HGLOG_OUT(); |
|
415 } |
|
416 |
|
417 // -------------------------------------------------------------------------- |
|
418 // KImplementationTable |
|
419 // -------------------------------------------------------------------------- |
|
420 // |
|
421 LOCAL_C const TImplementationProxy KImplementationTable[] = |
|
422 { |
|
423 IMPLEMENTATION_PROXY_ENTRY(KImpId, CPreviewProviderCRP::CreateL) |
|
424 }; |
|
425 |
|
426 // -------------------------------------------------------------------------- |
|
427 // ImplementationGroupProxy |
|
428 // -------------------------------------------------------------------------- |
|
429 // |
|
430 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) |
|
431 { |
|
432 aTableCount = (sizeof(KImplementationTable) / sizeof(TImplementationProxy)); |
|
433 return KImplementationTable; |
|
434 } |
|
435 |
|
436 |
|
437 // End of file |
|