utilityapps/screengrabber/src/sgengine.cpp
changeset 55 2d9cac8919d3
equal deleted inserted replaced
53:819e59dfc032 55:2d9cac8919d3
       
     1 /*
       
     2 * Copyright (c) 2010 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: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <s32file.h> 
       
    19 #include <bautils.h>
       
    20 #include <pathinfo.h>
       
    21 #include <apparc.h> 
       
    22 #include <imageconversion.h>
       
    23 #include <textresolver.h>
       
    24 #include <apgtask.h> 
       
    25 
       
    26 #include <hblabel.h>
       
    27 #include <hbmessagebox.h>
       
    28 
       
    29 #include "mainview.h"
       
    30 #include "sgengine.h"
       
    31 #include "enginewrapper.h"
       
    32 #include "gifanimator.h"
       
    33 
       
    34 
       
    35 #define SC_PRINTS
       
    36 
       
    37     #ifdef SC_PRINTS
       
    38      #define SC_DEBUG(a) RDebug::Print(a)
       
    39      #define SC_DEBUG2(a,b) RDebug::Print(a,b)
       
    40     #else
       
    41      #define SC_DEBUG(a) 
       
    42      #define SC_DEBUG2(a,b)
       
    43     #endif
       
    44 
       
    45 
       
    46 
       
    47 
       
    48 _LIT(KDefaultImageFileName, "Shot");
       
    49 _LIT(KDefaultVideoFileName, "Video");
       
    50 
       
    51 #define HIGH_QUALITY_JPEG 97
       
    52 #define LOW_QUALITY_JPEG 60
       
    53 #define DEFAULT_SEQ_CAPTURE_DELAY_MS 5000   // 5.000 secs
       
    54 #define VIDEO_CAPTURE_DELAY 250             // 0.25 secs
       
    55 #define VIDEO_CAPTURE_MINIMUM_DELAY 200     // 0.20 secs
       
    56 const TInt KSettingsDrive = EDriveC;
       
    57 _LIT(KSettingsFileName, "screengrabber_settings.ini");
       
    58 _LIT(KScreenShotsSubDirectory, "Screen Shots\\");
       
    59 _LIT(KSGTemporaryDirectory, "\\system\\temp\\screengrabber\\");
       
    60 
       
    61 
       
    62 #define KEY_CAPTURE_PRIORITY 100            // do not change, this is for window server
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 
       
    66 SGEngine::SGEngine() : CActive(EPriorityStandard)
       
    67     {
       
    68     // No implementation required
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 
       
    73 SGEngine::~SGEngine()
       
    74     {
       
    75  
       
    76     TRAP_IGNORE( CleanTemporaryFilesL() );
       
    77 
       
    78 
       
    79     if (iFrameImageData)
       
    80         delete iFrameImageData;
       
    81 
       
    82     if (iPreviouslyCapturedBitmap)
       
    83         delete iPreviouslyCapturedBitmap;
       
    84 
       
    85     if (iImageEncoder)
       
    86         delete iImageEncoder;
       
    87      
       
    88     delete iVideoFrameArray;
       
    89 
       
    90     Cancel();
       
    91     iTimer.Close();
       
    92 
       
    93     iFileSession.Close(); 
       
    94     
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 
       
    99 SGEngine* SGEngine::NewLC(EngineWrapper *aEngineWrapper)
       
   100     {
       
   101     SGEngine* self = new (ELeave) SGEngine();
       
   102     CleanupStack::PushL(self);
       
   103     self->ConstructL(aEngineWrapper);
       
   104     return self;
       
   105     }
       
   106 
       
   107 // ---------------------------------------------------------------------------
       
   108 
       
   109 SGEngine* SGEngine::NewL(EngineWrapper *aEngineWrapper)
       
   110     {
       
   111     SGEngine* self = SGEngine::NewLC(aEngineWrapper);
       
   112     CleanupStack::Pop(); // self;
       
   113     return self;
       
   114     }
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 
       
   118 void SGEngine::ConstructL(EngineWrapper *aEngineWrapper)
       
   119     {
       
   120 
       
   121     iEngineWrapper = aEngineWrapper;
       
   122    
       
   123     iHashKeyCapturingActivated = EFalse; // Check this
       
   124    
       
   125     User::LeaveIfError(iTimer.CreateLocal());
       
   126 
       
   127     iVideoFrameArray = new(ELeave) CVideoFrameArray(10000);
       
   128 
       
   129     iPreviouslyCapturedBitmap = new(ELeave) CFbsBitmap;
       
   130 
       
   131     iCapturingInProgress = EFalse;
       
   132     iStopCapturing = EFalse;
       
   133     iNumberOfTakenShots = 0;
       
   134     iCurrentFrameNumber = 0;
       
   135     iHashKeyDown = EFalse;
       
   136 	
       
   137 
       
   138 	CActiveScheduler::Add(this);
       
   139 	User::LeaveIfError(iFileSession.Connect());  
       
   140 	
       
   141 	// create window group.
       
   142     iRootWin = CEikonEnv::Static()->RootWin();
       
   143 	iRootWin.EnableReceiptOfFocus(EFalse);
       
   144     
       
   145     }
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 
       
   149 void SGEngine::RunL(){
       
   150 
       
   151 
       
   152     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- RunL begin"));
       
   153     
       
   154     switch (iState) 
       
   155         {
       
   156         // encoding of the image is now finished
       
   157         case EEncodingImage: 
       
   158             {
       
   159             if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   160                 {
       
   161                 // single shot done
       
   162                 CapturingFinishedL( iStatus.Int() );
       
   163                 }
       
   164 
       
   165             else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   166                 {
       
   167                 // increase the counter    
       
   168                 iNumberOfTakenShots++;
       
   169                 
       
   170                 // check if we can take more shots or just finish
       
   171                 if (!iStopCapturing && iStatus.Int()==KErrNone)
       
   172                     {
       
   173         
       
   174                     // some delay before the next shot can be taken    
       
   175                     iState = ESequenceDelay;
       
   176                     
       
   177                     // some checking that the value of delay is valid
       
   178                     TInt delay(iGrabSettings.iSequantialCaptureDelay); //ms
       
   179                     if (delay<0 || delay > 999999)
       
   180                         delay = DEFAULT_SEQ_CAPTURE_DELAY_MS;
       
   181                       
       
   182                     iTimer.After(iStatus, delay*1000);
       
   183                     SetActive();  
       
   184                     }
       
   185                 else
       
   186                     {
       
   187                     // finished
       
   188                     CapturingFinishedL( iStatus.Int() );
       
   189                     }                       
       
   190                }
       
   191             else
       
   192                 User::Panic(_L("Wrong mode"), 32);            
       
   193 
       
   194             break;
       
   195             }
       
   196 
       
   197         // delay finished, ready to take the next shot
       
   198         case ESequenceDelay: 
       
   199             {
       
   200             TakeScreenShotAndSaveL();
       
   201 
       
   202             break;
       
   203             }
       
   204             
       
   205         // asked to cancel capturing    
       
   206         case ECancelCapturing:
       
   207             {
       
   208             // finished
       
   209             CapturingFinishedL( iStatus.Int() );
       
   210 
       
   211             break;
       
   212             }
       
   213             
       
   214         case ENextVideoFrame:
       
   215             {
       
   216             // increase the counter
       
   217             iCurrentFrameNumber++;
       
   218             
       
   219             // check if we can take more frames or just finish
       
   220             if (!iStopCapturing && iStatus.Int()==KErrNone)
       
   221                 {
       
   222                 // take next frame
       
   223                 CaptureFrameForVideoL();
       
   224                 }
       
   225             else
       
   226                 {
       
   227                 // finished, save video
       
   228                 SaveVideoL( iStatus.Int() );
       
   229                 }               
       
   230             }
       
   231             break;
       
   232 
       
   233         case ECancelVideoCapturing:
       
   234             {
       
   235             // finished, save video
       
   236             SaveVideoL( iStatus.Int() );                
       
   237             }
       
   238             break;
       
   239                                 
       
   240         default:
       
   241             {
       
   242             break;
       
   243             }
       
   244         }
       
   245     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- RunL end"));
       
   246     
       
   247 
       
   248 }
       
   249 
       
   250 
       
   251 void SGEngine::EnableRcpOfFoc(TBool aState)
       
   252 	{
       
   253 	iRootWin.EnableReceiptOfFocus(aState);
       
   254 	}
       
   255 
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 
       
   259 void SGEngine::DoCancel(){
       
   260     iTimer.Cancel();
       
   261 }
       
   262 
       
   263 // ---------------------------------------------------------------------------
       
   264 
       
   265 void SGEngine::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TInt& aValue)
       
   266     {
       
   267     if (aDicFS->IsPresentL(aUid))
       
   268         {
       
   269         RDictionaryReadStream in;
       
   270         in.OpenLC(*aDicFS, aUid);
       
   271         aValue = in.ReadInt16L();
       
   272         CleanupStack::PopAndDestroy(); // in        
       
   273         }
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------------------------
       
   277 
       
   278 void SGEngine::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TDes& aValue)
       
   279     {
       
   280     if (aDicFS->IsPresentL(aUid))
       
   281         {
       
   282         RDictionaryReadStream in;
       
   283         in.OpenLC(*aDicFS, aUid);
       
   284         TInt bufLength = in.ReadInt16L();   // get length of descriptor
       
   285         in.ReadL(aValue, bufLength);        // get the descriptor itself
       
   286         CleanupStack::PopAndDestroy(); // in
       
   287         }
       
   288     }
       
   289 // ----------------------------------------------------------------------------
       
   290 
       
   291 void SGEngine::LoadSettingsL()
       
   292     {
       
   293 	 
       
   294     // set defaults
       
   295     iGrabSettings.iCaptureMode = ECaptureModeSingleCapture;
       
   296     
       
   297     iGrabSettings.iSingleCaptureHotkey = EHotkeySendKey;
       
   298     iGrabSettings.iSingleCaptureImageFormat = EImageFormatPNG;
       
   299     iGrabSettings.iSingleCaptureMemoryInUseMultiDrive = EPhoneMemory;
       
   300     iGrabSettings.iSingleCaptureFileName.Copy( KDefaultImageFileName );
       
   301 
       
   302     iGrabSettings.iSequantialCaptureHotkey = EHotkeySendKey;
       
   303     iGrabSettings.iSequantialCaptureImageFormat = EImageFormatPNG;
       
   304     iGrabSettings.iSequantialCaptureDelay = DEFAULT_SEQ_CAPTURE_DELAY_MS;
       
   305     iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive = EPhoneMemory;
       
   306     iGrabSettings.iSequantialCaptureFileName.Copy( KDefaultImageFileName );
       
   307 
       
   308     iGrabSettings.iVideoCaptureHotkey = EHotkeySendKey;
       
   309     iGrabSettings.iVideoCaptureVideoFormat = EVideoFormatAnimatedGIF;
       
   310     iGrabSettings.iVideoCaptureMemoryInUseMultiDrive = EPhoneMemory;    
       
   311     iGrabSettings.iVideoCaptureFileName.Copy( KDefaultVideoFileName );
       
   312        
       
   313         
       
   314     // make sure that the private path of this app in c-drive exists
       
   315     
       
   316 	iFileSession.CreatePrivatePath( KSettingsDrive ); // c:\\private\\101fb751\\
       
   317     
       
   318     // handle settings always in the private directory 
       
   319     
       
   320 	if (iFileSession.SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   321         {
       
   322         // open or create a dictionary file store
       
   323         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(iFileSession, KSettingsFileName, KUidScreenGrabber);
       
   324 
       
   325         LoadDFSValueL(settingsStore, KSGSettingCaptureMode,                             iGrabSettings.iCaptureMode);
       
   326         
       
   327         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureHotkey,                     iGrabSettings.iSingleCaptureHotkey);
       
   328         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureImageFormat,                iGrabSettings.iSingleCaptureImageFormat);
       
   329         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureMemoryInUseMultiDrive,      iGrabSettings.iSingleCaptureMemoryInUseMultiDrive);
       
   330         LoadDFSValueL(settingsStore, KSGSettingSingleCaptureFileName,                   iGrabSettings.iSingleCaptureFileName);
       
   331         
       
   332         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureHotkey,                 iGrabSettings.iSequantialCaptureHotkey);
       
   333         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureImageFormat,            iGrabSettings.iSequantialCaptureImageFormat);
       
   334         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureDelay,                  iGrabSettings.iSequantialCaptureDelay);
       
   335         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureMemoryInUseMultiDrive,  iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive);
       
   336         LoadDFSValueL(settingsStore, KSGSettingSequantialCaptureFileName,               iGrabSettings.iSequantialCaptureFileName);
       
   337 
       
   338         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureHotkey,                      iGrabSettings.iVideoCaptureHotkey);
       
   339         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureVideoFormat,                 iGrabSettings.iVideoCaptureVideoFormat);
       
   340         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureMemoryInUseMultiDrive,       iGrabSettings.iVideoCaptureMemoryInUseMultiDrive);
       
   341         LoadDFSValueL(settingsStore, KSGSettingVideoCaptureFileName,                    iGrabSettings.iVideoCaptureFileName);
       
   342 
       
   343         CleanupStack::PopAndDestroy(); // settingsStore         
       
   344         }
       
   345 //chesk if all settings are in range - for safety reason, not to set some controls out of range - it causes the crash
       
   346 	if (!(iGrabSettings.iCaptureMode >= ECaptureModeSingleCapture && iGrabSettings.iCaptureMode <= ECaptureModeVideoCapture))
       
   347 	    { //give it default value
       
   348         iGrabSettings.iCaptureMode = ECaptureModeSingleCapture;
       
   349 	    }
       
   350 	if (!(iGrabSettings.iSingleCaptureHotkey >= EHotkeySendKey && iGrabSettings.iSingleCaptureHotkey <= EHotkeyCameraKey1))
       
   351 	    {
       
   352         iGrabSettings.iSingleCaptureHotkey = EHotkeySendKey;
       
   353 	    }
       
   354 	if (!(iGrabSettings.iSingleCaptureImageFormat >= EImageFormatPNG && iGrabSettings.iSingleCaptureImageFormat <= EImageFormatGIF))
       
   355 	    {
       
   356         iGrabSettings.iSingleCaptureImageFormat = EImageFormatPNG;
       
   357 	    }
       
   358 	if (!(iGrabSettings.iSingleCaptureMemoryInUseMultiDrive >= EPhoneMemory && iGrabSettings.iSingleCaptureMemoryInUseMultiDrive <= EMemoryCard))
       
   359 	    {
       
   360         iGrabSettings.iSingleCaptureMemoryInUseMultiDrive = EPhoneMemory;
       
   361 	    }
       
   362 	
       
   363     if (!(iGrabSettings.iSequantialCaptureHotkey >= EHotkeySendKey && iGrabSettings.iSequantialCaptureHotkey <= EHotkeyCameraKey1))
       
   364         {
       
   365         iGrabSettings.iSequantialCaptureHotkey = EHotkeySendKey;
       
   366         }
       
   367     if (!(iGrabSettings.iSequantialCaptureImageFormat >= EImageFormatPNG && iGrabSettings.iSequantialCaptureImageFormat <= EImageFormatGIF))
       
   368         {
       
   369         iGrabSettings.iSequantialCaptureImageFormat = EImageFormatPNG;
       
   370         }
       
   371     if (!(iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive >= EPhoneMemory && iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive <= EMemoryCard))
       
   372         {
       
   373         iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive = EPhoneMemory;
       
   374         }
       
   375 
       
   376     if (!(iGrabSettings.iVideoCaptureHotkey >= EHotkeySendKey && iGrabSettings.iVideoCaptureHotkey <= EHotkeyCameraKey1))
       
   377         {
       
   378         iGrabSettings.iVideoCaptureHotkey = EHotkeySendKey;
       
   379         }
       
   380     if (iGrabSettings.iVideoCaptureVideoFormat != EVideoFormatAnimatedGIF)
       
   381         {
       
   382         iGrabSettings.iVideoCaptureVideoFormat = EVideoFormatAnimatedGIF;
       
   383         }
       
   384     if (!(iGrabSettings.iVideoCaptureMemoryInUseMultiDrive >= EPhoneMemory && iGrabSettings.iVideoCaptureMemoryInUseMultiDrive <= EMemoryCard))
       
   385         {
       
   386         iGrabSettings.iVideoCaptureMemoryInUseMultiDrive = EPhoneMemory;
       
   387         }
       
   388 	
       
   389     }
       
   390 
       
   391 // ---------------------------------------------------------------------------
       
   392 
       
   393 void SGEngine::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TInt& aValue)
       
   394     {
       
   395     RDictionaryWriteStream out;
       
   396     out.AssignLC(*aDicFS, aUid);
       
   397     out.WriteInt16L(aValue);
       
   398     out.CommitL();  
       
   399     CleanupStack::PopAndDestroy(1);// out
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------------------------
       
   403 
       
   404 void SGEngine::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TDes& aValue)
       
   405     {
       
   406     RDictionaryWriteStream out;
       
   407     out.AssignLC(*aDicFS, aUid);
       
   408     out.WriteInt16L(aValue.Length());       // write length of the descriptor
       
   409     out.WriteL(aValue, aValue.Length());    // write the descriptor itself
       
   410     out.CommitL();  
       
   411     CleanupStack::PopAndDestroy(1);// out
       
   412     }
       
   413     
       
   414 // ---------------------------------------------------------------------------
       
   415 void SGEngine::SaveSettingsL(const TGrabSettings& aGrabSettings)
       
   416     {
       
   417 
       
   418 	
       
   419     // set the new settings
       
   420     iGrabSettings = aGrabSettings;
       
   421 
       
   422     // handle settings always in c:\\private\\101fb751\\
       
   423     if (iFileSession.SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   424         {
       
   425         // delete existing store to make sure that it is clean and not eg corrupted
       
   426         if (BaflUtils::FileExists(iFileSession, KSettingsFileName))
       
   427             {
       
   428             iFileSession.Delete(KSettingsFileName);
       
   429             }
       
   430         
       
   431         // create a dictionary file store
       
   432         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(iFileSession, KSettingsFileName, KUidScreenGrabber);
       
   433 
       
   434         SaveDFSValueL(settingsStore, KSGSettingCaptureMode,                             iGrabSettings.iCaptureMode);
       
   435         
       
   436         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureHotkey,                     iGrabSettings.iSingleCaptureHotkey);
       
   437         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureImageFormat,                iGrabSettings.iSingleCaptureImageFormat);
       
   438         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureMemoryInUseMultiDrive,      iGrabSettings.iSingleCaptureMemoryInUseMultiDrive);
       
   439         SaveDFSValueL(settingsStore, KSGSettingSingleCaptureFileName,                   iGrabSettings.iSingleCaptureFileName);
       
   440         
       
   441         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureHotkey,                 iGrabSettings.iSequantialCaptureHotkey);
       
   442         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureImageFormat,            iGrabSettings.iSequantialCaptureImageFormat);
       
   443         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureDelay,                  iGrabSettings.iSequantialCaptureDelay);
       
   444         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureMemoryInUseMultiDrive,  iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive);
       
   445         SaveDFSValueL(settingsStore, KSGSettingSequantialCaptureFileName,               iGrabSettings.iSequantialCaptureFileName);
       
   446 
       
   447         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureHotkey,                      iGrabSettings.iVideoCaptureHotkey);
       
   448         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureVideoFormat,                 iGrabSettings.iVideoCaptureVideoFormat);
       
   449         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureMemoryInUseMultiDrive,       iGrabSettings.iVideoCaptureMemoryInUseMultiDrive);
       
   450         SaveDFSValueL(settingsStore, KSGSettingVideoCaptureFileName,                    iGrabSettings.iVideoCaptureFileName);
       
   451         
       
   452         settingsStore->CommitL();
       
   453         CleanupStack::PopAndDestroy(); // settingsStore             
       
   454         }
       
   455 		
       
   456     }
       
   457         
       
   458 // ---------------------------------------------------------------------------
       
   459 
       
   460 void SGEngine::ActivateCaptureKeysL(TBool aChangeKey)
       
   461     {
       
   462 	
       
   463     // if changing the capture key, capturing needs to be cancelled first
       
   464     if (aChangeKey)
       
   465         {
       
   466         CancelCapturing();
       
   467         }
       
   468 
       
   469     // get hotkey of the capture
       
   470     TInt captureHotkey(0);
       
   471     if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   472         captureHotkey = iGrabSettings.iSingleCaptureHotkey;
       
   473     else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   474         captureHotkey = iGrabSettings.iSequantialCaptureHotkey;
       
   475     else if (iGrabSettings.iCaptureMode == ECaptureModeVideoCapture)
       
   476         captureHotkey = iGrabSettings.iVideoCaptureHotkey;
       
   477     else
       
   478         User::Panic(_L("Wrong mode"), 40);
       
   479     
       
   480     
       
   481 
       
   482     // start capturing based on user selected key
       
   483     switch (captureHotkey)
       
   484         {
       
   485         case EHotkeySendKey:
       
   486             {
       
   487             iCapturedKey    = iRootWin.CaptureKey(EStdKeyYes, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   488             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyYes, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   489             break;
       
   490             }
       
   491         case EHotkeyPowerKey:
       
   492             {
       
   493             iCapturedKey    = iRootWin.CaptureKey(EStdKeyDevice2, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   494             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyDevice2, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   495             break;
       
   496             }
       
   497         case EHotkeySideKey:
       
   498             {
       
   499             iCapturedKey    = iRootWin.CaptureKey(EStdKeyDevice6, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   500             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyDevice6, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   501             break;            
       
   502             }
       
   503         case EHotkeyCameraKey1:
       
   504             {
       
   505             iCapturedKey    = iRootWin.CaptureKey(EStdKeyDevice7, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   506             iCapturedKeyUnD = iRootWin.CaptureKeyUpAndDowns(EStdKeyDevice7, EModifierCtrl|EModifierShift|EModifierFunc, 0, KEY_CAPTURE_PRIORITY);
       
   507             break;            
       
   508             }
       
   509         default:
       
   510             {
       
   511             User::Panic(_L("Key not supported"), 100);
       
   512             break;
       
   513             }
       
   514         }
       
   515 		
       
   516     }
       
   517 
       
   518 // ---------------------------------------------------------------------------
       
   519 
       
   520 
       
   521 void SGEngine::CancelCapturing()
       
   522     {
       
   523 	
       
   524     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- CancelCapturing start"));
       
   525     // cancel all captures
       
   526     iRootWin.CancelCaptureKey(iCapturedKey);
       
   527     iRootWin.CancelCaptureKeyUpAndDowns(iCapturedKeyUnD);
       
   528     
       
   529     if (iHashKeyCapturingActivated)
       
   530         {
       
   531         iRootWin.CancelCaptureKey(iCapturedKeyHash);
       
   532         iRootWin.CancelCaptureKeyUpAndDowns(iCapturedKeyHashUnD);
       
   533         
       
   534         iHashKeyCapturingActivated = EFalse;
       
   535         }
       
   536     
       
   537     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- CancelCapturing end"));
       
   538 	
       
   539     }
       
   540 
       
   541 // ---------------------------------------------------------------------------
       
   542 
       
   543 bool SGEngine::TakeScreenShotAndSaveL()
       
   544     {
       
   545 	
       
   546     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- TakeSsAndSave start"));
       
   547     if ( IsActive() )
       
   548         {
       
   549         SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- TakeSsAndSave already active, ignored"));
       
   550         return false;
       
   551         }
       
   552     
       
   553     // take a screen shot
       
   554     CWsScreenDevice* screenDevice = new( ELeave ) CWsScreenDevice(CEikonEnv::Static()->WsSession() );
       
   555     CleanupStack::PushL( screenDevice );
       
   556 	
       
   557     User::LeaveIfError( screenDevice->Construct( CEikonEnv::Static()->WsSession().GetFocusScreen() ) );
       
   558 
       
   559 	
       
   560     User::LeaveIfError( iPreviouslyCapturedBitmap->Create(screenDevice->SizeInPixels(), screenDevice->DisplayMode()) );
       
   561     User::LeaveIfError( screenDevice->CopyScreenToBitmap(iPreviouslyCapturedBitmap) );
       
   562     CleanupStack::PopAndDestroy(); // screenDevice
       
   563 
       
   564 
       
   565     // get memory in use & image format of the screen capture
       
   566     TDriveNumber memoryInUse(EDriveC);
       
   567     TInt intMemInUse(0);
       
   568     TInt imageFormat(0);
       
   569     TFileName fileName;
       
   570     
       
   571     if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   572         {        
       
   573 //        memoryInUse = iGrabSettings.iSingleCaptureMemoryInUseMultiDrive;
       
   574         intMemInUse = iGrabSettings.iSingleCaptureMemoryInUseMultiDrive;
       
   575         
       
   576         imageFormat = iGrabSettings.iSingleCaptureImageFormat;
       
   577         fileName = iGrabSettings.iSingleCaptureFileName;
       
   578         }
       
   579     else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   580         {          
       
   581 //        memoryInUse = iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive;
       
   582         intMemInUse = iGrabSettings.iSequantialCaptureMemoryInUseMultiDrive;
       
   583         
       
   584         imageFormat = iGrabSettings.iSequantialCaptureImageFormat;
       
   585         fileName = iGrabSettings.iSequantialCaptureFileName;
       
   586         }
       
   587     else
       
   588         User::Panic(_L("Wrong mode"), 30);  
       
   589 
       
   590 
       
   591     // init the path for saving the file
       
   592 	
       
   593 	iSaveFileName.Copy( PathInfo::PhoneMemoryRootPath() );
       
   594 	
       
   595 //    if (memoryInUse != EDriveC)//something different as PhoneMemory (memory card or mass memory)
       
   596     if (intMemInUse != 0)//something different as PhoneMemory (memory card or mass memory)
       
   597     	{
       
   598 		memoryInUse = EDriveY;	    
       
   599 		if (PathInfo::GetRootPath(iSaveFileName, memoryInUse) != KErrNone || !DriveOK(memoryInUse))
       
   600 			{
       
   601 			//we need to find first available memory card in EDriveE - EDriveY range
       
   602 			for (TInt i = EDriveY; i>=EDriveE; i--)
       
   603 				{
       
   604 				if ( DriveOK((TDriveNumber)(i)))
       
   605 					{
       
   606 					if (IsDriveMMC((TDriveNumber)(i)))
       
   607 						{
       
   608 						PathInfo::GetRootPath(iSaveFileName, (TDriveNumber)(i));
       
   609 						break;
       
   610 						}    
       
   611 					}
       
   612 				}
       
   613 			}
       
   614     	}
       
   615 
       
   616     iSaveFileName.Append( PathInfo::ImagesPath() );
       
   617     iSaveFileName.Append( KScreenShotsSubDirectory );
       
   618     
       
   619     
       
   620     // a quick check that filename is valid
       
   621     if (fileName.Length() > 0 && fileName.Length() <= 255) 
       
   622         iSaveFileName.Append( fileName );
       
   623     else
       
   624         iSaveFileName.Append( KDefaultImageFileName );
       
   625 
       
   626     iSaveFileName.Append( _L(".") );
       
   627 
       
   628 
       
   629     // reset the encoder
       
   630     if (iImageEncoder)
       
   631         {
       
   632         delete iImageEncoder;
       
   633         iImageEncoder = NULL;
       
   634         }
       
   635         
       
   636     
       
   637     switch (imageFormat)
       
   638         {
       
   639         case EImageFormatPNG:
       
   640             {
       
   641             // set filename
       
   642             iSaveFileName.Append(_L("png"));
       
   643             CApaApplication::GenerateFileName(iFileSession, iSaveFileName );  // unique filename
       
   644 
       
   645             // init & convert
       
   646             iImageEncoder = CImageEncoder::FileNewL(iFileSession, iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypePNGUid);
       
   647 			
       
   648             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   649             }
       
   650             break;
       
   651         
       
   652         case EImageFormatJPGHQ:
       
   653         case EImageFormatJPGLQ:
       
   654             {
       
   655             // reset frameimagedata
       
   656             if (iFrameImageData)
       
   657                 {
       
   658                 delete iFrameImageData;
       
   659                 iFrameImageData = NULL;
       
   660                 }
       
   661             
       
   662             // set filename
       
   663             iSaveFileName.Append(_L("jpg"));
       
   664             CApaApplication::GenerateFileName(iFileSession, iSaveFileName );  // unique filename
       
   665 
       
   666             // init 
       
   667             iImageEncoder = CImageEncoder::FileNewL(iFileSession, iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeJPGUid);
       
   668 
       
   669             // JPEG properties
       
   670             TJpegImageData* imageData = new(ELeave) TJpegImageData;
       
   671             imageData->iSampleScheme = TJpegImageData::EColor444;
       
   672             imageData->iQualityFactor = (imageFormat==EImageFormatJPGHQ) ? HIGH_QUALITY_JPEG : LOW_QUALITY_JPEG;
       
   673             iFrameImageData = CFrameImageData::NewL();
       
   674             User::LeaveIfError(iFrameImageData->AppendImageData(imageData));  //ownership of imageData is transferred
       
   675 
       
   676             // convert
       
   677             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap, iFrameImageData );
       
   678             }
       
   679             break;
       
   680         
       
   681         case EImageFormatBMP:
       
   682             {
       
   683             // set filename
       
   684             iSaveFileName.Append(_L("bmp"));
       
   685             CApaApplication::GenerateFileName(iFileSession, iSaveFileName );  // unique filename
       
   686 
       
   687             // init & convert
       
   688             iImageEncoder = CImageEncoder::FileNewL(iFileSession, iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeBMPUid);
       
   689             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   690             }
       
   691             break;
       
   692 
       
   693         case EImageFormatGIF:
       
   694             {
       
   695             // set filename
       
   696             iSaveFileName.Append(_L("gif"));
       
   697             CApaApplication::GenerateFileName(iFileSession, iSaveFileName );  // unique filename
       
   698 
       
   699             // init & convert
       
   700             iImageEncoder = CImageEncoder::FileNewL(iFileSession, iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeGIFUid);
       
   701             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   702             }
       
   703             break;
       
   704             
       
   705         case EImageFormatMBM:
       
   706             {
       
   707             // set filename
       
   708             iSaveFileName.Append(_L("mbm"));
       
   709             CApaApplication::GenerateFileName(iFileSession, iSaveFileName );  // unique filename
       
   710 
       
   711             // init & convert
       
   712             iImageEncoder = CImageEncoder::FileNewL(iFileSession, iSaveFileName, CImageEncoder::EOptionAlwaysThread, KImageTypeMBMUid);
       
   713             iImageEncoder->Convert( &iStatus, *iPreviouslyCapturedBitmap );
       
   714             }
       
   715             break;
       
   716             
       
   717         default:
       
   718             {
       
   719             User::Panic(_L("Invalid Img Type"), 20);
       
   720             }
       
   721         }
       
   722 
       
   723     // set the state of the active object
       
   724     iState = EEncodingImage;
       
   725 
       
   726     // indicate an outstanding request
       
   727     SetActive();
       
   728     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- TakeSsAndSave end"));
       
   729 	return true;
       
   730     }
       
   731     
       
   732 // ---------------------------------------------------------------------------
       
   733 
       
   734 
       
   735 TBool SGEngine::DriveOK(TDriveNumber aNumber)
       
   736     {
       
   737 	
       
   738     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- Driveok start"));
       
   739     TBool isOK(EFalse);
       
   740 
       
   741     TVolumeInfo vInfo;
       
   742 
       
   743     // check if we can access the drive
       
   744     if (iFileSession.Volume(vInfo, aNumber) == KErrNone)
       
   745         isOK = ETrue;
       
   746 
       
   747     // returns ETrue if memory card working properly
       
   748     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- DriveOK end"));
       
   749     return isOK;
       
   750 	
       
   751     }
       
   752 // ---------------------------------------------------------------------------
       
   753 
       
   754 
       
   755 TBool SGEngine::IsDriveMMC(TDriveNumber aDrive)
       
   756     {
       
   757     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- IsDriveMMC start"));
       
   758     TBool isOK(EFalse);
       
   759 
       
   760     TDriveInfo ii;   
       
   761     if (iFileSession.Drive(ii, aDrive)==KErrNone) 
       
   762         {      
       
   763             if (ii.iType!=EMediaNotPresent &&
       
   764                 ii.iType!=EMediaUnknown &&           
       
   765                 ii.iType!=EMediaCdRom &&         
       
   766                 ii.iType!=EMediaRom) 
       
   767                 {           // memory card          
       
   768                     isOK=ETrue;      
       
   769                 }   
       
   770         }    
       
   771                 
       
   772     
       
   773     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- IsDriveMMC end"));
       
   774     return isOK;
       
   775     }
       
   776 
       
   777 
       
   778 void SGEngine::CapturingFinishedL(TInt aErr)
       
   779     {
       
   780 	
       
   781     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- CapturingFinished start"));
       
   782     // display a global query to show the results
       
   783     
       
   784     if (aErr == KErrNone)
       
   785         {
       
   786         switch (iGrabSettings.iCaptureMode)
       
   787             {
       
   788             case ECaptureModeSingleCapture:
       
   789                 {
       
   790                 iEngineWrapper->ShowImageCapturedNote();
       
   791                 }
       
   792                 break;
       
   793             
       
   794             case ECaptureModeSequantialCapture:
       
   795                 {
       
   796                 iEngineWrapper->ShowSequantialImagesCapturedNote(iNumberOfTakenShots);
       
   797                 }
       
   798                 break;            
       
   799     
       
   800             case ECaptureModeVideoCapture:
       
   801                 {
       
   802                 iEngineWrapper->ShowVideoCapturedNote();
       
   803                 }
       
   804                 break;             
       
   805     
       
   806             default:
       
   807                 User::Panic(_L("Inv.capt.mode"), 51);
       
   808                 break;
       
   809             }            
       
   810        
       
   811         }
       
   812     else
       
   813         {
       
   814         
       
   815         // Get error message with CTextResolver
       
   816         CTextResolver* textResolver = CTextResolver::NewLC();
       
   817         iEngineWrapper->ShowErrorMessage(textResolver->ResolveErrorString(aErr));
       
   818 
       
   819         CleanupStack::PopAndDestroy();  //textResolver    
       
   820         
       
   821         }
       
   822 
       
   823     // capturing can now be restarted
       
   824     iState = EIdle;
       
   825     iCapturingInProgress = EFalse;
       
   826     iStopCapturing = EFalse;
       
   827     
       
   828     // reset values
       
   829     iNumberOfTakenShots = 0;
       
   830     iCurrentFrameNumber = 0;
       
   831     iVideoFrameArray->Reset();
       
   832     
       
   833     
       
   834     iState = EQueryDelay;
       
   835     iTimer.After(iStatus, 2000000);
       
   836     SetActive(); 
       
   837     
       
   838     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- capturingfinished end"));
       
   839 	
       
   840     }
       
   841 
       
   842 
       
   843 #if defined(HB_QT_S60_EVENT_FILTER)
       
   844     TBool SGEngine::HandleCaptureCommandsL(const TWsEvent* aEvent)
       
   845 	{
       
   846 #else
       
   847     TBool SGEngine::HandleCaptureCommandsL(const QSymbianEvent *event)
       
   848 	{
       
   849     if (event->type() != QSymbianEvent::WindowServerEvent) {
       
   850         return ETrue; //continueEventLoop
       
   851     }
       
   852     const TWsEvent *aEvent = event->windowServerEvent();
       
   853 #endif
       
   854 	
       
   855     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- HandleCaptureCommand start"));
       
   856 	
       
   857 	
       
   858     TBool continueEventLoop(ETrue);
       
   859     
       
   860     // get hotkey of the capture
       
   861     TInt captureHotkey(0);
       
   862     if (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture)
       
   863         captureHotkey = iGrabSettings.iSingleCaptureHotkey;
       
   864     else if (iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture)
       
   865         captureHotkey = iGrabSettings.iSequantialCaptureHotkey;
       
   866     else if (iGrabSettings.iCaptureMode == ECaptureModeVideoCapture)
       
   867         captureHotkey = iGrabSettings.iVideoCaptureHotkey;
       
   868     else
       
   869         User::Panic(_L("Wrong mode"), 41);
       
   870     
       
   871     // ignore any errors
       
   872     if (aEvent->Type()==EEventErrorMessage)
       
   873         {
       
   874         // error
       
   875         }
       
   876     
       
   877             
       
   878     // handle captured keys, we are interested here only of the keydown events
       
   879     else
       
   880         
       
   881         if (
       
   882               ( captureHotkey == EHotkeySendKey &&
       
   883                 aEvent->Type()==EEventKeyDown && aEvent->Key()->iScanCode==EStdKeyYes )
       
   884             ||
       
   885               ( captureHotkey == EHotkeyPowerKey &&
       
   886                 aEvent->Type()==EEventKeyDown && aEvent->Key()->iScanCode==EStdKeyDevice2 )
       
   887             ||
       
   888               ( captureHotkey == EHotkeySideKey &&
       
   889                 aEvent->Type()==EEventKeyDown && aEvent->Key()->iScanCode==EStdKeyDevice6 )
       
   890             ||
       
   891               ( captureHotkey == EHotkeyCameraKey1 &&
       
   892                 aEvent->Type()==EEventKeyDown && aEvent->Key()->iScanCode==EStdKeyDevice7 )
       
   893             )
       
   894         {
       
   895         
       
   896         // check if already capturing images in sequence
       
   897         if ( iCapturingInProgress && !iStopCapturing && iNumberOfTakenShots!=0 && iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture )
       
   898             {
       
   899             // asking to stop capturing
       
   900             iStopCapturing = ETrue; 
       
   901             
       
   902             // cancel the active object, this will cancel any timer delays and ICL stuff
       
   903             Cancel();
       
   904             
       
   905             // set status
       
   906             iState = ECancelCapturing; 
       
   907             
       
   908             // jump smoothly to RunL()
       
   909             iTimer.After(iStatus, 50);
       
   910             SetActive(); 
       
   911 
       
   912             // do not continue the event loop in HandleWsEventL for these events
       
   913             continueEventLoop = EFalse;
       
   914             }
       
   915 
       
   916         // check if already capturing video
       
   917         else if ( iCapturingInProgress && !iStopCapturing && iGrabSettings.iCaptureMode == ECaptureModeVideoCapture )
       
   918             {
       
   919             // asking to stop capturing
       
   920             iStopCapturing = ETrue;
       
   921             
       
   922             // cancel the active object, this will cancel any timer delays and ICL stuff
       
   923             Cancel();
       
   924 
       
   925             // set status
       
   926             iState = ECancelVideoCapturing;
       
   927             
       
   928             // jump smoothly to RunL()
       
   929             iTimer.After(iStatus, 50);
       
   930             SetActive(); 
       
   931 
       
   932             // do not continue the event loop in HandleWsEventL for these events
       
   933             continueEventLoop = EFalse;
       
   934             }        
       
   935         else if (!iCapturingInProgress && (iGrabSettings.iCaptureMode == ECaptureModeSingleCapture || iGrabSettings.iCaptureMode == ECaptureModeSequantialCapture ))
       
   936             {
       
   937             
       
   938             // take a screen shot and save it
       
   939            if( TakeScreenShotAndSaveL())
       
   940                {
       
   941                // not capturing anything, so start doing that
       
   942                iCapturingInProgress = ETrue;    
       
   943                // do not continue the event loop in HandleWsEventL for these events
       
   944                continueEventLoop = EFalse;
       
   945                }
       
   946             }
       
   947         
       
   948         else if (!iCapturingInProgress && iGrabSettings.iCaptureMode == ECaptureModeVideoCapture )
       
   949             {
       
   950             // not capturing anything, so start doing that
       
   951             iCapturingInProgress = ETrue;
       
   952             
       
   953             // clean temporary files
       
   954             TRAP_IGNORE( CleanTemporaryFilesL() );
       
   955             
       
   956             // get initial dimensions for the video
       
   957             CWsScreenDevice* screenDevice = new(ELeave) CWsScreenDevice ( CEikonEnv::Static()->WsSession() );
       
   958             CleanupStack::PushL(screenDevice);
       
   959 			
       
   960             User::LeaveIfError( screenDevice->Construct( CEikonEnv::Static()->WsSession().GetFocusScreen() ) );
       
   961 			
       
   962             iVideoDimensions = screenDevice->SizeInPixels();
       
   963             iPreviousFrameScreenDimension = screenDevice->SizeInPixels();
       
   964             CleanupStack::PopAndDestroy(); // screenDevice
       
   965 
       
   966             // capture the first frame
       
   967             CaptureFrameForVideoL();              
       
   968 
       
   969             // do not continue the event loop in HandleWsEventL for these events
       
   970             continueEventLoop = EFalse;
       
   971             }
       
   972 
       
   973         }
       
   974 
       
   975     // catch other event types as well so that we can ignore them
       
   976     else if (
       
   977               ( captureHotkey == EHotkeySendKey &&
       
   978                 aEvent->Key()->iScanCode==EStdKeyYes )
       
   979             ||
       
   980               ( captureHotkey == EHotkeyPowerKey &&
       
   981                 aEvent->Key()->iScanCode==EStdKeyDevice2 )
       
   982             ||
       
   983               ( captureHotkey == EHotkeySideKey &&
       
   984                 aEvent->Key()->iScanCode==EStdKeyDevice6 )
       
   985             ||
       
   986               ( captureHotkey == EHotkeyCameraKey1 &&
       
   987                 aEvent->Key()->iScanCode==EStdKeyDevice7 )
       
   988            )
       
   989         {
       
   990         // do not continue the event loop in HandleWsEventL for these events
       
   991         continueEventLoop = EFalse;
       
   992         }
       
   993 
       
   994     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- HandleCapturcommand end"));
       
   995 
       
   996     
       
   997     return continueEventLoop;
       
   998     
       
   999     }
       
  1000 
       
  1001 // ---------------------------------------------------------------------------
       
  1002 
       
  1003 void SGEngine::CleanTemporaryFilesL()
       
  1004     {
       
  1005 	
       
  1006     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- CleanTempFiles start"));
       
  1007     
       
  1008     // delete temporary files from C and D drives    
       
  1009     CFileMan* fileMan = CFileMan::NewL(iFileSession);
       
  1010 
       
  1011     TFileName delFilesPath;
       
  1012         
       
  1013     for (TInt i=0; i<1; i++)
       
  1014         {
       
  1015         delFilesPath.Copy(KNullDesC);
       
  1016         delFilesPath.Append('C'+i);
       
  1017         delFilesPath.Append(_L(":"));
       
  1018         delFilesPath.Append(KSGTemporaryDirectory);
       
  1019         delFilesPath.Append(_L("*.$$$"));
       
  1020         
       
  1021         fileMan->Delete(delFilesPath);
       
  1022         }
       
  1023 
       
  1024     delete fileMan;    
       
  1025     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- CleanTempfile end"));
       
  1026 	
       
  1027     }
       
  1028 
       
  1029 // ---------------------------------------------------------------------------
       
  1030 
       
  1031 void SGEngine::ActivateModelL()
       
  1032     {
       
  1033     // clean temporary files
       
  1034     TRAP_IGNORE( CleanTemporaryFilesL() );
       
  1035             
       
  1036     // load settings
       
  1037     TRAP_IGNORE( LoadSettingsL() );
       
  1038 
       
  1039     // start capturing
       
  1040     ActivateCaptureKeysL();
       
  1041     }
       
  1042 
       
  1043 // ---------------------------------------------------------------------------
       
  1044 
       
  1045 void SGEngine::DeActivateModelL()
       
  1046     {
       
  1047 	
       
  1048     CancelCapturing();
       
  1049 
       
  1050     // for a faster exit, send the application to background
       
  1051     TApaTask selfTask(CEikonEnv::Static()->WsSession());
       
  1052     selfTask.SetWgId(iRootWin.Identifier());
       
  1053     selfTask.SendToBackground();
       
  1054 	
       
  1055 	
       
  1056     }
       
  1057     
       
  1058 // ---------------------------------------------------------------------------
       
  1059 
       
  1060 
       
  1061 void SGEngine::CaptureFrameForVideoL()
       
  1062     {
       
  1063     
       
  1064     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- CaptureFrameforvide start"));
       
  1065     // record time
       
  1066     TTime timeNow;
       
  1067     timeNow.HomeTime();
       
  1068     
       
  1069     // take a screen shot   
       
  1070     CFbsBitmap* currentCapturedBitmap = new(ELeave) CFbsBitmap;
       
  1071     CleanupStack::PushL(currentCapturedBitmap);
       
  1072 
       
  1073     CWsScreenDevice* screenDevice = new(ELeave) CWsScreenDevice( CEikonEnv::Static()->WsSession() );
       
  1074     CleanupStack::PushL( screenDevice );
       
  1075     User::LeaveIfError( screenDevice->Construct( CEikonEnv::Static()->WsSession().GetFocusScreen() ) );
       
  1076     
       
  1077     TSize currentScreenSize = screenDevice->SizeInPixels();
       
  1078 
       
  1079     User::LeaveIfError( currentCapturedBitmap->Create(currentScreenSize, EColor256) );
       
  1080     User::LeaveIfError( screenDevice->CopyScreenToBitmap(currentCapturedBitmap) );
       
  1081     CleanupStack::PopAndDestroy(); // screenDevice
       
  1082 
       
  1083     // grow video's dimensions if the size has changed
       
  1084     if (currentScreenSize.iWidth > iVideoDimensions.iWidth)
       
  1085         {
       
  1086         iVideoDimensions.iWidth = currentScreenSize.iWidth;
       
  1087         }
       
  1088     if (currentScreenSize.iHeight > iVideoDimensions.iHeight)
       
  1089         {
       
  1090         iVideoDimensions.iHeight = currentScreenSize.iHeight;
       
  1091         }
       
  1092 
       
  1093     TInt64 currentDelay(0);
       
  1094  
       
  1095 
       
  1096     // create a new frame
       
  1097     TVideoFrame frame;
       
  1098     frame.iDelay = 500; // use default delay 5.00 secs
       
  1099     
       
  1100     // get info of the RAM drive
       
  1101     TDriveNumber ramDrive = EDriveD;
       
  1102     TVolumeInfo ramDriveInfo;
       
  1103     iFileSession.Volume(ramDriveInfo, ramDrive);
       
  1104     
       
  1105     // init the directory for saving the file, preferably use ram drive if there is enough disk space, otherwise use always C drive
       
  1106     TFileName tempDirectory;
       
  1107     TFileName sessionPath;
       
  1108     
       
  1109     if (ramDriveInfo.iFree > (iVideoDimensions.iWidth*iVideoDimensions.iHeight+50000))
       
  1110         sessionPath.Copy( _L("D:") );
       
  1111     else
       
  1112         sessionPath.Copy( _L("C:") );
       
  1113     
       
  1114     sessionPath.Append(KSGTemporaryDirectory);
       
  1115     tempDirectory.Copy(KSGTemporaryDirectory);
       
  1116     
       
  1117     iFileSession.MkDirAll(sessionPath);
       
  1118     iFileSession.SetSessionPath(sessionPath);
       
  1119 
       
  1120     // create a temp file, path to the bitmap is saved automatically to frame.iFileStorePath
       
  1121     RFile file;
       
  1122     User::LeaveIfError( file.Temp(iFileSession, tempDirectory, frame.iFileStorePath, EFileWrite) );
       
  1123     RFileWriteStream writeStream(file);
       
  1124     
       
  1125     TBool ignoreFrame(EFalse);
       
  1126     
       
  1127     // check if is this the first frame
       
  1128     if (iCurrentFrameNumber == 0)
       
  1129         {
       
  1130         // first frame is always the full one
       
  1131         frame.iWidth = currentScreenSize.iWidth;    
       
  1132         frame.iHeight = currentScreenSize.iHeight;  
       
  1133         frame.iXPos = 0;
       
  1134         frame.iYPos = 0;
       
  1135         frame.iEnableTransparency = EFalse;
       
  1136         frame.iFillsWholeScreen = ETrue;
       
  1137         
       
  1138         currentCapturedBitmap->ExternalizeL(writeStream);  
       
  1139 
       
  1140         }
       
  1141     
       
  1142     else
       
  1143         {
       
  1144         // next frame is a difference between the previous one
       
  1145         currentDelay = timeNow.MicroSecondsFrom(iPreviousFrameTaken).Int64();
       
  1146         
       
  1147         // get reference to previos frame
       
  1148         TVideoFrame& prevFrame = iVideoFrameArray->At(iVideoFrameArray->Count()-1);
       
  1149         
       
  1150         
       
  1151         // check if video dimensions have changed
       
  1152         if (currentScreenSize.iWidth != iPreviousFrameScreenDimension.iWidth
       
  1153             || currentScreenSize.iHeight != iPreviousFrameScreenDimension.iHeight)
       
  1154             {
       
  1155             // dimensions have changed -> save a full bitmap
       
  1156             frame.iWidth = currentScreenSize.iWidth;    
       
  1157             frame.iHeight = currentScreenSize.iHeight;  
       
  1158             frame.iXPos = 0;
       
  1159             frame.iYPos = 0;
       
  1160             frame.iEnableTransparency = EFalse;
       
  1161             frame.iFillsWholeScreen = ETrue;
       
  1162             
       
  1163             currentCapturedBitmap->ExternalizeL(writeStream);            
       
  1164 
       
  1165             // update the previous frame to contain the new delay value
       
  1166             prevFrame.iDelay = TUint( (double) currentDelay / 10000 );
       
  1167             }
       
  1168 
       
  1169         else
       
  1170             {
       
  1171             // compare the bitmaps
       
  1172             TUint bufSize = currentScreenSize.iWidth*3;
       
  1173             HBufC8* curImgScanLineBuf = HBufC8::NewLC(bufSize);
       
  1174             TPtr8 curImgScanLinePtr = curImgScanLineBuf->Des();
       
  1175             HBufC8* prevImgScanLineBuf = HBufC8::NewLC(bufSize);
       
  1176             TPtr8 prevImgScanLinePtr = prevImgScanLineBuf->Des();
       
  1177             
       
  1178             TPoint pt(0,0);
       
  1179             TBool differenceFound(EFalse);
       
  1180             TPoint leftTopDifferencePoint(0,0);
       
  1181             TPoint rightBottomDifferencePoint(currentScreenSize.iWidth,currentScreenSize.iHeight);
       
  1182             
       
  1183             // scan the image from top to bottom
       
  1184             for (TInt i=0; i<currentScreenSize.iHeight; i++)
       
  1185                 {
       
  1186                 pt.iY = i;
       
  1187                 
       
  1188                 currentCapturedBitmap->GetScanLine(curImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1189                 iPreviouslyCapturedBitmap->GetScanLine(prevImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1190                 
       
  1191                 if (curImgScanLinePtr != prevImgScanLinePtr)
       
  1192                     {
       
  1193                     differenceFound = ETrue;
       
  1194                     
       
  1195                     // get the y-coordinate
       
  1196                     leftTopDifferencePoint.iY = i;
       
  1197 
       
  1198                     break;    
       
  1199                     }
       
  1200                 }
       
  1201                 
       
  1202             if (differenceFound)
       
  1203                 {
       
  1204                 // now we know that there is some difference between those two captured frames,
       
  1205                 // get the bottom value by scaning from bottom to top
       
  1206                 for (TInt i=currentScreenSize.iHeight-1; i>=0; i--)
       
  1207                     {
       
  1208                     pt.iY = i;
       
  1209                     
       
  1210                     currentCapturedBitmap->GetScanLine(curImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1211                     iPreviouslyCapturedBitmap->GetScanLine(prevImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1212                     
       
  1213                     if (curImgScanLinePtr != prevImgScanLinePtr)
       
  1214                         {
       
  1215                         // get the y-coordinate
       
  1216                         rightBottomDifferencePoint.iY = i+1;
       
  1217 
       
  1218                         break;    
       
  1219                         }
       
  1220                     }
       
  1221                     
       
  1222                 // check that the height of the cropped image will be at least 1
       
  1223                 if (rightBottomDifferencePoint.iY <= leftTopDifferencePoint.iY)
       
  1224                     rightBottomDifferencePoint.iY = leftTopDifferencePoint.iY+1;  
       
  1225                 
       
  1226                       
       
  1227                 // get also the x-coordinates by scanning vertical scan lines
       
  1228                 bufSize = currentScreenSize.iHeight*3;
       
  1229                 HBufC8* curImgVerticalScanLineBuf = HBufC8::NewLC(bufSize);
       
  1230                 TPtr8 curImgVerticalScanLinePtr = curImgVerticalScanLineBuf->Des();
       
  1231                 HBufC8* prevImgVerticalScanLineBuf = HBufC8::NewLC(bufSize);
       
  1232                 TPtr8 prevImgVerticalScanLinePtr = prevImgVerticalScanLineBuf->Des();
       
  1233                 
       
  1234                 // first scan by from left to right
       
  1235                 for (TInt i=0; i<currentScreenSize.iWidth; i++)
       
  1236                     {
       
  1237                     currentCapturedBitmap->GetVerticalScanLine(curImgVerticalScanLinePtr, i, EColor256);
       
  1238                     iPreviouslyCapturedBitmap->GetVerticalScanLine(prevImgVerticalScanLinePtr, i, EColor256);
       
  1239                     
       
  1240                     if (curImgVerticalScanLinePtr != prevImgVerticalScanLinePtr)
       
  1241                         {
       
  1242                         leftTopDifferencePoint.iX = i;
       
  1243                         break;
       
  1244                         }
       
  1245                     }
       
  1246 
       
  1247                 // finally scan from right to left
       
  1248                 for (TInt i=currentScreenSize.iWidth-1; i>=0; i--)
       
  1249                     {
       
  1250                     currentCapturedBitmap->GetVerticalScanLine(curImgVerticalScanLinePtr, i, EColor256);
       
  1251                     iPreviouslyCapturedBitmap->GetVerticalScanLine(prevImgVerticalScanLinePtr, i, EColor256);
       
  1252                     
       
  1253                     if (curImgVerticalScanLinePtr != prevImgVerticalScanLinePtr)
       
  1254                         {
       
  1255                         rightBottomDifferencePoint.iX = i+1;
       
  1256                         break;
       
  1257                         }
       
  1258                     }
       
  1259                     
       
  1260                 CleanupStack::PopAndDestroy(2); //curImgVerticalScanLineBuf,prevImgVerticalScanLineBuf               
       
  1261 
       
  1262                 
       
  1263                 // check that the width of the cropped image will be at least 1
       
  1264                 if (rightBottomDifferencePoint.iX <= leftTopDifferencePoint.iX)
       
  1265                     rightBottomDifferencePoint.iX = leftTopDifferencePoint.iX+1;
       
  1266                    
       
  1267                 
       
  1268                 // record dimensions and position of the image           
       
  1269                 frame.iWidth = rightBottomDifferencePoint.iX - leftTopDifferencePoint.iX;    
       
  1270                 frame.iHeight = rightBottomDifferencePoint.iY - leftTopDifferencePoint.iY;  
       
  1271                 frame.iXPos = leftTopDifferencePoint.iX;
       
  1272                 frame.iYPos = leftTopDifferencePoint.iY;
       
  1273                 frame.iEnableTransparency = ETrue;
       
  1274                 frame.iFillsWholeScreen = EFalse;
       
  1275             
       
  1276             
       
  1277                 // take a copy of the current frame
       
  1278                 CFbsBitmap* workingBitmap = new(ELeave) CFbsBitmap;
       
  1279                 CleanupStack::PushL(workingBitmap);
       
  1280                 User::LeaveIfError( workingBitmap->Create(currentScreenSize, EColor256) );
       
  1281 
       
  1282                 bufSize = currentScreenSize.iWidth*3;
       
  1283                 HBufC8* tempScanLineBuf = HBufC8::NewLC(bufSize);
       
  1284                 TPtr8 tempScanLinePtr = tempScanLineBuf->Des();
       
  1285                 
       
  1286                 for (TInt i=0; i<currentScreenSize.iHeight; i++)
       
  1287                     {
       
  1288                     pt.iY = i;
       
  1289                     currentCapturedBitmap->GetScanLine(tempScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1290                     workingBitmap->SetScanLine(tempScanLinePtr, i);
       
  1291                     }
       
  1292                     
       
  1293                 CleanupStack::PopAndDestroy(); //tempScanLineBuf
       
  1294                 
       
  1295                 
       
  1296                 // mark the non-changed areas with transparency color
       
  1297                 TUint8* curPtr = NULL;
       
  1298                 TUint8* prevPtr = NULL;
       
  1299                 for (TInt i=frame.iYPos; i<frame.iYPos+frame.iHeight; i++)
       
  1300                     {
       
  1301                     pt.iY = i;
       
  1302                     
       
  1303                     workingBitmap->GetScanLine(curImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1304                     iPreviouslyCapturedBitmap->GetScanLine(prevImgScanLinePtr, pt, currentScreenSize.iWidth, EColor256);
       
  1305                     
       
  1306                     // check single pixels in the scanline
       
  1307                     for (TInt j=frame.iXPos; j<frame.iXPos+frame.iWidth; j++)
       
  1308                         {
       
  1309                         curPtr = &curImgScanLinePtr[j];
       
  1310                         prevPtr = &prevImgScanLinePtr[j];
       
  1311                         
       
  1312                         // check that our transparency index isn't already in use
       
  1313                         if (curPtr[0] == TRANSPARENCY_INDEX)
       
  1314                             curPtr[0] = TRANSPARENCY_ALTERNATIVE_INDEX;
       
  1315                         
       
  1316                         // replace with transparency index if there is no change compared to the previous frame
       
  1317                         if (curPtr[0] == prevPtr[0])
       
  1318                             curPtr[0] = TRANSPARENCY_INDEX;
       
  1319                         }
       
  1320                         
       
  1321                     // set new scanline    
       
  1322                     workingBitmap->SetScanLine(curImgScanLinePtr, i);
       
  1323                     }
       
  1324 
       
  1325 
       
  1326                 // externalize the bitmap
       
  1327                 TRect changedRect(leftTopDifferencePoint, rightBottomDifferencePoint);
       
  1328                 workingBitmap->ExternalizeRectangleL(writeStream, changedRect);
       
  1329                 
       
  1330                 CleanupStack::PopAndDestroy(); //workingBitmap
       
  1331  
       
  1332                 // update the previous frame to contain the new delay value
       
  1333                 prevFrame.iDelay = TUint( (double) currentDelay / 10000 );
       
  1334                 }
       
  1335 
       
  1336             else
       
  1337                 {
       
  1338                 // frames are identical, we can just ignore this one
       
  1339                 ignoreFrame = ETrue;     
       
  1340                 }
       
  1341             
       
  1342             CleanupStack::PopAndDestroy(2); //curImgScanLineBuf,prevImgScanLineBuf
       
  1343 
       
  1344             } // if (videoDimensionsHaveChanged)
       
  1345 
       
  1346         } //if (iCurrentFrameNumber == 0)
       
  1347             
       
  1348     // close the stream
       
  1349     writeStream.CommitL();
       
  1350     writeStream.Close();
       
  1351     file.Close();
       
  1352     
       
  1353 
       
  1354     if (ignoreFrame)
       
  1355         {
       
  1356         // delete the temp file since we don't need that
       
  1357             iFileSession.Delete(frame.iFileStorePath);
       
  1358         }
       
  1359     else
       
  1360         {
       
  1361         // remember for the next frame when this frame was taken
       
  1362         iPreviousFrameTaken = timeNow;
       
  1363 
       
  1364         // take a copy of currentCapturedBitmap to iPreviouslyCapturedBitmap
       
  1365         User::LeaveIfError( iPreviouslyCapturedBitmap->Create(iVideoDimensions, EColor256) );
       
  1366 
       
  1367         TPoint pt(0,0);
       
  1368         HBufC8* tempScanLineBuf = HBufC8::NewMaxLC(iVideoDimensions.iWidth);
       
  1369         TPtr8 tempScanLinePtr = tempScanLineBuf->Des();
       
  1370         
       
  1371         for (TInt i=0; i<iVideoDimensions.iHeight; i++)
       
  1372             {
       
  1373             pt.iY = i;
       
  1374             currentCapturedBitmap->GetScanLine(tempScanLinePtr, pt, iVideoDimensions.iWidth, EColor256);
       
  1375             iPreviouslyCapturedBitmap->SetScanLine(tempScanLinePtr, i);
       
  1376             }
       
  1377             
       
  1378         CleanupStack::PopAndDestroy(); //tempScanLineBuf
       
  1379         
       
  1380         // append frame information to the array
       
  1381         iVideoFrameArray->AppendL(frame);
       
  1382         
       
  1383         // remember screen size
       
  1384         iPreviousFrameScreenDimension = currentScreenSize;
       
  1385         }    
       
  1386 
       
  1387     
       
  1388     CleanupStack::PopAndDestroy(); //currentCapturedBitmap
       
  1389     
       
  1390 
       
  1391     // set the state of the active object
       
  1392     iState = ENextVideoFrame;
       
  1393     
       
  1394     // check time spent on the work above (probably this is not so important)
       
  1395     TTime timeNow2;
       
  1396     timeNow2.HomeTime();
       
  1397     TInt64 handlingDelay = timeNow2.MicroSecondsFrom(timeNow).Int64();
       
  1398     
       
  1399     // calculate delay till next frame
       
  1400     TUint idealDelay = VIDEO_CAPTURE_DELAY*1000;
       
  1401     TInt usedDelay; 
       
  1402     if (currentDelay > idealDelay)
       
  1403         usedDelay = idealDelay - (currentDelay - idealDelay) - handlingDelay;
       
  1404     else
       
  1405         usedDelay = idealDelay - handlingDelay;
       
  1406     
       
  1407     // check that the delay is atleast minimum delay anyway
       
  1408     if (usedDelay < VIDEO_CAPTURE_MINIMUM_DELAY*1000)
       
  1409         usedDelay = VIDEO_CAPTURE_MINIMUM_DELAY*1000;
       
  1410     
       
  1411     iTimer.After(iStatus, usedDelay);
       
  1412 
       
  1413     // indicate an outstanding request
       
  1414     SetActive();
       
  1415     
       
  1416     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- Captureframeforvideo end"));
       
  1417 	
       
  1418     }
       
  1419 
       
  1420 // ---------------------------------------------------------------------------
       
  1421 
       
  1422 void SGEngine::SaveVideoL(TInt aErr)
       
  1423     {
       
  1424 
       
  1425     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- SaveVideo start"));
       
  1426     
       
  1427     if (aErr)
       
  1428         CapturingFinishedL(aErr);   
       
  1429    
       
  1430     else if (iGrabSettings.iVideoCaptureVideoFormat == EVideoFormatAnimatedGIF)
       
  1431         {
       
  1432         TInt err(KErrNone);
       
  1433 
       
  1434         
       
  1435 			iSaveFileName.Copy( PathInfo::PhoneMemoryRootPath() );
       
  1436             if (iGrabSettings.iVideoCaptureMemoryInUseMultiDrive != 0)//something different as PhoneMemory (memory card or mass memory)
       
  1437             	{
       
  1438         		if (PathInfo::GetRootPath(iSaveFileName,EDriveY) != KErrNone || !DriveOK(EDriveY))
       
  1439         			{
       
  1440         			//we need to find first available memory card in EDriveE - EDriveY range
       
  1441         			for (TInt i = EDriveY; i>=EDriveE; i--)
       
  1442         				{
       
  1443         				if ( DriveOK((TDriveNumber)(i)))
       
  1444         					{
       
  1445         					if (IsDriveMMC((TDriveNumber)(i)))
       
  1446         						{
       
  1447         						PathInfo::GetRootPath(iSaveFileName, (TDriveNumber)(i));
       
  1448         						break;
       
  1449         						}    
       
  1450         					}
       
  1451         				}
       
  1452         			}
       
  1453             	}
       
  1454 
       
  1455         
       
  1456         iSaveFileName.Append( PathInfo::ImagesPath() );     // animated gif is actually an image, not a video
       
  1457         iSaveFileName.Append( KScreenShotsSubDirectory );
       
  1458         
       
  1459         // a quick check that filename is valid
       
  1460         if (iGrabSettings.iVideoCaptureFileName.Length() > 0 && iGrabSettings.iVideoCaptureFileName.Length() <= 255) 
       
  1461             iSaveFileName.Append( iGrabSettings.iVideoCaptureFileName );
       
  1462         else
       
  1463             iSaveFileName.Append( KDefaultVideoFileName );
       
  1464 
       
  1465         iSaveFileName.Append( _L(".gif") );
       
  1466 
       
  1467         CApaApplication::GenerateFileName(iFileSession, iSaveFileName );  // unique filename
       
  1468 
       
  1469         // create and save the gif animation
       
  1470         err = CGifAnimator::CreateGifAnimation(iSaveFileName, iVideoDimensions, iVideoFrameArray, *iEngineWrapper);
       
  1471         
       
  1472         // remove the saved file in case of errors since it's likely corrupted
       
  1473         if (err != KErrNone)
       
  1474             iFileSession.Delete(iSaveFileName);
       
  1475         
       
  1476         CapturingFinishedL(err);   
       
  1477         }
       
  1478         
       
  1479     else
       
  1480         CapturingFinishedL(KErrNotSupported);
       
  1481     
       
  1482     SC_DEBUG(_L("SCREENGRABBER ------------------------------------------------------- SaveVideo end"));
       
  1483     }
       
  1484 // ---------------------------------------------------------------------------
       
  1485