|
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 const TInt KMinTimeForOrientationSwitch = 1; // 1 second |
|
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 iLastWgIdRedraw = ETrue; |
|
58 } |
|
59 |
|
60 // -------------------------------------------------------------------------- |
|
61 // CPreviewProviderCRP::~CPreviewProviderCRP |
|
62 // -------------------------------------------------------------------------- |
|
63 // |
|
64 CPreviewProviderCRP::~CPreviewProviderCRP() |
|
65 { |
|
66 Env().UnregisterEventHandler( this ); |
|
67 iScreenshots.ResetAndDestroy(); |
|
68 iWgIds.Close(); |
|
69 } |
|
70 |
|
71 // -------------------------------------------------------------------------- |
|
72 // CPreviewProviderCRP::DoDraw |
|
73 // -------------------------------------------------------------------------- |
|
74 // |
|
75 void CPreviewProviderCRP::DoDraw( MWsGc& /*aGc*/, const TRect& /*aRect*/, |
|
76 const TDesC8& /*aData*/) const |
|
77 { |
|
78 //draws nothing |
|
79 } |
|
80 |
|
81 // -------------------------------------------------------------------------- |
|
82 // CPreviewProviderCRP::HandleMessage |
|
83 // -------------------------------------------------------------------------- |
|
84 // |
|
85 void CPreviewProviderCRP::HandleMessage( const TDesC8& aData ) |
|
86 { |
|
87 TRAP_IGNORE( DoHandleMessageL( aData ) ); |
|
88 } |
|
89 |
|
90 // -------------------------------------------------------------------------- |
|
91 // CPreviewProviderCRP::DoHandleMessageL |
|
92 // -------------------------------------------------------------------------- |
|
93 // |
|
94 void CPreviewProviderCRP::DoHandleMessageL( const TDesC8& aData ) |
|
95 { |
|
96 TSLOG_CONTEXT( DoHandleMessageL, TSLOG_LOCAL ); |
|
97 TSLOG_IN(); |
|
98 |
|
99 RDesReadStream in( aData ); |
|
100 switch( in.ReadInt32L() ) |
|
101 { |
|
102 case NPreviewMsg::ERegister: |
|
103 { |
|
104 const TInt id = in.ReadInt32L(); |
|
105 Register( id ); |
|
106 } |
|
107 break; |
|
108 case NPreviewMsg::EUnregister: |
|
109 { |
|
110 const TInt id = in.ReadInt32L(); |
|
111 Unregister( id ); |
|
112 } |
|
113 break; |
|
114 case NPreviewMsg::EChangeScreen: |
|
115 { |
|
116 const TInt screen = in.ReadInt32L(); |
|
117 if ( Env().ScreenCount() ) |
|
118 { |
|
119 iScreen = screen; |
|
120 } |
|
121 } |
|
122 break; |
|
123 case NPreviewMsg::ESetPreviewParam: |
|
124 iScreenshotSize.iWidth = in.ReadInt32L(); |
|
125 iScreenshotSize.iHeight = in.ReadInt32L(); |
|
126 iScreenshotMode = static_cast<TDisplayMode>( in.ReadInt32L() ); |
|
127 break; |
|
128 case NPreviewMsg::ETakePreview: |
|
129 ScreenshotL(); |
|
130 break; |
|
131 case NPreviewMsg::EAckPreviewReady: |
|
132 RemoveScreenshot( in.ReadInt32L() ); |
|
133 break; |
|
134 } |
|
135 |
|
136 TSLOG_OUT(); |
|
137 } |
|
138 |
|
139 // -------------------------------------------------------------------------- |
|
140 // CPreviewProviderCRP::ConstructL |
|
141 // -------------------------------------------------------------------------- |
|
142 // |
|
143 void CPreviewProviderCRP::ConstructL( MWsGraphicDrawerEnvironment& aEnv, |
|
144 const TGraphicDrawerId& aId, MWsClient& aOwner, const TDesC8& /*aData*/ ) |
|
145 { |
|
146 TSLOG_CONTEXT( ConstructL, TSLOG_LOCAL ); |
|
147 TSLOG_IN(); |
|
148 |
|
149 BaseConstructL( aEnv, aId, aOwner ); |
|
150 aEnv.RegisterEventHandler( this, this, TWservCrEvent::EWindowGroupChanged | |
|
151 TWservCrEvent::EDeviceOrientationChanged | |
|
152 TWservCrEvent::EScreenDrawing ); |
|
153 iScreenChangedTime = 0; |
|
154 |
|
155 TSLOG_OUT(); |
|
156 } |
|
157 |
|
158 // -------------------------------------------------------------------------- |
|
159 // CPreviewProviderCRP::DoHandleEvent |
|
160 // -------------------------------------------------------------------------- |
|
161 // |
|
162 void CPreviewProviderCRP::DoHandleEvent( const TWservCrEvent& aEvent ) |
|
163 { |
|
164 TSLOG_CONTEXT( DoHandleEvent, TSLOG_LOCAL ); |
|
165 TSLOG_IN(); |
|
166 |
|
167 if ( aEvent.Type() == TWservCrEvent::EWindowGroupChanged ) |
|
168 { |
|
169 const TInt wgId = aEvent.WindowGroupIdentifier(); |
|
170 if ( iWgIds.FindInOrder( iPrevId ) >= 0 || |
|
171 ( iPrevId == 0 && iPrevReg != 0 ) ) |
|
172 { |
|
173 TTime currTime; |
|
174 currTime.HomeTime(); |
|
175 TTimeIntervalSeconds secondsFrom; |
|
176 TInt err = currTime.SecondsFrom( iScreenChangedTime, secondsFrom ); |
|
177 if ( err != KErrNone || secondsFrom.Int() > KMinTimeForOrientationSwitch ) |
|
178 { |
|
179 if ( iLastWgIdRedraw ) |
|
180 { |
|
181 TRAP_IGNORE( ScreenshotL() ); |
|
182 } |
|
183 } |
|
184 else |
|
185 { |
|
186 // Reset time to allow screenshot taking on next wg change |
|
187 iScreenChangedTime = 0; |
|
188 // Order screenshot rotation |
|
189 BitmapRotationNeeded( iPrevId?iPrevId:iPrevReg, iClockwiseRot ); |
|
190 } |
|
191 iPrevReg = 0; |
|
192 } |
|
193 iPrevId = wgId; |
|
194 iLastWgIdRedraw = EFalse; |
|
195 } |
|
196 else if ( aEvent.Type() == TWservCrEvent::EDeviceOrientationChanged ) |
|
197 { |
|
198 iScreenChangedTime.HomeTime(); |
|
199 if ( iLastWgIdRedraw ) |
|
200 { |
|
201 TRAP_IGNORE( ScreenshotL() ); |
|
202 } |
|
203 } |
|
204 else if ( aEvent.Type() == TWservCrEvent::EScreenDrawing ) |
|
205 { |
|
206 iLastWgIdRedraw = ETrue; |
|
207 } |
|
208 |
|
209 TSLOG_OUT(); |
|
210 } |
|
211 |
|
212 // -------------------------------------------------------------------------- |
|
213 // CPreviewProviderCRP::ScaleComplete |
|
214 // -------------------------------------------------------------------------- |
|
215 // |
|
216 void CPreviewProviderCRP::ScaleCompleteL( const CFbsBitmap& aBitmap ) |
|
217 { |
|
218 TSLOG_CONTEXT( ScaleComplete, TSLOG_LOCAL ); |
|
219 TSLOG_IN(); |
|
220 |
|
221 const TInt msg[] = { |
|
222 NPreviewMsg::EPreviewReady, |
|
223 iPrevId?iPrevId:iPrevReg, |
|
224 aBitmap.Handle() |
|
225 }; |
|
226 TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg); |
|
227 User::LeaveIfError( SendMessage( buf ) ); |
|
228 TSLOG3( TSLOG_INFO, "size = %dx%d handle = %d", |
|
229 aBitmap.SizeInPixels().iWidth, |
|
230 aBitmap.SizeInPixels().iHeight, |
|
231 aBitmap.Handle() ); |
|
232 TSLOG_OUT(); |
|
233 } |
|
234 |
|
235 // -------------------------------------------------------------------------- |
|
236 // CPreviewProviderCRP::UnregisterComplete |
|
237 // -------------------------------------------------------------------------- |
|
238 // |
|
239 void CPreviewProviderCRP::UnregisterComplete( TInt aWgId ) |
|
240 { |
|
241 TSLOG_CONTEXT( UnregisterComplete, TSLOG_LOCAL ); |
|
242 TSLOG_IN(); |
|
243 |
|
244 const TInt msg[] = { |
|
245 NPreviewMsg::EUnregisterReady, |
|
246 aWgId, |
|
247 0 |
|
248 }; |
|
249 TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg); |
|
250 SendMessage(buf); |
|
251 |
|
252 TSLOG_OUT(); |
|
253 } |
|
254 |
|
255 |
|
256 // -------------------------------------------------------------------------- |
|
257 // CPreviewProviderCRP::BitmapRotationNeeded |
|
258 // -------------------------------------------------------------------------- |
|
259 // |
|
260 void CPreviewProviderCRP::BitmapRotationNeeded( TInt aWgId, TBool aClockwise ) |
|
261 { |
|
262 TSLOG_CONTEXT( BitmapRotationNeeded, TSLOG_LOCAL ); |
|
263 TSLOG_IN(); |
|
264 |
|
265 const TInt msg[] = { |
|
266 aClockwise ? NPreviewMsg::EBitmapRotationNeeded90 : NPreviewMsg::EBitmapRotationNeeded270, |
|
267 aWgId, |
|
268 0 |
|
269 }; |
|
270 TPckgC<TInt[sizeof(msg) / sizeof(TInt)]> buf(msg); |
|
271 SendMessage(buf); |
|
272 |
|
273 TSLOG_OUT(); |
|
274 } |
|
275 |
|
276 |
|
277 // -------------------------------------------------------------------------- |
|
278 // CPreviewProviderCRP::Register |
|
279 // -------------------------------------------------------------------------- |
|
280 // |
|
281 void CPreviewProviderCRP::Register( TInt aWgId ) |
|
282 { |
|
283 TSLOG_CONTEXT( Register, TSLOG_LOCAL ); |
|
284 TSLOG_IN(); |
|
285 |
|
286 iPrevReg = aWgId; |
|
287 iWgIds.InsertInOrder( aWgId ); |
|
288 |
|
289 TSLOG_OUT(); |
|
290 } |
|
291 |
|
292 // -------------------------------------------------------------------------- |
|
293 // CPreviewProviderCRP::Unregister |
|
294 // -------------------------------------------------------------------------- |
|
295 // |
|
296 void CPreviewProviderCRP::Unregister( TInt aWgId ) |
|
297 { |
|
298 TSLOG_CONTEXT( Unregister, TSLOG_LOCAL ); |
|
299 TSLOG_IN(); |
|
300 |
|
301 const TInt index = iWgIds.FindInOrder( aWgId ); |
|
302 if ( index >= 0 ) |
|
303 { |
|
304 iWgIds.Remove( index ); |
|
305 } |
|
306 |
|
307 UnregisterComplete( aWgId ); |
|
308 |
|
309 TSLOG_OUT(); |
|
310 } |
|
311 |
|
312 // -------------------------------------------------------------------------- |
|
313 // CPreviewProviderCRP::ScreenShotL |
|
314 // -------------------------------------------------------------------------- |
|
315 // |
|
316 void CPreviewProviderCRP::ScreenshotL() |
|
317 { |
|
318 CFbsBitmap* screenshot = new (ELeave)CFbsBitmap(); |
|
319 CleanupStack::PushL( screenshot ); |
|
320 ScreenshotL( *screenshot ); |
|
321 ScaleCompleteL( *screenshot ); |
|
322 iScreenshots.InsertL( screenshot, iScreenshots.Count() ); |
|
323 CleanupStack::Pop( screenshot ); |
|
324 CheckOverflow(); |
|
325 } |
|
326 |
|
327 // -------------------------------------------------------------------------- |
|
328 // CPreviewProviderCRP::ScreenShotL |
|
329 // -------------------------------------------------------------------------- |
|
330 // |
|
331 void CPreviewProviderCRP::ScreenshotL(CFbsBitmap& aBitmap) |
|
332 { |
|
333 TSLOG_CONTEXT( ScreenShot, TSLOG_LOCAL ); |
|
334 TSLOG_IN(); |
|
335 |
|
336 if( 0 > iScreen || Env().ScreenCount() <= iScreen ) |
|
337 { |
|
338 //screen offset out of range. skip request |
|
339 User::Leave(KErrArgument); |
|
340 } |
|
341 // Find the screen resolution |
|
342 MWsScreenConfig* screenConfig = |
|
343 Env().Screen( iScreen )->ObjectInterface<MWsScreenConfig>(); |
|
344 |
|
345 const TSize sz = screenConfig->ScreenModeSizeInPixels(); |
|
346 |
|
347 // Get the screen buffer (containing screenshot data) |
|
348 MWsFrontBuffer* screenFront = |
|
349 Env().Screen( iScreen )->ObjectInterface<MWsFrontBuffer>(); |
|
350 |
|
351 // With NGA we do not support downscaling of the screenshots. |
|
352 // So use the size of the screen if no screenshot size has been explicitly |
|
353 // set or if the old method for taking screenshots is not available. |
|
354 if ( iScreenshotSize.iWidth == 0 || |
|
355 iScreenshotSize.iHeight == 0 || |
|
356 !screenFront ) |
|
357 { |
|
358 iScreenshotSize = sz; |
|
359 } |
|
360 |
|
361 // Mark direction for possible rotation |
|
362 iClockwiseRot = iScreenshotSize.iWidth > iScreenshotSize.iHeight; |
|
363 |
|
364 // Use the the same DisplayMode as for the source image |
|
365 // so override the display mode, ignoring any requests. |
|
366 iScreenshotMode = screenConfig->DisplayMode(); |
|
367 |
|
368 TSLOG3( TSLOG_INFO, "iShotSize: %dx%d mode: %d", |
|
369 iScreenshotSize.iWidth, iScreenshotSize.iHeight, iScreenshotMode ); |
|
370 |
|
371 aBitmap.Reset(); |
|
372 User::LeaveIfError( aBitmap.Create( iScreenshotSize, iScreenshotMode ) ); |
|
373 |
|
374 // Check if front buffer is available. |
|
375 // Will always be NULL with NGA. |
|
376 if ( screenFront ) |
|
377 { |
|
378 TSLOG0( TSLOG_INFO, "non-NGA, using front buffer" ); |
|
379 FrontBufferScreenShot( aBitmap, *screenFront, sz, screenConfig->Stride() ); |
|
380 } |
|
381 #ifdef NGA |
|
382 else |
|
383 { |
|
384 TSLOG0( TSLOG_INFO, "NGA, using CopyScreenToBitmapL" ); |
|
385 MWsScreenDevice* screenDevice = static_cast<MWsScreenDevice*>( |
|
386 Env().Screen( iScreen )->ResolveObjectInterface( |
|
387 MWsScreenDevice::EWsObjectInterfaceId ) ); |
|
388 User::LeaveIfNull( screenDevice ); |
|
389 screenDevice->CopyScreenToBitmapL( &aBitmap, iScreenshotSize ); |
|
390 } |
|
391 #endif |
|
392 TSLOG_OUT(); |
|
393 } |
|
394 |
|
395 // -------------------------------------------------------------------------- |
|
396 // CPreviewProviderCRP::RemoveScreenshot |
|
397 // -------------------------------------------------------------------------- |
|
398 // |
|
399 void CPreviewProviderCRP::RemoveScreenshot( TInt aBitmapHandle ) |
|
400 { |
|
401 for( int iter(0); iter < iScreenshots.Count(); ++iter ) |
|
402 { |
|
403 if( iScreenshots[iter]->Handle() == aBitmapHandle ) |
|
404 { |
|
405 delete iScreenshots[iter]; |
|
406 iScreenshots.Remove(iter); |
|
407 break; |
|
408 } |
|
409 } |
|
410 } |
|
411 |
|
412 // -------------------------------------------------------------------------- |
|
413 // CPreviewProviderCRP::CheckOverflow |
|
414 // -------------------------------------------------------------------------- |
|
415 // |
|
416 void CPreviewProviderCRP::CheckOverflow() |
|
417 { |
|
418 TInt overflow( iScreenshots.Count() - KMaxShots); |
|
419 while( 0 < overflow-- ) |
|
420 { |
|
421 delete iScreenshots[0]; |
|
422 iScreenshots.Remove(0); |
|
423 } |
|
424 } |
|
425 |
|
426 // -------------------------------------------------------------------------- |
|
427 // CPreviewProviderCRP::FrontBufferScreenShot |
|
428 // -------------------------------------------------------------------------- |
|
429 // |
|
430 void CPreviewProviderCRP::FrontBufferScreenShot( CFbsBitmap& aBitmap, |
|
431 MWsFrontBuffer& aFront, |
|
432 const TSize& aSrcSize, |
|
433 TInt aSrcStride ) |
|
434 { |
|
435 TSLOG_CONTEXT( CPreviewProviderCRP::FrontBufferScreenShot, TSLOG_LOCAL ); |
|
436 TSLOG_IN(); |
|
437 |
|
438 const TUint8* src = static_cast<const TUint8*> ( aFront.GetBits() ); |
|
439 TSLOG1( TSLOG_INFO, "src address = [%d]", src ); |
|
440 |
|
441 TInt srcstride( aSrcStride ); |
|
442 TInt srcwidth( aSrcSize.iWidth ); |
|
443 TInt srcheight( aSrcSize.iHeight ); |
|
444 TInt dststride( aBitmap.DataStride() ); |
|
445 TInt dstheight( iScreenshotSize.iHeight ); |
|
446 TInt dstwidth( iScreenshotSize.iWidth ); |
|
447 TInt stepdst( dststride / dstwidth ); |
|
448 TInt stepsrc( srcstride / srcwidth ); |
|
449 // scale must be TInt type |
|
450 TInt scaleX( aSrcSize.iWidth / iScreenshotSize.iWidth ); |
|
451 TInt scaleY( aSrcSize.iHeight / iScreenshotSize.iHeight ); |
|
452 |
|
453 aBitmap.LockHeap(); |
|
454 |
|
455 TUint8* dst = ( TUint8* ) aBitmap.DataAddress(); |
|
456 |
|
457 TInt minWidth = Min( srcwidth, dstwidth ); |
|
458 TInt minHeight = Min( srcheight, dstheight ); |
|
459 TInt minStep = Min( stepsrc, stepdst ); |
|
460 |
|
461 for ( TInt y = minHeight; y > 0; y-- ) |
|
462 { |
|
463 for ( TInt x = minWidth; x > 0; x-- ) |
|
464 { |
|
465 Mem::Copy( dst, src, minStep ); |
|
466 dst += stepdst; |
|
467 src += scaleX*stepdst; |
|
468 } |
|
469 src += srcstride - scaleX * stepdst * minWidth; |
|
470 src += ( scaleY - 1 ) * srcstride; |
|
471 } |
|
472 |
|
473 aBitmap.UnlockHeap(); |
|
474 TSLOG_OUT(); |
|
475 } |
|
476 |
|
477 // -------------------------------------------------------------------------- |
|
478 // KImplementationTable |
|
479 // -------------------------------------------------------------------------- |
|
480 // |
|
481 LOCAL_C const TImplementationProxy KImplementationTable[] = |
|
482 { |
|
483 IMPLEMENTATION_PROXY_ENTRY(KImpId, CPreviewProviderCRP::CreateL) |
|
484 }; |
|
485 |
|
486 // -------------------------------------------------------------------------- |
|
487 // ImplementationGroupProxy |
|
488 // -------------------------------------------------------------------------- |
|
489 // |
|
490 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) |
|
491 { |
|
492 aTableCount = (sizeof(KImplementationTable) / sizeof(TImplementationProxy)); |
|
493 return KImplementationTable; |
|
494 } |
|
495 |
|
496 |
|
497 // End of file |