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