testconnuis/htiui/HtiServicePlugins/HtiScreenshotServicePlugin/src/HtiScreenshotServicePlugin.cpp
changeset 2 453d490c84a5
equal deleted inserted replaced
1:753e33780645 2:453d490c84a5
       
     1 /*
       
     2 * Copyright (c) 2009 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:  SysInfoPlugin implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "../../../symbian_version.hrh"
       
    21 
       
    22 
       
    23 #include "HtiScreenshotServicePlugin.h"
       
    24 #include <HtiDispatcherInterface.h>
       
    25 #include <HtiLogging.h>
       
    26 
       
    27 #include <imageconversion.h>
       
    28 #include <ezcompressor.h>
       
    29 #include <hal.h>
       
    30 
       
    31 #include <AknLayoutConfig.h>
       
    32 #include <apgtask.h> 
       
    33 #include <AknCapServerDefs.h>
       
    34 
       
    35 #if ( SYMBIAN_VERSION_SUPPORT < SYMBIAN_4 )
       
    36 #include <alf/alfdrawer.h>
       
    37 #endif
       
    38 
       
    39 // CONSTANTS
       
    40 const static TUid KScreenshotServiceUid = {0x1020DEC3};
       
    41 
       
    42 enum TScreenCommands
       
    43     {
       
    44     // Normal screencapture
       
    45     ECmdScreen                = 0x01,
       
    46     ECmdScreenRegion          = 0x02,
       
    47     ECmdScreenZip             = 0x03,
       
    48     ECmdScreenRegionZip       = 0x04,
       
    49 
       
    50     // Text recognition
       
    51     ECmdTextRcg               = 0x10,
       
    52     ECmdTextRcg_u             = 0x11,
       
    53 
       
    54     // Text bitmap
       
    55     ECmdTextBitmap            = 0x12,
       
    56     ECmdTextBitmap_u          = 0x13,
       
    57 
       
    58     // Screencapture in series
       
    59     ECmdScreenSeries          = 0x21,
       
    60     ECmdScreenRegionSeries    = 0x22,
       
    61     ECmdScreenZipSeries       = 0x23,
       
    62     ECmdScreenRegionZipSeries = 0x24,
       
    63 
       
    64     // Selects the screen to use
       
    65     ECmdSelectScreen          = 0x30,
       
    66 
       
    67     // Gets the current screen size and orientation
       
    68     ECmdScreenMode            = 0x3A,
       
    69     
       
    70     // Rotates the screen to portrait or landscape
       
    71     ECmdRotateScreen          = 0x3B,
       
    72 
       
    73     // Screencapture on updated part of screen only
       
    74     ECmdDeltaCaptureMask           = 0x80,
       
    75     ECmdDeltaScreen                = 0x81,
       
    76     ECmdDeltaScreenRegion          = 0x82,
       
    77     ECmdDeltaScreenZip             = 0x83,
       
    78     ECmdDeltaScreenRegionZip       = 0x84,
       
    79     ECmdDeltaScreenReset           = 0x85
       
    80     //ECmdDeltaScreenSeries          = 0xA1,
       
    81     //ECmdDeltaScreenRegionSeries    = 0xA2,
       
    82     //ECmdDeltaScreenZipSeries       = 0xA3,
       
    83     //ECmdDeltaScreenRegionZipSeries = 0xA4
       
    84     };
       
    85 
       
    86 enum TScreenResponse
       
    87     {
       
    88     ERspOk = 0xF0,
       
    89     ERspNotFound = 0xF1
       
    90     };
       
    91 
       
    92 enum THtiFontAttributes
       
    93     {
       
    94     EHtiFontAttBold = 0x01,
       
    95     EHtiFontAttItalic = 0x02,
       
    96     EHtiFontAttNotAA = 0x04,
       
    97     EHtiFontAttPrintPositionFlag = 0x08,
       
    98     EHtiFontAttPrintPositionValue = 0x10
       
    99     };
       
   100 
       
   101 const static TInt KHtiFontAttSuperscriptValue = 0;
       
   102 const static TInt KHtiFontAttSubscriptValue = 1;
       
   103 
       
   104 //1 byte for cmd and 2*4 for 4 coordinates
       
   105 const static TInt KMinScreenRegionCmdLength = 9;
       
   106 const static TInt KScreenDisplayOffset = 1;
       
   107 const static TInt KScreenMIMEOffset = KScreenDisplayOffset + 1;
       
   108 const static TInt KScreenScreenNumber = KScreenMIMEOffset + 8;
       
   109 const static TInt KRegionDisplayOffset = KMinScreenRegionCmdLength;
       
   110 const static TInt KRegionMIMEOffset = KRegionDisplayOffset + 1;
       
   111 const static TInt KRegionScreenNumber = KRegionMIMEOffset + 8;
       
   112 
       
   113 const static TInt KSeriesDurationOffset = 1;
       
   114 const static TInt KSeriesIntervalOffset = KSeriesDurationOffset + 4;
       
   115 const static TInt KSeriesDisplayOffset = KSeriesIntervalOffset + 4;
       
   116 const static TInt KSeriesMIMEOffset = KSeriesDisplayOffset + 1;
       
   117 const static TInt KSeriesScreenNumber = KSeriesMIMEOffset + 8;
       
   118 const static TInt KMinSeriesCmdLength = KSeriesMIMEOffset;
       
   119 
       
   120 const static TInt KRegionSeriesTlX = KSeriesDisplayOffset + 1;
       
   121 const static TInt KRegionSeriesTlY = KRegionSeriesTlX + 2;
       
   122 const static TInt KRegionSeriesBlX = KRegionSeriesTlY + 2;
       
   123 const static TInt KRegionSeriesBlY = KRegionSeriesBlX + 2;
       
   124 const static TInt KRegionSeriesMIMEOffset = KRegionSeriesBlY + 2;
       
   125 const static TInt KRegionSeriesScreenNumber = KRegionSeriesMIMEOffset + 8;
       
   126 const static TInt KMinRegionSeriesCmdLength = KRegionSeriesMIMEOffset;
       
   127 
       
   128 const static TInt KDeltaResetCmdLength = 1;
       
   129 const static TInt KScreenModeCmdLength = 1;
       
   130 
       
   131 const static TInt KScreenNrOffset = 1;
       
   132 const static TInt KSelectScreenCmdLength = 2;
       
   133 const static TInt KRotateScreenCmdLength = 2;
       
   134 
       
   135 _LIT( KSeriesShotPath, "c:\\Hti\\SeriesShot\\" );
       
   136 
       
   137 //errors' descriptions
       
   138 _LIT8( KErrDescrInvalid, "invalid arguments" );
       
   139 _LIT8( KErrDescrInvalidMode, "invalid color mode" );
       
   140 _LIT8( KErrDescrRegiontEmpty, "region is empty" );
       
   141 _LIT8( KErrDescrRegionNotNormailized, "region is not normalized" );
       
   142 _LIT8( KErrDescrRegionOutOfScreen, "region is out of screen" );
       
   143 _LIT8( KErrDescrUnknownCommand, "unknown command" );
       
   144 _LIT8( KErrDescrFailedConvert, "failed to convert to image format" );
       
   145 _LIT8( KErrDescrFailedCompress, "failed to compress" );
       
   146 _LIT8( KErrDescrMIMENotSupported, "MIME type not supported" );
       
   147 _LIT8( KErrDescrScreenNotSupported, "screen not supported" );
       
   148 
       
   149 _LIT( KScreenshotPanic, "Screenshot plug-in invalid state" );
       
   150 
       
   151 //_LIT(KS60Sans, "Series 60 Sans");
       
   152 //_LIT(KS60SansTitleBold, "Series 60 Sans TitleSmBd");
       
   153 
       
   154 //const TInt KFonHeighMin = 110;
       
   155 //const TInt KFonHeighMax = 190;
       
   156 /*
       
   157 // ----------------------------------------------------------------------------
       
   158 void CHtiScreenshotServicePlugin::InitFontCache()
       
   159     {
       
   160     //temporary
       
   161     //just put harcoded data
       
   162     //should be either external file or auto-defined based on logical fonts
       
   163     //or some test app
       
   164     TFontSpec fs;
       
   165     fs.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
       
   166     //primary font
       
   167     fs.iTypeface.iName = KS60Sans;
       
   168     fs.iHeight = 161;
       
   169     fs.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   170     iFontCache.Append(fs);
       
   171 
       
   172     fs.iFontStyle.SetStrokeWeight(EStrokeWeightNormal);
       
   173 
       
   174     //Series 60 Sans TitleSmBd, 183
       
   175     fs.iTypeface.iName = KS60SansTitleBold;
       
   176     fs.iHeight = 183;
       
   177     iFontCache.Append(fs);
       
   178 
       
   179     //Series 60 Sans TitleSmBd, 172
       
   180     fs.iTypeface.iName = KS60SansTitleBold;
       
   181     fs.iHeight = 172;
       
   182     iFontCache.Append(fs);
       
   183 
       
   184     //Series 60 Sans,           122
       
   185     fs.iTypeface.iName = KS60Sans;
       
   186     fs.iHeight = 122;
       
   187     iFontCache.Append(fs);
       
   188     //Series 60 Sans,           116
       
   189     fs.iTypeface.iName = KS60Sans;
       
   190     fs.iHeight = 116;
       
   191     iFontCache.Append(fs);
       
   192 
       
   193     //Series 60 Sans TitleSmBd, 138
       
   194     fs.iTypeface.iName = KS60SansTitleBold;
       
   195     fs.iHeight = 138;
       
   196     iFontCache.Append(fs);
       
   197     }
       
   198 */
       
   199 
       
   200 // ----------------------------------------------------------------------------
       
   201 TInt ImageDifferenceL( CFbsBitmap* aImage1, CFbsBitmap* aImage2,
       
   202                        CFbsBitmap* &aResult, TRect &aRect )
       
   203     {
       
   204     HTI_LOG_TEXT( "ImageDifferenceL()" );
       
   205 
       
   206     // By default return coordinates of the full image
       
   207     aRect = TRect( 0, 0, aImage2->SizeInPixels().iWidth,
       
   208                   aImage2->SizeInPixels().iHeight );
       
   209 
       
   210 //1. check that aImage1 and aImage2 are valid and can be compared
       
   211     if ( aImage1 == NULL || aImage2 == NULL )
       
   212         {
       
   213         HTI_LOG_TEXT( "return KErrArgument" );
       
   214         return KErrArgument;
       
   215         }
       
   216 
       
   217     if ( aImage1->SizeInPixels() != aImage2->SizeInPixels() )
       
   218         {
       
   219         HTI_LOG_TEXT( "return KErrGeneral (size)" );
       
   220         return KErrGeneral;
       
   221         }
       
   222 
       
   223     if ( aImage1->DisplayMode() != aImage2->DisplayMode() )
       
   224         {
       
   225         HTI_LOG_TEXT( "return KErrGeneral (displaymode)" );
       
   226         return KErrGeneral;
       
   227         }
       
   228 
       
   229 
       
   230 //2. iterate through images from each border and compare to findout outline for diff region
       
   231     TSize orgSize = aImage1->SizeInPixels();
       
   232 
       
   233     TBitmapUtil srcBmpIterator1( aImage1 );
       
   234     TBitmapUtil srcBmpIterator2( aImage2 );
       
   235 
       
   236     srcBmpIterator1.Begin( TPoint( 0, 0 ) );
       
   237     srcBmpIterator2.Begin( TPoint( 0, 0 ), srcBmpIterator1 );
       
   238 
       
   239     TRect diffOutline = TRect( -1, -1, -1, -1 );
       
   240 
       
   241     //2.1 top border iteration
       
   242     TPoint c( 0,0 );
       
   243     for ( ; c.iY < orgSize.iHeight && diffOutline.iTl.iY == -1; ++c.iY )
       
   244         {
       
   245         c.iX = 0;
       
   246         srcBmpIterator1.SetPos( c );
       
   247         srcBmpIterator2.SetPos( c );
       
   248         for ( ; c.iX < orgSize.iWidth && diffOutline.iTl.iY == -1; ++c.iX )
       
   249             {
       
   250             if ( srcBmpIterator1.GetPixel() != srcBmpIterator2.GetPixel() )
       
   251                 {
       
   252                 diffOutline.iTl.iY = c.iY;
       
   253                 }
       
   254 
       
   255             srcBmpIterator1.IncXPos();
       
   256             srcBmpIterator2.IncXPos();
       
   257             }
       
   258         }
       
   259 
       
   260     //2.2 bottom iteration
       
   261     c.SetXY( 0, orgSize.iHeight - 1 );
       
   262     for ( ; c.iY >= diffOutline.iTl.iY && diffOutline.iBr.iY == -1; --c.iY )
       
   263         {
       
   264         c.iX = 0;
       
   265         srcBmpIterator1.SetPos( c );
       
   266         srcBmpIterator2.SetPos( c );
       
   267         for (; c.iX < orgSize.iWidth && diffOutline.iBr.iY == -1; ++c.iX )
       
   268             {
       
   269             if ( srcBmpIterator1.GetPixel() != srcBmpIterator2.GetPixel() )
       
   270                 {
       
   271                 diffOutline.iBr.iY = c.iY;
       
   272                 }
       
   273 
       
   274             srcBmpIterator1.IncXPos();
       
   275             srcBmpIterator2.IncXPos();
       
   276             }
       
   277         }
       
   278 
       
   279     //2.3 left, goes in vertical lines
       
   280     c.SetXY( 0, diffOutline.iTl.iY );
       
   281     for ( ; c.iX < orgSize.iWidth && diffOutline.iTl.iX == -1; ++c.iX )
       
   282         {
       
   283         c.iY = diffOutline.iTl.iY;
       
   284         srcBmpIterator1.SetPos( c );
       
   285         srcBmpIterator2.SetPos( c );
       
   286         for ( ; c.iY <= diffOutline.iBr.iY && diffOutline.iTl.iX == -1; ++c.iY )
       
   287 
       
   288             {
       
   289             if ( srcBmpIterator1.GetPixel() != srcBmpIterator2.GetPixel() )
       
   290                 {
       
   291                 diffOutline.iTl.iX = c.iX;
       
   292                 }
       
   293 
       
   294             srcBmpIterator1.IncYPos();
       
   295             srcBmpIterator2.IncYPos();
       
   296             }
       
   297         }
       
   298     //2.4 right, goes in vertical lines
       
   299     c.SetXY( orgSize.iWidth - 1, diffOutline.iTl.iY );
       
   300     for ( ; c.iX >= diffOutline.iTl.iX && diffOutline.iBr.iX == -1; --c.iX )
       
   301         {
       
   302         c.iY = diffOutline.iTl.iY;
       
   303         srcBmpIterator1.SetPos( c );
       
   304         srcBmpIterator2.SetPos( c );
       
   305         for ( ; c.iY <= diffOutline.iBr.iY && diffOutline.iBr.iX == -1; ++c.iY )
       
   306 
       
   307             {
       
   308             if ( srcBmpIterator1.GetPixel() != srcBmpIterator2.GetPixel() )
       
   309                 {
       
   310                 diffOutline.iBr.iX = c.iX;
       
   311                 }
       
   312 
       
   313             srcBmpIterator1.IncYPos();
       
   314             srcBmpIterator2.IncYPos();
       
   315             }
       
   316         }
       
   317     srcBmpIterator2.End();
       
   318     srcBmpIterator1.End();
       
   319 
       
   320     //3. if there is some diff create CFbsBitmap in aResult and copy outlined image from aImage2
       
   321     if ( diffOutline.iTl.iX == -1 &&
       
   322          diffOutline.iTl.iY == -1 &&
       
   323          diffOutline.iBr.iX == -1 &&
       
   324          diffOutline.iBr.iY == -1 )
       
   325         {
       
   326         // No difference found
       
   327         aRect = TRect( 0, 0, 0, 0 );
       
   328         HTI_LOG_TEXT( "return KErrNotFound" );
       
   329         return KErrNotFound;
       
   330         }
       
   331 
       
   332     aRect = diffOutline;
       
   333 
       
   334     HTI_LOG_FORMAT( "Tlx - %d", aRect.iTl.iX );
       
   335     HTI_LOG_FORMAT( "Tly - %d", aRect.iTl.iY );
       
   336     HTI_LOG_FORMAT( "Bty - %d", aRect.iBr.iX );
       
   337     HTI_LOG_FORMAT( "Bry - %d", aRect.iBr.iY );
       
   338 
       
   339     // The bottom right co-ordinate is not included in the rectange
       
   340     // (see TRect documentation) so we need to stretch the rectange
       
   341     // for BitBlt to get the correct sized image.
       
   342 
       
   343     TRect captureRect( diffOutline.iTl.iX, diffOutline.iTl.iY,
       
   344                        diffOutline.iBr.iX + 1, diffOutline.iBr.iY + 1 );
       
   345 
       
   346     aResult = new (ELeave) CFbsBitmap();
       
   347     User::LeaveIfError( aResult->Create( captureRect.Size(), aImage2->DisplayMode() ) );
       
   348     CleanupStack::PushL( aResult );
       
   349 
       
   350     CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( aResult );
       
   351     CleanupStack::PushL( bmpDevice );
       
   352 
       
   353     CFbsBitGc* bmpCtx;
       
   354     bmpDevice->CreateContext( bmpCtx );
       
   355     bmpCtx->BitBlt( TPoint( 0, 0 ), aImage2, captureRect );
       
   356 
       
   357     delete bmpCtx;
       
   358     bmpCtx = NULL;
       
   359 
       
   360     CleanupStack::PopAndDestroy(); // bmpDevice
       
   361     CleanupStack::Pop(); // aResult
       
   362 
       
   363     HTI_LOG_TEXT( "return KErrNone" );
       
   364     return KErrNone;
       
   365     }
       
   366 
       
   367 // ----------------------------------------------------------------------------
       
   368 CICLHandler::CICLHandler( CImageEncoder* aService, MICLObserver* anObserver ):
       
   369     CActive( EPriorityStandard ),
       
   370     iObserver( anObserver ),
       
   371     iService( aService )
       
   372     {
       
   373     CActiveScheduler::Add( this );
       
   374     }
       
   375 
       
   376 // ----------------------------------------------------------------------------
       
   377 CICLHandler::~CICLHandler()
       
   378     {
       
   379     Cancel();
       
   380     }
       
   381 
       
   382 // ----------------------------------------------------------------------------
       
   383 void CICLHandler::Start()
       
   384     {
       
   385     SetActive();
       
   386     }
       
   387 
       
   388 // ----------------------------------------------------------------------------
       
   389 void CICLHandler::RunL()
       
   390     {
       
   391     iObserver->ICLComplete( iStatus.Int() );
       
   392     }
       
   393 
       
   394 // ----------------------------------------------------------------------------
       
   395 void CICLHandler::DoCancel()
       
   396     {
       
   397     iService->Cancel();
       
   398     }
       
   399 
       
   400 /*
       
   401 // ----------------------------------------------------------------------------
       
   402 TInt CICLHandler::RunError(TInt aError)
       
   403     {
       
   404 
       
   405     }
       
   406 */
       
   407 
       
   408 // ----------------------------------------------------------------------------
       
   409 // Create instance of concrete ECOM interface implementation
       
   410 CHtiScreenshotServicePlugin* CHtiScreenshotServicePlugin::NewL()
       
   411     {
       
   412     CHtiScreenshotServicePlugin* self = new (ELeave) CHtiScreenshotServicePlugin;
       
   413     CleanupStack::PushL( self );
       
   414     self->ConstructL();
       
   415     CleanupStack::Pop();
       
   416     return self;
       
   417     }
       
   418 
       
   419 // ----------------------------------------------------------------------------
       
   420 // Constructor
       
   421 CHtiScreenshotServicePlugin::CHtiScreenshotServicePlugin():
       
   422     iScreen( NULL ),
       
   423     iEncodedBitmap( NULL ),
       
   424     iScreenDevice( NULL ),
       
   425     iBitmapEncoder( NULL ),
       
   426     iICLHandler( NULL ),
       
   427     iCompress( EFalse ),
       
   428     iDeltaCapture( EFalse ),
       
   429     iPreviousBitmap( NULL )
       
   430     {
       
   431     }
       
   432 
       
   433 // ----------------------------------------------------------------------------
       
   434 CHtiScreenshotServicePlugin::~CHtiScreenshotServicePlugin()
       
   435     {
       
   436     HTI_LOG_FUNC_IN( "~CHtiScreenshotServicePlugin" );
       
   437 
       
   438     iFontCache.Close();
       
   439 
       
   440     delete iScreen;
       
   441     delete iEncodedBitmap;
       
   442 
       
   443     delete iICLHandler;
       
   444     delete iBitmapEncoder;
       
   445 
       
   446     delete iScreenDevice;
       
   447 
       
   448     delete iSeriesShot;
       
   449 
       
   450     if ( iPreviousBitmap )
       
   451         delete iPreviousBitmap;
       
   452 
       
   453     iWs.Close();
       
   454     HTI_LOG_FUNC_OUT( "~CHtiScreenshotServicePlugin" );
       
   455     }
       
   456 
       
   457 // ----------------------------------------------------------------------------
       
   458 // Second phase construction.
       
   459 void CHtiScreenshotServicePlugin::ConstructL()
       
   460     {
       
   461     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::ConstructL" );
       
   462     User::LeaveIfError( iWs.Connect() );
       
   463 
       
   464     iScreenDevice = new ( ELeave ) CWsScreenDevice( iWs );
       
   465     User::LeaveIfError( iScreenDevice->Construct() );
       
   466 
       
   467     //InitFontCache();
       
   468 
       
   469     iSeriesShot = CSeriesShot::NewL( this );
       
   470 
       
   471     iPreviousBitmap = new ( ELeave ) CFbsBitmap;
       
   472 
       
   473     //SelectEncoder( KImageTypeBMPUid );
       
   474     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::ConstructL" );
       
   475     }
       
   476 
       
   477 // ----------------------------------------------------------------------------
       
   478 TBool CHtiScreenshotServicePlugin::IsBusy()
       
   479     {
       
   480     if ( iICLHandler )
       
   481         {
       
   482         return iICLHandler->IsActive();
       
   483         }
       
   484 
       
   485     if ( iSeriesShot->IsOngoing() )
       
   486         {
       
   487         return ETrue;
       
   488         }
       
   489 
       
   490     return iEncodedBitmap != NULL;
       
   491     }
       
   492 
       
   493 // ----------------------------------------------------------------------------
       
   494 inline TInt CHtiScreenshotServicePlugin::ParseInt16( const TUint8* aStart )
       
   495     {
       
   496     return aStart[0] + (aStart[1]<<8);
       
   497     }
       
   498 
       
   499 // ----------------------------------------------------------------------------
       
   500 inline TInt CHtiScreenshotServicePlugin::ParseInt32( const TUint8* aStart )
       
   501     {
       
   502     return aStart[0] + (aStart[1]<<8) + (aStart[2]<<16) + (aStart[3]<<24);
       
   503     }
       
   504 
       
   505 // ----------------------------------------------------------------------------
       
   506 void CHtiScreenshotServicePlugin::SendTextRecgReplyL(
       
   507                                     const TBool aResult,
       
   508                                     const TRect& aLocation,
       
   509                                     const TInt aFontIndex)
       
   510     {
       
   511     HTI_LOG_FUNC_IN( "SendTextRecgReplyL" );
       
   512     HBufC8* sendMsg = HBufC8::NewL( 10 );
       
   513     CleanupStack::PushL( sendMsg );
       
   514     if ( aResult )
       
   515         {
       
   516         sendMsg->Des().Append( ERspOk );
       
   517         TUint16 co = aLocation.iTl.iX;
       
   518         sendMsg->Des().Append( (TUint8*)(&co), 2 );
       
   519         co = aLocation.iTl.iY;
       
   520         sendMsg->Des().Append( (TUint8*)(&co), 2 );
       
   521         co = aLocation.iBr.iX;
       
   522         sendMsg->Des().Append( (TUint8*)(&co), 2 );
       
   523         co = aLocation.iBr.iY;
       
   524         sendMsg->Des().Append( (TUint8*)(&co), 2 );
       
   525         sendMsg->Des().Append( (TUint8)aFontIndex );
       
   526         }
       
   527     else
       
   528         {
       
   529         sendMsg->Des().Append( ERspNotFound );
       
   530         sendMsg->Des().AppendFill( 0, 5 );
       
   531         }
       
   532 
       
   533     User::LeaveIfError( iDispatcher->DispatchOutgoingMessage(
       
   534                             sendMsg,
       
   535                             KScreenshotServiceUid) );
       
   536 
       
   537     CleanupStack::Pop();
       
   538     HTI_LOG_FUNC_OUT( "SendTextRecgReplyL" );
       
   539     }
       
   540 
       
   541 // ----------------------------------------------------------------------------
       
   542 void CHtiScreenshotServicePlugin::CopyUnicode( TDes & aTo, const TDesC8& aFrom )
       
   543 {
       
   544     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::CopyUnicode" );
       
   545     //aTo.Copy( reinterpret_cast<const TUint16*>(aFrom.Ptr()), aFrom.Length() );
       
   546     TInt len = aFrom.Length()>>1;
       
   547     aTo.SetLength( len );
       
   548     for ( TInt i = 0; i < len; ++i )
       
   549     {
       
   550         aTo[i] = (TUint16)aFrom[i<<1] + (((TUint16)aFrom[(i<<1)+1])<<8);
       
   551     }
       
   552     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::CopyUnicode" );
       
   553 }
       
   554 
       
   555 // ----------------------------------------------------------------------------
       
   556 TInt CHtiScreenshotServicePlugin::ParseString( const TDesC8& aRequest,
       
   557                                         TInt anOffset,
       
   558                                         TBool aUnicode,
       
   559                                         TDes& aResult)
       
   560     {
       
   561     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::ParseString" );
       
   562     //validate parameters
       
   563     //if offset outside the string return empty string
       
   564     if ( anOffset >= aRequest.Size() )
       
   565         {
       
   566         return anOffset;
       
   567         }
       
   568 
       
   569     TInt len = aRequest[ anOffset ];
       
   570     HTI_LOG_FORMAT( "len %d", len );
       
   571 
       
   572     if ( len> aResult.MaxLength() )
       
   573         {
       
   574         return KErrBadDescriptor;
       
   575         }
       
   576 
       
   577     TInt nextOffset = ( aUnicode ? len * 2 : len ) + anOffset + 1;
       
   578     HTI_LOG_FORMAT( "nextOffset %d", nextOffset );
       
   579     HTI_LOG_FORMAT( "reqSize %d", aRequest.Size() );
       
   580     if ( nextOffset > aRequest.Size() )
       
   581         {
       
   582         return KErrArgument;
       
   583         }
       
   584 
       
   585     if ( aUnicode )
       
   586         {
       
   587         //const TUint8* ptr = aRequest.Mid( anOffset + 1, len * 2 ).Ptr();
       
   588         //aResult.Copy( (const TUint16*)ptr, len );
       
   589         CopyUnicode( aResult, aRequest.Mid( anOffset + 1, len * 2 ) );
       
   590         }
       
   591     else
       
   592         {
       
   593         aResult.Copy( aRequest.Mid( anOffset + 1, len ) );
       
   594         }
       
   595 
       
   596     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::ParseString" );
       
   597     return nextOffset;
       
   598     }
       
   599 
       
   600 // ----------------------------------------------------------------------------
       
   601 TInt CHtiScreenshotServicePlugin::ParseFontSpec( const TDesC8& aRequest,
       
   602                     TInt anOffset,
       
   603                     TBool aUnicode,
       
   604                     TFontSpec& aResult)
       
   605     {
       
   606     if ( anOffset >= aRequest.Size() )
       
   607         {
       
   608         return KErrArgument;
       
   609         }
       
   610 
       
   611     //get font name
       
   612     TPtr tn = aResult.iTypeface.iName.Des();
       
   613     TInt offset = ParseString( aRequest,
       
   614                     anOffset,
       
   615                     aUnicode,
       
   616                     tn );
       
   617 
       
   618     if ( offset > anOffset )
       
   619         {
       
   620         HTI_LOG_DES(aResult.iTypeface.iName);
       
   621         //check that we have valid descr
       
   622         if ( offset + 2 <= aRequest.Size() )
       
   623             {
       
   624             aResult.iHeight = ParseInt16( aRequest.Ptr() + offset );
       
   625             HTI_LOG_FORMAT( "font height %d", aResult.iHeight );
       
   626             //check style byte
       
   627             TUint8 style = aRequest[ offset + 2 ];
       
   628             HTI_LOG_FORMAT( "style %d", style );
       
   629 
       
   630             //stroke bit
       
   631             if ( style & EHtiFontAttBold )
       
   632                 {
       
   633                 aResult.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   634                 }
       
   635             else
       
   636                 {
       
   637                 aResult.iFontStyle.SetStrokeWeight(EStrokeWeightNormal);
       
   638                 }
       
   639             //posture
       
   640             if ( style & EHtiFontAttItalic )
       
   641                 {
       
   642                 aResult.iFontStyle.SetPosture(EPostureItalic);
       
   643                 }
       
   644             else
       
   645                 {
       
   646                 aResult.iFontStyle.SetPosture(EPostureUpright);
       
   647                 }
       
   648             //bitmap glyph type
       
   649             if ( style & EHtiFontAttNotAA )
       
   650                 {
       
   651                 aResult.iFontStyle.SetBitmapType( EMonochromeGlyphBitmap );
       
   652                 }
       
   653             else
       
   654                 {
       
   655                 aResult.iFontStyle.SetBitmapType( EAntiAliasedGlyphBitmap );
       
   656                 }
       
   657             //print position
       
   658             if ( style & EHtiFontAttPrintPositionFlag )
       
   659                 {
       
   660                 TInt printPos = style & EHtiFontAttPrintPositionValue;
       
   661                 if ( printPos == KHtiFontAttSuperscriptValue )
       
   662                     {
       
   663                     aResult.iFontStyle.SetPrintPosition( EPrintPosSuperscript );
       
   664                     }
       
   665                 else if ( printPos == KHtiFontAttSubscriptValue )
       
   666                     {
       
   667                     aResult.iFontStyle.SetPrintPosition( EPrintPosSubscript );
       
   668                     }
       
   669                 }
       
   670             else
       
   671                 {
       
   672                 aResult.iFontStyle.SetPrintPosition( EPrintPosNormal );
       
   673                 }
       
   674             return offset + 3;
       
   675             }
       
   676         else
       
   677             {
       
   678             return KErrArgument;
       
   679             }
       
   680         }
       
   681     else
       
   682         {
       
   683         return offset<0?offset:KErrArgument;
       
   684         }
       
   685     }
       
   686 
       
   687 // ----------------------------------------------------------------------------
       
   688 void CHtiScreenshotServicePlugin::ProcessTextRcgMessageL(
       
   689                                     const TDesC8& aMessage)
       
   690     {
       
   691     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::ProcessTextRcgMessageL" );
       
   692     TBool unicode = aMessage[0] & 0x1;
       
   693 
       
   694     TBuf<0xFF> text;
       
   695 
       
   696     TInt offset = ParseString(aMessage, 1, unicode, text);
       
   697 
       
   698     HTI_LOG_FORMAT( "offset %d ", offset );
       
   699     if ( offset > 1 )
       
   700         {
       
   701         HTI_LOG_DES(text);
       
   702 
       
   703         if ( offset + 1 < aMessage.Size() )
       
   704             {
       
   705             TInt numOfFonts = aMessage[ offset ];
       
   706             HTI_LOG_FORMAT( "num of fonts %d", numOfFonts );
       
   707             iFontCache.Reset();
       
   708             TInt nextOffset  = offset + 1;
       
   709             for ( TInt i = 0; i < numOfFonts; ++i )
       
   710                 {
       
   711                 TFontSpec fontSpec;
       
   712                 nextOffset = ParseFontSpec(aMessage,
       
   713                                             nextOffset,
       
   714                                             unicode,
       
   715                                             fontSpec);
       
   716                 if ( nextOffset < 0 )
       
   717                     {
       
   718                     iDispatcher->DispatchOutgoingErrorMessage(
       
   719                         nextOffset,
       
   720                         KErrDescrInvalid,
       
   721                         KScreenshotServiceUid);
       
   722                     return;
       
   723                     }
       
   724                 else
       
   725                     {
       
   726                     iFontCache.Append( fontSpec );
       
   727                     }
       
   728                 }
       
   729 
       
   730             //parameters parsing END
       
   731             //get screenshot
       
   732             TRect empty;
       
   733             CreateBitmapL( empty, ENone );
       
   734 
       
   735             //call text rcg routines
       
   736             TInt fontIndex;
       
   737             TRect resultRect;
       
   738 
       
   739             //recognize text using fonts from iFontCache
       
   740             TBool result = RecognizeTextL( text, resultRect, fontIndex );
       
   741 
       
   742             SendTextRecgReplyL( result, resultRect, fontIndex );
       
   743 
       
   744             delete iScreen;
       
   745             iScreen = NULL;
       
   746             }
       
   747         else
       
   748             {
       
   749             //no fonts data
       
   750             iDispatcher->DispatchOutgoingErrorMessage(
       
   751                         KErrArgument,
       
   752                         KErrDescrInvalid,
       
   753                         KScreenshotServiceUid);
       
   754 
       
   755             }
       
   756         }
       
   757     else if ( offset == 1 )
       
   758         {
       
   759         //empty text
       
   760         iDispatcher->DispatchOutgoingErrorMessage(
       
   761                         KErrArgument,
       
   762                         KErrDescrInvalid,
       
   763                         KScreenshotServiceUid);
       
   764         }
       
   765     else
       
   766         {
       
   767         //error
       
   768         iDispatcher->DispatchOutgoingErrorMessage(
       
   769                         offset,
       
   770                         KErrDescrInvalid,
       
   771                         KScreenshotServiceUid);
       
   772         }
       
   773     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::ProcessTextRcgMessageL" );
       
   774     }
       
   775 
       
   776 // ----------------------------------------------------------------------------
       
   777 void CHtiScreenshotServicePlugin::ProcessTextBitmapMessageL(
       
   778                                     const TDesC8& aMessage)
       
   779     {
       
   780     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::ProcessTextBitmapMessageL" );
       
   781     TBool unicode = aMessage[0] & 0x1;
       
   782 
       
   783     TDisplayMode displayMode = ENone;
       
   784     //check display
       
   785     if ( aMessage.Size() > KScreenDisplayOffset )
       
   786         {
       
   787         displayMode = (TDisplayMode)aMessage[KScreenDisplayOffset];
       
   788         if ( displayMode >= EColorLast )
       
   789             {
       
   790             iDispatcher->DispatchOutgoingErrorMessage(
       
   791                             KErrArgument,
       
   792                             KErrDescrInvalidMode,
       
   793                             KScreenshotServiceUid);
       
   794             return;
       
   795             }
       
   796         }
       
   797 
       
   798     //check mime
       
   799     TPtrC8 mime;
       
   800     if ( aMessage[KScreenMIMEOffset] > 0 &&
       
   801         ( aMessage[KScreenMIMEOffset] + KScreenMIMEOffset+1 ) < aMessage.Size() )
       
   802         {
       
   803         mime.Set( aMessage.Mid(KScreenMIMEOffset+1, aMessage[KScreenMIMEOffset] ) );
       
   804         if ( !IsMIMETypeSupported( mime ) )
       
   805             {
       
   806             iDispatcher->DispatchOutgoingErrorMessage(
       
   807                             KErrArgument,
       
   808                             KErrDescrMIMENotSupported,
       
   809                             KScreenshotServiceUid);
       
   810             return;
       
   811             }
       
   812         }
       
   813     else if ( aMessage[KScreenMIMEOffset] != 0 )
       
   814         {
       
   815         iDispatcher->DispatchOutgoingErrorMessage(
       
   816                         KErrArgument,
       
   817                         KErrDescrInvalidMode,
       
   818                         KScreenshotServiceUid);
       
   819         return;
       
   820         }
       
   821 
       
   822     TBuf<0xFF> text;
       
   823     TInt preTextOffset = KScreenMIMEOffset + aMessage[KScreenMIMEOffset] + 1;
       
   824     TInt offset = ParseString( aMessage, preTextOffset, unicode, text );
       
   825 
       
   826     HTI_LOG_FORMAT( "offset %d ", offset );
       
   827     if ( offset == preTextOffset )
       
   828         {
       
   829         //empty text
       
   830         iDispatcher->DispatchOutgoingErrorMessage(
       
   831                         KErrArgument,
       
   832                         KErrDescrInvalid,
       
   833                         KScreenshotServiceUid);
       
   834         }
       
   835     else if ( offset < preTextOffset )
       
   836         {
       
   837         //error
       
   838         iDispatcher->DispatchOutgoingErrorMessage(
       
   839                         offset,
       
   840                         KErrDescrInvalid,
       
   841                         KScreenshotServiceUid);
       
   842         }
       
   843 
       
   844     HTI_LOG_DES(text);
       
   845     TFontSpec fontSpec;
       
   846     offset = ParseFontSpec(aMessage,
       
   847                             offset,
       
   848                             unicode,
       
   849                             fontSpec);
       
   850     if ( offset < 0 )
       
   851         {
       
   852         iDispatcher->DispatchOutgoingErrorMessage(
       
   853             offset,
       
   854             KErrDescrInvalid,
       
   855             KScreenshotServiceUid);
       
   856 
       
   857         return;
       
   858         }
       
   859 
       
   860     //check colors
       
   861     HTI_LOG_TEXT( "check colors" );
       
   862     if ( offset + 2*4 != aMessage.Size() )
       
   863         {
       
   864         iDispatcher->DispatchOutgoingErrorMessage(
       
   865             offset,
       
   866             KErrDescrInvalid,
       
   867             KScreenshotServiceUid);
       
   868         return;
       
   869         }
       
   870 
       
   871     //extract colors
       
   872     TUint32 fgColor = ParseInt32( aMessage.Ptr() + offset );
       
   873     TUint32 bgColor = ParseInt32( aMessage.Ptr() + offset + 4 );
       
   874     HTI_LOG_FORMAT( "FG color %d", fgColor );
       
   875     HTI_LOG_FORMAT( "BG color %d", bgColor );
       
   876 
       
   877     //END parsing
       
   878     //generate and return bitmap
       
   879     CFont* useFont;
       
   880 
       
   881     User::LeaveIfError( iScreenDevice->GetNearestFontToDesignHeightInPixels(
       
   882                             useFont, fontSpec ) );
       
   883 
       
   884     TDisplayMode dm = displayMode==ENone || displayMode==0?
       
   885                                         iScreenDevice->DisplayMode():
       
   886                                         displayMode;
       
   887 
       
   888 
       
   889     delete iScreen;
       
   890     iScreen = NULL;
       
   891     iScreen = CHtiTextRcg::GetTextBitmapL(
       
   892                             text,
       
   893                             useFont,
       
   894                             TRgb( fgColor ),
       
   895                             TRgb( bgColor ),
       
   896                             dm );
       
   897 
       
   898     iScreenDevice->ReleaseFont( useFont );
       
   899 
       
   900     //Encode iBitmap
       
   901     iCompress = EFalse;
       
   902     if ( mime.Length() == 0 )
       
   903         {
       
   904         EncodeBitmapL(); //use default encoder BMP
       
   905         }
       
   906     else
       
   907         {
       
   908         HTI_LOG_DES( mime );
       
   909         EncodeBitmapL( mime );
       
   910         }
       
   911 
       
   912     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::ProcessTextBitmapMessageL" );
       
   913     }
       
   914 
       
   915 /*
       
   916 // ----------------------------------------------------------------------------
       
   917 TBool CHtiScreenshotServicePlugin::RecognizeTextAllL(
       
   918                         const TDesC& aText,
       
   919                         TPoint& aResult)
       
   920     {
       
   921     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::RecognizeTextAllL" );
       
   922 
       
   923     TSize screenRect = iScreenDevice->SizeInPixels();
       
   924     TInt nofTF = iScreenDevice->NumTypefaces();
       
   925     HTI_LOG_FORMAT( "Number of typefaces %d", nofTF );
       
   926     TBool returnValue = EFalse;
       
   927     for ( TInt i = 0; i < nofTF; ++i )
       
   928         {
       
   929         TTypefaceSupport tf;
       
   930         iScreenDevice->TypefaceSupport(tf, i);
       
   931 
       
   932         HTI_LOG_DES(tf.iTypeface.iName);
       
   933 
       
   934         if ( tf.iIsScalable )
       
   935             {
       
   936             //iterate throuh heighes
       
   937 
       
   938             HTI_LOG_FORMAT( "num of heighs %d", tf.iNumHeights );
       
   939             HTI_LOG_FORMAT( "min h in tw %d", tf.iMinHeightInTwips );
       
   940             HTI_LOG_FORMAT( "max h in tw %d", tf.iMaxHeightInTwips );
       
   941             HTI_LOG_FORMAT( "scalable %d", tf.iIsScalable );
       
   942 
       
   943             HTI_LOG_TEXT( "-----------------------" );
       
   944 
       
   945             TInt minHeight = Max(tf.iMinHeightInTwips, KFonHeighMin );
       
   946             TInt maxHeight = Min(tf.iMaxHeightInTwips, KFonHeighMax );
       
   947 
       
   948             if ( minHeight > maxHeight )
       
   949                 {
       
   950                 continue;
       
   951                 }
       
   952 
       
   953             for ( TInt v = 0; v < 2; ++v )
       
   954                 {
       
   955                 TInt lastFontHeight = 0;
       
   956                 for ( TInt fh = minHeight; fh <= maxHeight; ++fh )
       
   957                     {
       
   958                     TFontSpec fs( tf.iTypeface.iName, fh );
       
   959                     fs.iFontStyle.SetBitmapType( EAntiAliasedGlyphBitmap );
       
   960                     switch ( v )
       
   961                         {
       
   962                         case 1:
       
   963                             {
       
   964                             fs.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   965                             HTI_LOG_TEXT( "BOLD" );
       
   966                             }
       
   967                             break;
       
   968                         default:
       
   969                             {
       
   970                             HTI_LOG_TEXT( "DEFAULT" );
       
   971                             }
       
   972                         }
       
   973                     HTI_LOG_FORMAT( "hh  %d", fh );
       
   974 
       
   975                     CFont* useFont = NULL;
       
   976 
       
   977                     iScreenDevice->GetNearestFontToDesignHeightInTwips(useFont, fs);
       
   978 
       
   979                     if ( screenRect.iHeight < useFont->HeightInPixels() ||
       
   980                          screenRect.iWidth < useFont->MaxNormalCharWidthInPixels()
       
   981                         )
       
   982                         {
       
   983                         break;
       
   984                         }
       
   985 
       
   986                     if ( useFont->HeightInPixels() == lastFontHeight )
       
   987                         {
       
   988                         continue;
       
   989                         }
       
   990 
       
   991 
       
   992                     lastFontHeight = useFont->HeightInPixels();
       
   993 
       
   994                     returnValue = iTextRcg.RecognizeTextL(
       
   995                                                 iScreen,
       
   996                                                 aText,
       
   997                                                 useFont,
       
   998                                                 aResult);
       
   999                     //HTI_LOG_TEXT( "ReleaseFont" );
       
  1000                     iScreenDevice->ReleaseFont(useFont);
       
  1001 
       
  1002                     if ( returnValue )
       
  1003                         {
       
  1004                         HTI_LOG_TEXT( "Found" );
       
  1005                         HTI_LOG_DES( aText );
       
  1006                         HTI_LOG_DES( tf.iTypeface.iName );
       
  1007                         HTI_LOG_FORMAT( "Font height in twips %d", fh );
       
  1008                         HTI_LOG_FORMAT( "X %d", aResult.iX );
       
  1009                         HTI_LOG_FORMAT( "Y %d", aResult.iY );
       
  1010                         return returnValue;
       
  1011                         }
       
  1012                     }
       
  1013                 }
       
  1014             }
       
  1015         else
       
  1016             {//non scal. font
       
  1017             TFontSpec fs( tf.iTypeface.iName,0 ); //height doesn't matter for
       
  1018                                                 //not scalable font
       
  1019 
       
  1020             CFont* useFont = NULL;
       
  1021             //HTI_LOG_TEXT( "GetFont" );
       
  1022             iScreenDevice->GetNearestFontToDesignHeightInTwips( useFont, fs );
       
  1023 
       
  1024             returnValue = iTextRcg.RecognizeTextL(
       
  1025                                         iScreen,
       
  1026                                         aText,
       
  1027                                         useFont,
       
  1028                                         aResult );
       
  1029             //HTI_LOG_TEXT( "ReleaseFont" );
       
  1030             iScreenDevice->ReleaseFont( useFont );
       
  1031 
       
  1032             if ( returnValue )
       
  1033                 {
       
  1034                 HTI_LOG_TEXT( "Found" );
       
  1035                 HTI_LOG_DES( aText );
       
  1036                 HTI_LOG_DES(tf.iTypeface.iName );
       
  1037                 HTI_LOG_FORMAT( "X %d", aResult.iX );
       
  1038                 HTI_LOG_FORMAT( "Y %d", aResult.iY );
       
  1039                 return returnValue;
       
  1040                 }
       
  1041             }
       
  1042         }
       
  1043 
       
  1044     //
       
  1045 
       
  1046     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::RecognizeTextAllL" );
       
  1047     //return returnValue;
       
  1048     return EFalse;
       
  1049     }
       
  1050 */
       
  1051 
       
  1052 // ----------------------------------------------------------------------------
       
  1053 TBool CHtiScreenshotServicePlugin::RecognizeTextL(
       
  1054                         const TDesC& aText,
       
  1055                         TRect& aResult,
       
  1056                         TInt& aFontIndex)
       
  1057     {
       
  1058     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::RecognizeTextL" );
       
  1059 
       
  1060     TSize screenRect = iScreenDevice->SizeInPixels();
       
  1061     TInt cacheSize = iFontCache.Count();
       
  1062     HTI_LOG_FORMAT( "Cache size %d", cacheSize );
       
  1063 
       
  1064     TBool returnValue = EFalse;
       
  1065     for ( TInt i = 0; i < cacheSize; ++i )
       
  1066         {
       
  1067         CFont* useFont = NULL;
       
  1068 
       
  1069         User::LeaveIfError(iScreenDevice->GetNearestFontToDesignHeightInPixels(
       
  1070                                 useFont, iFontCache[i] ) );
       
  1071         if ( iFontCache[i].iFontStyle.BitmapType()==EAntiAliasedGlyphBitmap )
       
  1072             {
       
  1073             iTextRcg.SetHint( EHintEdge );
       
  1074             }
       
  1075         else
       
  1076             {
       
  1077             iTextRcg.SetHint( EHintNone );
       
  1078             }
       
  1079 
       
  1080         //check that font in valid size
       
  1081         if ( screenRect.iHeight < useFont->HeightInPixels() ||
       
  1082              screenRect.iWidth < useFont->MaxNormalCharWidthInPixels()
       
  1083             )
       
  1084             {
       
  1085             break;
       
  1086             }
       
  1087 
       
  1088         returnValue = iTextRcg.RecognizeTextL( iScreen, aText, useFont,
       
  1089                 aResult );
       
  1090 
       
  1091         iScreenDevice->ReleaseFont( useFont );
       
  1092 
       
  1093         if ( returnValue )
       
  1094             {
       
  1095             HTI_LOG_FORMAT( "Found! fontIndex %d", i );
       
  1096             HTI_LOG_DES( aText );
       
  1097             HTI_LOG_DES( iFontCache[i].iTypeface.iName );
       
  1098             HTI_LOG_FORMAT( "TL X %d", aResult.iTl.iX );
       
  1099             HTI_LOG_FORMAT( "TL Y %d", aResult.iTl.iY );
       
  1100             HTI_LOG_FORMAT( "BR X %d", aResult.iBr.iX );
       
  1101             HTI_LOG_FORMAT( "BR Y %d", aResult.iBr.iY );
       
  1102             aFontIndex = i;
       
  1103             return returnValue;
       
  1104             }
       
  1105         }
       
  1106 
       
  1107     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::RecognizeTextL" );
       
  1108     return EFalse;
       
  1109     }
       
  1110 
       
  1111 /*
       
  1112 TBool CHtiScreenshotServicePlugin::RecognizeTextL(
       
  1113                         const TDesC& aText,
       
  1114                         const TDesC& aTypeface,
       
  1115                         TPoint& aResult)
       
  1116     {
       
  1117     HTI_LOG_FUNC_IN( "RecognizeTextL typeface" );
       
  1118     //const CFont* fontUsed = NULL;// AknLayoutUtils::FontFromName(aTypeface);
       
  1119     CFont* useFont = NULL;
       
  1120     TFontSpec fs(aTypeface, 0);
       
  1121 
       
  1122     iScreenDevice->GetNearestFontInTwips(useFont, fs);
       
  1123 
       
  1124     TBool returnValue = iTextRcg.RecognizeTextL(iScreen, aText, useFont, aResult);
       
  1125 
       
  1126 HTI_LOG_FUNC_OUT( "RecognizeTextL" );
       
  1127     return returnValue;
       
  1128 }
       
  1129 */
       
  1130 
       
  1131 // ----------------------------------------------------------------------------
       
  1132 void CHtiScreenshotServicePlugin::ProcessMessageL(const TDesC8& aMessage,
       
  1133                 THtiMessagePriority /*aPriority*/)
       
  1134     {
       
  1135     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::ProcessMessage");
       
  1136 
       
  1137     if ( iICLHandler )
       
  1138         {
       
  1139         if ( iICLHandler->IsActive() || iEncodedBitmap)
       
  1140             {
       
  1141             User::Leave( KErrInUse );
       
  1142             }
       
  1143         }
       
  1144 
       
  1145     if ( iSeriesShot->IsOngoing() )
       
  1146         User::Leave( KErrInUse );
       
  1147 
       
  1148     // update the current screen mode
       
  1149     TPixelsAndRotation currentPixelsAndRotation;
       
  1150     iScreenDevice->GetScreenModeSizeAndRotation(
       
  1151             iScreenDevice->CurrentScreenMode(), currentPixelsAndRotation );
       
  1152     iScreenDevice->SetScreenSizeAndRotation( currentPixelsAndRotation );
       
  1153 
       
  1154     if ( aMessage.Length() > 0 )
       
  1155         {
       
  1156         // set/reset delta capture status
       
  1157         iDeltaCapture = ( aMessage[0] & ECmdDeltaCaptureMask ) ? ETrue : EFalse;
       
  1158         if ( iDeltaCapture )
       
  1159             {
       
  1160             HTI_LOG_TEXT( "DeltaCapture ETrue" );
       
  1161             }
       
  1162 
       
  1163         //if text recogn call separate handler
       
  1164         if ( aMessage[0] == ECmdTextRcg ||
       
  1165              aMessage[0] == ECmdTextRcg_u )
       
  1166             {
       
  1167             ProcessTextRcgMessageL( aMessage );
       
  1168             return;
       
  1169             }
       
  1170         else if ( aMessage[0] == ECmdTextBitmap ||
       
  1171                   aMessage[0] == ECmdTextBitmap_u )
       
  1172             {
       
  1173             ProcessTextBitmapMessageL( aMessage );
       
  1174             return;
       
  1175             }
       
  1176 
       
  1177         iCompress = ( aMessage[0] == ECmdScreenZip ) ||
       
  1178                     ( aMessage[0] == ECmdScreenRegionZip ) ||
       
  1179                     ( aMessage[0] == ECmdScreenZipSeries ) ||
       
  1180                     ( aMessage[0] == ECmdScreenRegionZipSeries ) ||
       
  1181                     ( aMessage[0] == ECmdDeltaScreenZip ) ||
       
  1182                     ( aMessage[0] == ECmdDeltaScreenRegionZip );
       
  1183 
       
  1184         HTI_LOG_FORMAT( "cmd 0x%x", aMessage[0] );
       
  1185         TPtrC8 mime;
       
  1186 
       
  1187         switch ( aMessage[0] )
       
  1188             {
       
  1189             case ECmdScreen:
       
  1190             case ECmdScreenZip:
       
  1191             case ECmdDeltaScreen:
       
  1192             case ECmdDeltaScreenZip:
       
  1193                 {
       
  1194                 TRect empty;
       
  1195                 TDisplayMode displayMode = ENone;
       
  1196                 //check display
       
  1197                 if ( aMessage.Length() > KScreenDisplayOffset )
       
  1198                     {
       
  1199                     displayMode = ( TDisplayMode ) aMessage[KScreenDisplayOffset];
       
  1200                     if ( displayMode >= EColorLast )
       
  1201                         {
       
  1202                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1203                                         KErrArgument,
       
  1204                                         KErrDescrInvalidMode,
       
  1205                                         KScreenshotServiceUid );
       
  1206                         return;
       
  1207                         }
       
  1208                     }
       
  1209 
       
  1210                 bool screenNumberSet = false;
       
  1211                 //check screen number
       
  1212                 if ( (aMessage.Length() > KScreenScreenNumber) && 
       
  1213                         ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)))
       
  1214                     {
       
  1215                     TInt screenNumber = aMessage[aMessage.Length()-1];
       
  1216                     HTI_LOG_FORMAT( "set screen number: %d", screenNumber );
       
  1217                     screenNumberSet = true;
       
  1218                     TInt screens;
       
  1219                     TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
       
  1220                     if(ret)
       
  1221                         {
       
  1222                         HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
       
  1223                         User::Leave(ret);
       
  1224                         }
       
  1225                     HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
       
  1226                     if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
       
  1227                         {
       
  1228                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1229                                 KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
       
  1230                         return;
       
  1231                         }
       
  1232                     SetScreenNumber(screenNumber);
       
  1233                     }
       
  1234 
       
  1235                 CreateBitmapL( empty, displayMode );
       
  1236 
       
  1237                 //check mime
       
  1238                 if ( aMessage.Length() > KScreenMIMEOffset )
       
  1239                     {
       
  1240                     if(screenNumberSet)
       
  1241                         {
       
  1242                         mime.Set( aMessage.Mid( KScreenMIMEOffset, aMessage.Length()-1-KScreenMIMEOffset ) );
       
  1243                         }
       
  1244                     else
       
  1245                         {
       
  1246                         mime.Set( aMessage.Mid( KScreenMIMEOffset ) );
       
  1247                         }
       
  1248                     if ( !IsMIMETypeSupported( mime ) )
       
  1249                         {
       
  1250                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1251                                         KErrArgument,
       
  1252                                         KErrDescrMIMENotSupported,
       
  1253                                         KScreenshotServiceUid );
       
  1254                         return;
       
  1255                         }
       
  1256                     }
       
  1257                 }              
       
  1258                 break;
       
  1259 
       
  1260             case ECmdScreenRegion:
       
  1261             case ECmdScreenRegionZip:
       
  1262             case ECmdDeltaScreenRegion:
       
  1263             case ECmdDeltaScreenRegionZip:
       
  1264                 {
       
  1265                 //check screen number
       
  1266                 bool screenNumberSet = false;
       
  1267                 if ( (aMessage.Length() > KRegionScreenNumber) && 
       
  1268                         ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)))
       
  1269                     {
       
  1270                     TInt screenNumber = aMessage[aMessage.Length()-1];
       
  1271                     screenNumberSet = true;
       
  1272                     TInt screens;
       
  1273                     TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
       
  1274                     if(ret)
       
  1275                         {
       
  1276                         HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
       
  1277                         User::Leave(ret);
       
  1278                         }
       
  1279                     HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
       
  1280                     if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
       
  1281                         {
       
  1282                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1283                                 KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
       
  1284                         return;
       
  1285                         }
       
  1286                     SetScreenNumber(screenNumber);
       
  1287                     }
       
  1288 
       
  1289                 if ( aMessage.Length() >= KMinScreenRegionCmdLength )
       
  1290                     {
       
  1291                     TRect region;
       
  1292                     const TUint8* ptr = aMessage.Ptr();
       
  1293                     region.iTl.iX = ParseInt16( ptr + 1 );
       
  1294                     region.iTl.iY = ParseInt16( ptr + 3 );
       
  1295                     region.iBr.iX = ParseInt16( ptr + 5 );
       
  1296                     region.iBr.iY = ParseInt16( ptr + 7 );
       
  1297 
       
  1298                     //check empty and normmalizaed
       
  1299                     if ( !region.IsNormalized() )
       
  1300                         {
       
  1301                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1302                                         KErrArgument,
       
  1303                                         KErrDescrRegionNotNormailized,
       
  1304                                         KScreenshotServiceUid );
       
  1305                         return;
       
  1306                         }
       
  1307 
       
  1308                     if ( region.IsEmpty() )
       
  1309                         {
       
  1310                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1311                                         KErrArgument,
       
  1312                                         KErrDescrRegiontEmpty,
       
  1313                                         KScreenshotServiceUid );
       
  1314                         return;
       
  1315                         }
       
  1316 
       
  1317                     TRect screenRect;
       
  1318                     screenRect.iBr = iScreenDevice->SizeInPixels().AsPoint();
       
  1319                     screenRect.iBr.iX++; //TRect::Contains() omitts
       
  1320                     screenRect.iBr.iY++; //right bottom rows
       
  1321 
       
  1322                     TDisplayMode displayMode = ENone;
       
  1323                     if ( aMessage.Length() > KRegionDisplayOffset )
       
  1324                         {
       
  1325                         displayMode = ( TDisplayMode ) aMessage[KRegionDisplayOffset];
       
  1326                         if ( displayMode >= EColorLast )
       
  1327                             {
       
  1328                             iDispatcher->DispatchOutgoingErrorMessage(
       
  1329                                             KErrArgument,
       
  1330                                             KErrDescrInvalidMode,
       
  1331                                             KScreenshotServiceUid );
       
  1332                             return;
       
  1333                             }
       
  1334                         }
       
  1335 
       
  1336                     if ( screenRect.Contains( region.iTl ) &&
       
  1337                          screenRect.Contains( region.iBr ) )
       
  1338                         {
       
  1339                         CreateBitmapL( region, displayMode );
       
  1340                         }
       
  1341                     else
       
  1342                         {
       
  1343                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1344                                         KErrArgument,
       
  1345                                         KErrDescrRegionOutOfScreen,
       
  1346                                         KScreenshotServiceUid );
       
  1347                         return;
       
  1348                         }
       
  1349                     
       
  1350                     //check mime
       
  1351                     if ( aMessage.Length() > KRegionMIMEOffset )
       
  1352                         {
       
  1353                         if(!screenNumberSet)
       
  1354                             {
       
  1355                             mime.Set( aMessage.Mid( KRegionMIMEOffset ) );
       
  1356                             }
       
  1357                         else
       
  1358                             {
       
  1359                             mime.Set( aMessage.Mid( KRegionMIMEOffset, aMessage.Length()-1-KRegionMIMEOffset ) );
       
  1360                             }
       
  1361                         if ( !IsMIMETypeSupported( mime ) )
       
  1362                             {
       
  1363                             iDispatcher->DispatchOutgoingErrorMessage(
       
  1364                                             KErrArgument,
       
  1365                                             KErrDescrMIMENotSupported,
       
  1366                                             KScreenshotServiceUid );
       
  1367                             return;
       
  1368                             }
       
  1369                         }
       
  1370 
       
  1371                     }
       
  1372                 else
       
  1373                     {
       
  1374                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1375                                     KErrArgument,
       
  1376                                     KErrDescrInvalid,
       
  1377                                     KScreenshotServiceUid );
       
  1378                     return;
       
  1379                     }
       
  1380                 }
       
  1381                 break;
       
  1382 
       
  1383             case ECmdScreenSeries:
       
  1384             case ECmdScreenZipSeries:
       
  1385                 {
       
  1386                 if ( aMessage.Length() < KMinSeriesCmdLength )
       
  1387                     {
       
  1388                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1389                                     KErrArgument,
       
  1390                                     KErrDescrInvalid,
       
  1391                                     KScreenshotServiceUid );
       
  1392                     return;
       
  1393                     }
       
  1394                 
       
  1395                 bool screenNumberSet = false;
       
  1396                 if ( (aMessage.Length() > KSeriesScreenNumber) && 
       
  1397                         ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)) )
       
  1398                     {
       
  1399                     TInt screenNumber = aMessage[aMessage.Length()-1];
       
  1400                     screenNumberSet = true;
       
  1401                     TInt screens;
       
  1402                     TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
       
  1403                     if(ret)
       
  1404                         {
       
  1405                         HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
       
  1406                         User::Leave(ret);
       
  1407                         }
       
  1408                     HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
       
  1409                     if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
       
  1410                         {
       
  1411                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1412                                 KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
       
  1413                         return;
       
  1414                         }
       
  1415                     SetScreenNumber(screenNumber);
       
  1416                     }
       
  1417 
       
  1418                 TInt duration = ParseInt32( aMessage.Ptr() + KSeriesDurationOffset );
       
  1419                 TInt interval = ParseInt32( aMessage.Ptr() + KSeriesIntervalOffset );
       
  1420 
       
  1421                 TDisplayMode displayMode = ( TDisplayMode ) aMessage[KSeriesDisplayOffset];
       
  1422                 if ( displayMode >= EColorLast )
       
  1423                     {
       
  1424                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1425                                     KErrArgument,
       
  1426                                     KErrDescrInvalidMode,
       
  1427                                     KScreenshotServiceUid );
       
  1428                     return;
       
  1429                     }
       
  1430                 
       
  1431                 if ( aMessage.Length() > KSeriesMIMEOffset )
       
  1432                     {
       
  1433                     if(screenNumberSet)
       
  1434                         {
       
  1435                         mime.Set( aMessage.Mid( KSeriesMIMEOffset, aMessage.Length()-1-KSeriesMIMEOffset ) );
       
  1436                         }
       
  1437                     else
       
  1438                         {
       
  1439                         mime.Set( aMessage.Mid( KSeriesMIMEOffset ) );
       
  1440                         }
       
  1441                     if ( !IsMIMETypeSupported( mime ) )
       
  1442                         {
       
  1443                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1444                                         KErrArgument,
       
  1445                                         KErrDescrMIMENotSupported,
       
  1446                                         KScreenshotServiceUid );
       
  1447                         return;
       
  1448                         }
       
  1449                     }
       
  1450 
       
  1451                 TRect empty;
       
  1452                 iSeriesShot->StartL( duration, interval, displayMode, empty, mime );
       
  1453                 }
       
  1454                 return;
       
  1455 
       
  1456             case ECmdScreenRegionSeries:
       
  1457             case ECmdScreenRegionZipSeries:
       
  1458                 {
       
  1459                 bool screenNumberSet = false;
       
  1460                 if ( (aMessage.Length() > KRegionSeriesScreenNumber) && 
       
  1461                         ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)) )
       
  1462                     {
       
  1463                     TInt screenNumber = aMessage[aMessage.Length()-1];
       
  1464                     screenNumberSet = true;
       
  1465                     TInt screens;
       
  1466                     TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
       
  1467                     if(ret)
       
  1468                         {
       
  1469                         HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
       
  1470                         User::Leave(ret);
       
  1471                         }
       
  1472                     HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
       
  1473                     if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
       
  1474                         {
       
  1475                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1476                                 KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
       
  1477                         return;
       
  1478                         }
       
  1479                     SetScreenNumber(screenNumber);
       
  1480                     }
       
  1481 
       
  1482                 if ( aMessage.Length() < KMinRegionSeriesCmdLength )
       
  1483                     {
       
  1484                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1485                                     KErrArgument,
       
  1486                                     KErrDescrInvalid,
       
  1487                                     KScreenshotServiceUid);
       
  1488                     return;
       
  1489                     }
       
  1490                 TInt duration = ParseInt32( aMessage.Ptr() + KSeriesDurationOffset );
       
  1491                 TInt interval = ParseInt32( aMessage.Ptr() + KSeriesIntervalOffset );
       
  1492 
       
  1493                 TDisplayMode displayMode = ( TDisplayMode ) aMessage[KSeriesDisplayOffset];
       
  1494                 if ( displayMode >= EColorLast )
       
  1495                     {
       
  1496                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1497                                     KErrArgument,
       
  1498                                     KErrDescrInvalidMode,
       
  1499                                     KScreenshotServiceUid );
       
  1500                     return;
       
  1501                     }
       
  1502 
       
  1503                 TRect region;
       
  1504                 const TUint8* ptr = aMessage.Ptr();
       
  1505                 region.iTl.iX = ParseInt16( ptr + KRegionSeriesTlX );
       
  1506                 region.iTl.iY = ParseInt16( ptr + KRegionSeriesTlY );
       
  1507                 region.iBr.iX = ParseInt16( ptr + KRegionSeriesBlX );
       
  1508                 region.iBr.iY = ParseInt16( ptr + KRegionSeriesBlY );
       
  1509 
       
  1510                 //check empty and normmalizaed
       
  1511                 if ( !region.IsNormalized() )
       
  1512                     {
       
  1513                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1514                                     KErrArgument,
       
  1515                                     KErrDescrRegionNotNormailized,
       
  1516                                     KScreenshotServiceUid );
       
  1517                     return;
       
  1518                     }
       
  1519 
       
  1520                 if ( region.IsEmpty() )
       
  1521                     {
       
  1522                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1523                                     KErrArgument,
       
  1524                                     KErrDescrRegiontEmpty,
       
  1525                                     KScreenshotServiceUid );
       
  1526                     return;
       
  1527                     }
       
  1528 
       
  1529                 TRect screenRect;
       
  1530                 screenRect.iBr = iScreenDevice->SizeInPixels().AsPoint();
       
  1531                 screenRect.iBr.iX++; //TRect::Contains() omitts
       
  1532                 screenRect.iBr.iY++; //right bottom rows
       
  1533 
       
  1534                 if ( !screenRect.Contains( region.iTl ) ||
       
  1535                      !screenRect.Contains( region.iBr ) )
       
  1536                     {
       
  1537                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1538                                     KErrArgument,
       
  1539                                     KErrDescrRegionOutOfScreen,
       
  1540                                     KScreenshotServiceUid );
       
  1541                     return;
       
  1542                     }
       
  1543                 
       
  1544                 if ( aMessage.Length() > KRegionSeriesMIMEOffset )
       
  1545                     {
       
  1546                     if(screenNumberSet)
       
  1547                         {
       
  1548                         mime.Set( aMessage.Mid( KRegionSeriesMIMEOffset, aMessage.Length()-1-KRegionSeriesMIMEOffset ) );
       
  1549                         }
       
  1550                     else
       
  1551                         {
       
  1552                         mime.Set( aMessage.Mid( KRegionSeriesMIMEOffset ) );
       
  1553                         }
       
  1554                     if ( !IsMIMETypeSupported( mime ) )
       
  1555                         {
       
  1556                         iDispatcher->DispatchOutgoingErrorMessage(
       
  1557                                         KErrArgument,
       
  1558                                         KErrDescrMIMENotSupported,
       
  1559                                         KScreenshotServiceUid );
       
  1560                         return;
       
  1561                         }
       
  1562                     }
       
  1563 
       
  1564                 iSeriesShot->StartL( duration, interval, displayMode, region, mime );
       
  1565                 }
       
  1566                 return;
       
  1567 
       
  1568             case ECmdSelectScreen:
       
  1569                 {
       
  1570                 if ( aMessage.Length() != KSelectScreenCmdLength )
       
  1571                     {
       
  1572                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1573                                     KErrArgument,
       
  1574                                     KErrDescrInvalid,
       
  1575                                     KScreenshotServiceUid );
       
  1576                     return;
       
  1577                     }
       
  1578 
       
  1579                 TInt screenNr = aMessage[KScreenNrOffset];
       
  1580 
       
  1581                 TInt screens;
       
  1582                 TInt ret=HAL::Get( HAL::EDisplayNumberOfScreens, screens );
       
  1583                 if ( ret )
       
  1584                     {
       
  1585                     HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
       
  1586                     User::Leave( ret );
       
  1587                     }
       
  1588 
       
  1589 
       
  1590                 if ( ( screenNr > screens - 1 ) || ( screenNr < 0 ) )
       
  1591                     {
       
  1592                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1593                                     KErrArgument,
       
  1594                                     KErrDescrScreenNotSupported,
       
  1595                                     KScreenshotServiceUid );
       
  1596                     return;
       
  1597                     }
       
  1598 
       
  1599 
       
  1600                 HTI_LOG_FORMAT( "Number of screens %d", screens );
       
  1601                 HTI_LOG_FORMAT( "Setting to screen index %d", screenNr );
       
  1602 
       
  1603                 // Clear the previous delta bitmap to avoid error
       
  1604                 iPreviousBitmap->Reset();
       
  1605 
       
  1606                 // delete old screendevice and create a new one
       
  1607                 delete iScreenDevice;
       
  1608                 iScreenDevice = NULL;
       
  1609                 iScreenDevice = new ( ELeave ) CWsScreenDevice( iWs );
       
  1610                 User::LeaveIfError( iScreenDevice->Construct( screenNr ) );
       
  1611 
       
  1612                 TBuf8<1> okMsg;
       
  1613                 okMsg.Append( ECmdSelectScreen );
       
  1614                 iDispatcher->DispatchOutgoingMessage(
       
  1615                     okMsg.AllocL(), KScreenshotServiceUid );
       
  1616                 }
       
  1617                 return;
       
  1618 
       
  1619             case ECmdDeltaScreenReset:
       
  1620                 {
       
  1621                 if ( aMessage.Length() != KDeltaResetCmdLength )
       
  1622                     {
       
  1623                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1624                                     KErrArgument,
       
  1625                                     KErrDescrInvalid,
       
  1626                                     KScreenshotServiceUid );
       
  1627                     return;
       
  1628                     }
       
  1629 
       
  1630                 iPreviousBitmap->Reset();
       
  1631                 TBuf8<1> okMsg;
       
  1632                 okMsg.Append( ECmdDeltaScreenReset );
       
  1633                 iDispatcher->DispatchOutgoingMessage(
       
  1634                     okMsg.AllocL(), KScreenshotServiceUid );
       
  1635                 }
       
  1636                 return;
       
  1637 
       
  1638             case ECmdScreenMode:
       
  1639                 {
       
  1640                 if ( aMessage.Length() != KScreenModeCmdLength )
       
  1641                     {
       
  1642                     iDispatcher->DispatchOutgoingErrorMessage(
       
  1643                                     KErrArgument,
       
  1644                                     KErrDescrInvalid,
       
  1645                                     KScreenshotServiceUid );
       
  1646                     return;
       
  1647                     }
       
  1648 
       
  1649                 TInt focusScreen = iWs.GetFocusScreen();
       
  1650                 TPixelsAndRotation sizeAndRotation;
       
  1651                 TDisplayMode mode = ENone;
       
  1652                 TInt thisScreen = iScreenDevice->GetScreenNumber();
       
  1653                 iScreenDevice->GetDefaultScreenSizeAndRotation( sizeAndRotation );
       
  1654                 mode = iScreenDevice->DisplayMode();
       
  1655 
       
  1656                 HTI_LOG_FORMAT( "This screen   = %d", thisScreen );
       
  1657                 HTI_LOG_FORMAT( "Screen width  = %d", sizeAndRotation.iPixelSize.iWidth );
       
  1658                 HTI_LOG_FORMAT( "Screen height = %d", sizeAndRotation.iPixelSize.iHeight );
       
  1659                 HTI_LOG_FORMAT( "Rotation      = %d", sizeAndRotation.iRotation );
       
  1660                 HTI_LOG_FORMAT( "Display mode  = %d", mode );
       
  1661                 HTI_LOG_FORMAT( "Focus screen  = %d", focusScreen );
       
  1662                 TBuf8<8> respMsg;
       
  1663                 respMsg.Append( thisScreen );
       
  1664                 respMsg.Append( ( TUint8* )( &( sizeAndRotation.iPixelSize.iWidth ) ), 2 );
       
  1665                 respMsg.Append( ( TUint8* )( &( sizeAndRotation.iPixelSize.iHeight ) ), 2 );
       
  1666                 respMsg.Append( sizeAndRotation.iRotation );
       
  1667                 respMsg.Append( mode );
       
  1668                 respMsg.Append( focusScreen );
       
  1669                 iDispatcher->DispatchOutgoingMessage(
       
  1670                     respMsg.AllocL(), KScreenshotServiceUid );
       
  1671                 }
       
  1672                 return;
       
  1673            case ECmdRotateScreen:
       
  1674                {
       
  1675                if (aMessage.Length() != KRotateScreenCmdLength)
       
  1676                    {
       
  1677                    iDispatcher->DispatchOutgoingErrorMessage(KErrArgument,
       
  1678                            KErrDescrInvalid, KScreenshotServiceUid);
       
  1679                    return;
       
  1680                    }
       
  1681                HandleRotateScreen(aMessage.Right(aMessage.Length() -1));
       
  1682                return;
       
  1683                }
       
  1684             default:
       
  1685                 //Error: unknown command
       
  1686                 iDispatcher->DispatchOutgoingErrorMessage(
       
  1687                                 KErrArgument,
       
  1688                                 KErrDescrUnknownCommand,
       
  1689                                 KScreenshotServiceUid );
       
  1690                 return;
       
  1691             } // switch
       
  1692 
       
  1693         //Encode iBitmap
       
  1694         if ( mime.Length() == 0 )
       
  1695             {
       
  1696             EncodeBitmapL(); //use default encoder BMP
       
  1697             }
       
  1698         else
       
  1699             {
       
  1700             HTI_LOG_DES( mime );
       
  1701             EncodeBitmapL( mime );
       
  1702             }
       
  1703         }
       
  1704     else
       
  1705         {
       
  1706         //error: empty request
       
  1707         iDispatcher->DispatchOutgoingErrorMessage(
       
  1708                         KErrArgument,
       
  1709                         KErrDescrUnknownCommand,
       
  1710                         KScreenshotServiceUid );
       
  1711         }
       
  1712 
       
  1713     HTI_LOG_FUNC_OUT( "HtiScreenshotServicePlugin::ProcessMessage" );
       
  1714     }
       
  1715 
       
  1716 // ----------------------------------------------------------------------------
       
  1717 void CHtiScreenshotServicePlugin::HandleRotateScreen(const TDesC8& aData)
       
  1718     {
       
  1719     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::HandleRotateScreen" );
       
  1720              
       
  1721     TInt orientation = aData[0];
       
  1722     if (orientation > 1 || orientation < 0)
       
  1723         {
       
  1724         iDispatcher->DispatchOutgoingErrorMessage(KErrArgument,
       
  1725                 KErrDescrInvalid, KScreenshotServiceUid);
       
  1726         return;
       
  1727         }
       
  1728 
       
  1729     TBool isLandScape = orientation;
       
  1730 
       
  1731     RWsSession ws;
       
  1732     User::LeaveIfError(ws.Connect());
       
  1733     CWsScreenDevice* screenDevice = new (ELeave) CWsScreenDevice(ws);
       
  1734     CleanupStack::PushL(screenDevice);
       
  1735     User::LeaveIfError(screenDevice->Construct());
       
  1736     TSize currentScreenSize = screenDevice->SizeInPixels();
       
  1737 
       
  1738     TBool needsRotating = ETrue;
       
  1739     if (currentScreenSize.iWidth > currentScreenSize.iHeight && isLandScape)
       
  1740         {
       
  1741         // we are already in landscape 
       
  1742         HTI_LOG_TEXT("The screen are already in landscape.");
       
  1743         needsRotating = EFalse;
       
  1744         }
       
  1745     if (currentScreenSize.iWidth < currentScreenSize.iHeight
       
  1746             && (!isLandScape))
       
  1747         {
       
  1748         // we are already in portrait 
       
  1749         HTI_LOG_TEXT("The screen are already in portrait.");
       
  1750         needsRotating = EFalse;
       
  1751         }
       
  1752 
       
  1753     CAknLayoutConfig* layoutConfigPtr = CAknLayoutConfig::NewL();
       
  1754     CleanupStack::PushL(layoutConfigPtr);
       
  1755 
       
  1756     CAknLayoutConfig& layoutConfig = *layoutConfigPtr;
       
  1757 
       
  1758     const CAknLayoutConfig::THardwareStateArray& hwStates =
       
  1759             layoutConfig.HardwareStates();
       
  1760     const CAknLayoutConfig::TScreenModeArray& screenModes =
       
  1761             layoutConfig.ScreenModes();
       
  1762 
       
  1763     TInt newHwStateIndex = KErrNotFound;
       
  1764 
       
  1765     // lets select alternate state from current
       
  1766     TSize newScreenSize;
       
  1767     if (needsRotating)
       
  1768         {
       
  1769         newScreenSize = TSize(currentScreenSize.iHeight,
       
  1770                 currentScreenSize.iWidth);
       
  1771         HTI_LOG_FORMAT("Rotate the screen to the new width %d", newScreenSize.iWidth);
       
  1772         HTI_LOG_FORMAT("Rotate the screen to the new height %d", newScreenSize.iHeight);
       
  1773         }
       
  1774     else // basicly select current state again to ensure correct mode is informed to akncapserver
       
  1775         {
       
  1776         newScreenSize = TSize(currentScreenSize.iWidth,
       
  1777                 currentScreenSize.iHeight);
       
  1778         }
       
  1779 
       
  1780     for (TInt i = 0; i < hwStates.Count(); i++)
       
  1781         {
       
  1782         const CAknLayoutConfig::THardwareState hwState = hwStates.At(i);
       
  1783 
       
  1784         const CAknLayoutConfig::TScreenMode normal = screenModes.Find(
       
  1785                 hwState.ScreenMode());
       
  1786 
       
  1787         if (normal.SizeInPixels() == newScreenSize)
       
  1788             {
       
  1789             newHwStateIndex = i;
       
  1790             break;
       
  1791             }
       
  1792         }
       
  1793 
       
  1794     if (newHwStateIndex >= 0)
       
  1795         {
       
  1796         const CAknLayoutConfig::THardwareState newHwState = hwStates.At(
       
  1797                 newHwStateIndex);
       
  1798         TApaTaskList taskList(ws);
       
  1799         TApaTask aknCapsrvTask = taskList.FindApp(KAknCapServerUid);
       
  1800         TInt keyCode = newHwState.KeyCode();
       
  1801         HTI_LOG_FORMAT( "Send key code %d to akncapserver", keyCode );
       
  1802         aknCapsrvTask.SendKey(keyCode, 0);
       
  1803         }
       
  1804 
       
  1805     TBuf8<1> okMsg;
       
  1806     okMsg.Append(0);
       
  1807     iDispatcher->DispatchOutgoingMessage(okMsg.AllocL(),
       
  1808             KScreenshotServiceUid);
       
  1809 
       
  1810     CleanupStack::PopAndDestroy(layoutConfigPtr);
       
  1811     CleanupStack::PopAndDestroy(screenDevice);
       
  1812     ws.Close();
       
  1813              
       
  1814     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::HandleRotateScreen" );
       
  1815     }
       
  1816 // ----------------------------------------------------------------------------
       
  1817 void CHtiScreenshotServicePlugin::CreateBitmapL( TRect& aRegion,
       
  1818                                                  TDisplayMode aMode )
       
  1819     {
       
  1820     HTI_LOG_FUNC_IN( "CreateBitmapL" );
       
  1821     //create bitmap
       
  1822     TSize imageSize = aRegion.IsEmpty() ? iScreenDevice->SizeInPixels() :
       
  1823                         aRegion.Size();
       
  1824 
       
  1825     TDisplayMode displayMode = aMode == ENone ?
       
  1826                                         iScreenDevice->DisplayMode() : aMode;
       
  1827 
       
  1828     delete iScreen;//in case ICLComplete was not called
       
  1829     iScreen = NULL;
       
  1830     iScreen = new( ELeave ) CFbsBitmap;
       
  1831     User::LeaveIfError( iScreen->Create( imageSize, displayMode ) );
       
  1832 
       
  1833 	TInt err = KErrNone;
       
  1834 	TRect region;
       
  1835     if ( aRegion.IsEmpty() )
       
  1836         {
       
  1837         err = iScreenDevice->CopyScreenToBitmap( iScreen );
       
  1838 		region = imageSize;
       
  1839         }
       
  1840     else
       
  1841         {
       
  1842         err = iScreenDevice->CopyScreenToBitmap( iScreen, aRegion );
       
  1843 		region = aRegion;
       
  1844         }
       
  1845     if (err == KErrNoMemory)
       
  1846 	    {
       
  1847 		HTI_LOG_TEXT( "screenshot in camera mode" );
       
  1848 #if ( SYMBIAN_VERSION_SUPPORT < SYMBIAN_4 )
       
  1849 		err = CAlfDrawer::FallbackCopyScreenToBitmap(*iScreenDevice, iScreen, region);
       
  1850 #endif
       
  1851 		}
       
  1852 
       
  1853     if ( iDeltaCapture )
       
  1854         {
       
  1855         HTI_LOG_TEXT( "DeltaCapture enabled" );
       
  1856 
       
  1857 
       
  1858         CFbsBitmap* differenceBitmap = NULL;
       
  1859         TInt err = ImageDifferenceL( iPreviousBitmap,
       
  1860                                      iScreen,
       
  1861                                      differenceBitmap,
       
  1862                                      iDeltaRect );
       
  1863 
       
  1864         iPreviousBitmap->Reset();
       
  1865         iPreviousBitmap->Duplicate( iScreen->Handle() );
       
  1866 
       
  1867         if ( err == KErrNone )
       
  1868             {
       
  1869             delete iScreen;
       
  1870             iScreen = differenceBitmap;
       
  1871             }
       
  1872         else if ( err == KErrNotFound )
       
  1873             {
       
  1874             delete iScreen;
       
  1875             iScreen = NULL;
       
  1876 
       
  1877             if ( !iSeriesShot->IsOngoing() )
       
  1878                 {
       
  1879                 // Nothing has changed on the screen.
       
  1880                 // Send just iDeltaRect coordidates
       
  1881                 HBufC8* buf = HBufC8::NewL( 4 * 2 ); // 2 bytes for each coordinate
       
  1882                 buf->Des().SetLength( 4 * 2 );
       
  1883                 TUint16* ptr = (TUint16*) buf->Des().Ptr();
       
  1884                 ptr[0] = (TUint16) iDeltaRect.iTl.iX;
       
  1885                 ptr[1] = (TUint16) iDeltaRect.iTl.iY;
       
  1886                 ptr[2] = (TUint16) iDeltaRect.iBr.iX;
       
  1887                 ptr[3] = (TUint16) iDeltaRect.iBr.iY;
       
  1888                 // Response also sent in ICLComplete
       
  1889                 iDispatcher->DispatchOutgoingMessage( buf, KScreenshotServiceUid );
       
  1890                 }
       
  1891             }
       
  1892         }
       
  1893 
       
  1894     HTI_LOG_FUNC_OUT( "CreateBitmapL" );
       
  1895     }
       
  1896 /*
       
  1897 
       
  1898 // ----------------------------------------------------------------------------
       
  1899 void CleanupRArray( TAny* object )
       
  1900     {
       
  1901     ((RImageTypeDescriptionArray*)object)->ResetAndDestroy();
       
  1902     }
       
  1903 
       
  1904 // ----------------------------------------------------------------------------
       
  1905 void CHtiScreenshotServicePlugin::SelectEncoder( const TUid aEncoderUid )
       
  1906     {
       
  1907     //select encoder
       
  1908     RImageTypeDescriptionArray imageTypeArray;
       
  1909     CImageEncoder::GetImageTypesL( imageTypeArray );
       
  1910     CleanupStack::PushL( TCleanupItem(CleanupRArray, &imageTypeArray) );
       
  1911 
       
  1912     //select specified encoder
       
  1913     TBool found = EFalse;
       
  1914     for ( TInt i = 0; i < imageTypeArray.Count(); ++i )
       
  1915         {
       
  1916         if ( imageTypeArray[i]->ImageType() == aEncoderUid )
       
  1917             {
       
  1918             iImageEncoderType = imageTypeArray[i]->ImageType();
       
  1919             iImageEncoderSubtype = imageTypeArray[i]->SubType();
       
  1920             found = ETrue;
       
  1921             }
       
  1922         }
       
  1923 
       
  1924     if ( !found )
       
  1925         {
       
  1926         User::Leave( KErrNotFound );
       
  1927         }
       
  1928     CleanupStack::PopAndDestroy(); //imageTypeArray
       
  1929     }
       
  1930 */
       
  1931 
       
  1932 // ----------------------------------------------------------------------------
       
  1933 TBool CHtiScreenshotServicePlugin::IsMIMETypeSupported(TDesC8 &aMime)
       
  1934     {
       
  1935     HTI_LOG_DES(aMime);
       
  1936     RFileExtensionMIMETypeArray array;
       
  1937     CImageEncoder::GetFileTypesL(array);
       
  1938     for ( TInt i = 0; i < array.Count(); i++ )
       
  1939         {
       
  1940         if ( array[i]->MIMEType() == aMime )
       
  1941             {
       
  1942             HTI_LOG_TEXT( "MIME supported" );
       
  1943             array.ResetAndDestroy();
       
  1944             return ETrue;
       
  1945             }
       
  1946         }
       
  1947     HTI_LOG_TEXT( "MIME not supported" );
       
  1948     array.ResetAndDestroy();
       
  1949     return EFalse;
       
  1950     }
       
  1951 
       
  1952 
       
  1953 // ----------------------------------------------------------------------------
       
  1954 void CHtiScreenshotServicePlugin::EncodeBitmapL(const TDesC8& aImageTypeMIME )
       
  1955     {
       
  1956     HTI_LOG_FUNC_IN( "EncodeBitmapL" );
       
  1957     delete iBitmapEncoder;
       
  1958     iBitmapEncoder = NULL;
       
  1959     delete iICLHandler;
       
  1960     iICLHandler = NULL;
       
  1961 
       
  1962     if ( iScreen )
       
  1963         {
       
  1964         HTI_LOG_TEXT( "create encoder" );
       
  1965         if ( aImageTypeMIME  == KNullDesC8 )
       
  1966             {
       
  1967             iBitmapEncoder = CImageEncoder::DataNewL( iEncodedBitmap,
       
  1968                                         CImageEncoder::EOptionNone,
       
  1969                                         KImageTypeBMPUid);//,
       
  1970                                         //iImageEncoderSubtype);
       
  1971             }
       
  1972         else
       
  1973             {
       
  1974             iBitmapEncoder = CImageEncoder::DataNewL( iEncodedBitmap,
       
  1975                                         aImageTypeMIME);
       
  1976             }
       
  1977 
       
  1978         HTI_LOG_TEXT( "create CICLHandler" );
       
  1979         iICLHandler = new(ELeave) CICLHandler( iBitmapEncoder, this );
       
  1980         iBitmapEncoder->Convert( &(iICLHandler->iStatus), *iScreen );
       
  1981 
       
  1982         HTI_LOG_TEXT( "CICLHandler start");
       
  1983         iICLHandler->Start();
       
  1984         }
       
  1985     else
       
  1986         {
       
  1987         HTI_LOG_TEXT( "Nothing to encode" );
       
  1988         }
       
  1989 
       
  1990     HTI_LOG_FUNC_OUT( "EncodeBitmapL" );
       
  1991     }
       
  1992 
       
  1993 // ----------------------------------------------------------------------------
       
  1994 TInt CHtiScreenshotServicePlugin::Compress()
       
  1995     {
       
  1996     __ASSERT_ALWAYS(iEncodedBitmap!=NULL,User::Panic(KScreenshotPanic, KErrGeneral));
       
  1997     TInt err = KErrNone;
       
  1998     HBufC8* zippedTemp = NULL;
       
  1999 
       
  2000     HTI_LOG_FORMAT( "image size %d", iEncodedBitmap->Size() );
       
  2001     TInt numOfSteps = 4;
       
  2002     TInt comprBufferIncrease = iEncodedBitmap->Size()/numOfSteps;
       
  2003 
       
  2004     //straight way to handle cases
       
  2005     //when compressed data larger than uncompressed
       
  2006     //try until buffer for compr. data twice bigger than original data
       
  2007     for ( TInt i = 0; i < numOfSteps; ++i )
       
  2008         {
       
  2009         delete zippedTemp;
       
  2010         TRAP( err, zippedTemp = HBufC8::NewL( iEncodedBitmap->Size() +
       
  2011                                               i*comprBufferIncrease ) );
       
  2012         if ( err == KErrNone )
       
  2013             {
       
  2014             //try to zip
       
  2015             HTI_LOG_TEXT( "try to zip" );
       
  2016             TPtr8 zippedTempPtr = zippedTemp->Des();
       
  2017             TRAP( err, CEZCompressor::CompressL( zippedTempPtr,
       
  2018                                                  *iEncodedBitmap ) );
       
  2019             if ( err == KErrNone || err != KEZlibErrBuf )
       
  2020                 {
       
  2021                 break;
       
  2022                 }
       
  2023             }
       
  2024         else
       
  2025             {
       
  2026             break;
       
  2027             }
       
  2028         }
       
  2029 
       
  2030     if ( err == KErrNone )
       
  2031         {
       
  2032         delete iEncodedBitmap;
       
  2033         iEncodedBitmap = zippedTemp;
       
  2034         }
       
  2035     else
       
  2036         {
       
  2037         HTI_LOG_FORMAT( "compre error %d", err );
       
  2038         delete zippedTemp;
       
  2039         }
       
  2040 
       
  2041     return err;
       
  2042     }
       
  2043 
       
  2044 // ----------------------------------------------------------------------------
       
  2045 void CHtiScreenshotServicePlugin::ICLComplete( TInt anError)
       
  2046     {
       
  2047     HTI_LOG_FUNC_IN( "ICLComplete" );
       
  2048 
       
  2049     //delete what we dont need right away
       
  2050     delete iBitmapEncoder;
       
  2051     iBitmapEncoder = NULL;
       
  2052     delete iICLHandler;
       
  2053     iICLHandler = NULL;
       
  2054 
       
  2055 
       
  2056     if ( anError==KErrNone )
       
  2057         {
       
  2058         TInt err = KErrNone;
       
  2059 
       
  2060 
       
  2061         //compress
       
  2062         if ( iCompress )
       
  2063             {
       
  2064             HTI_LOG_TEXT( "compress" );
       
  2065             err = Compress();
       
  2066             }
       
  2067 
       
  2068         //send
       
  2069         if ( err == KErrNone )
       
  2070             {
       
  2071 
       
  2072             if ( !iSeriesShot->IsOngoing() )
       
  2073                 {
       
  2074                 // Not a series shot
       
  2075 
       
  2076                 if ( iDeltaCapture )
       
  2077                     {
       
  2078                     // DeltaCapture on
       
  2079 
       
  2080                     // If we have encoded the bitmap then we
       
  2081                     // also have some difference in the bitmap
       
  2082 
       
  2083                     HTI_LOG_TEXT( "Sending image with coordinates..." );
       
  2084 
       
  2085                     HBufC8* buf = HBufC8::NewL( (4*2) + iEncodedBitmap->Size() );
       
  2086                     buf->Des().SetLength(4*2);
       
  2087                     TUint16* ptr = (TUint16*) buf->Des().Ptr();
       
  2088                     ptr[0] = (TUint16) iDeltaRect.iTl.iX;
       
  2089                     ptr[1] = (TUint16) iDeltaRect.iTl.iY;
       
  2090                     ptr[2] = (TUint16) iDeltaRect.iBr.iX;
       
  2091                     ptr[3] = (TUint16) iDeltaRect.iBr.iY;
       
  2092 
       
  2093                     buf->Des().Append(*iEncodedBitmap);
       
  2094 
       
  2095                     delete iEncodedBitmap;
       
  2096                     iEncodedBitmap = NULL;
       
  2097 
       
  2098                     // Response also sent in CreateBitmapL
       
  2099                     err = iDispatcher->DispatchOutgoingMessage(buf,
       
  2100                                             KScreenshotServiceUid);
       
  2101                     }
       
  2102                 else
       
  2103                     {
       
  2104                     // Normal case
       
  2105                     HTI_LOG_TEXT( "Sending image..." );
       
  2106                     err = iDispatcher->DispatchOutgoingMessage(iEncodedBitmap,
       
  2107                                             KScreenshotServiceUid);
       
  2108                     }
       
  2109 
       
  2110                 if (  err == KErrNoMemory )
       
  2111                     {
       
  2112                     HTI_LOG_TEXT( "wait for memory" );
       
  2113                     iDispatcher->AddMemoryObserver( this );
       
  2114                     }
       
  2115                 else if ( err == KErrNone )
       
  2116                     {
       
  2117                     iEncodedBitmap = NULL;
       
  2118                     }
       
  2119                 else //just drop
       
  2120                     {
       
  2121                     HTI_LOG_TEXT( "ERROR: Impossible to send image" );
       
  2122                     delete iEncodedBitmap;
       
  2123                     iEncodedBitmap = NULL;
       
  2124                     }
       
  2125                 }
       
  2126             }
       
  2127         else
       
  2128             {
       
  2129             iSeriesShot->Cancel();
       
  2130             iDispatcher->DispatchOutgoingErrorMessage(
       
  2131                     err,
       
  2132                     KErrDescrFailedCompress,
       
  2133                     KScreenshotServiceUid);
       
  2134             delete iEncodedBitmap;
       
  2135             iEncodedBitmap = NULL;
       
  2136             }
       
  2137         }
       
  2138     else
       
  2139         {
       
  2140         iSeriesShot->Cancel();
       
  2141         iDispatcher->DispatchOutgoingErrorMessage(
       
  2142                         anError,
       
  2143                         KErrDescrFailedConvert,
       
  2144                         KScreenshotServiceUid);
       
  2145         delete iEncodedBitmap;
       
  2146         iEncodedBitmap = NULL;
       
  2147         }
       
  2148 
       
  2149     if ( iSeriesShot->IsOngoing() )
       
  2150         {
       
  2151         iSeriesShot->SaveImage( iEncodedBitmap, iCompress );
       
  2152         delete iEncodedBitmap;
       
  2153         iEncodedBitmap = NULL;
       
  2154 
       
  2155         // Check if there's still more to do
       
  2156         if ( iSeriesShot->IsOngoing() )
       
  2157             {
       
  2158             iSeriesShot->TriggerNewShot();
       
  2159             }
       
  2160         else
       
  2161             {
       
  2162             // - No, timer still active
       
  2163             // SeriesShot can complete here and in CSeriesShot::TimerExpired
       
  2164             SeriesShotCompletedL(iSeriesShot->ConstructCompletedMessageL());
       
  2165             }
       
  2166         }
       
  2167 
       
  2168     HTI_LOG_FUNC_OUT( "ICLComplete" );
       
  2169     }
       
  2170 
       
  2171 // ----------------------------------------------------------------------------
       
  2172 void CHtiScreenshotServicePlugin::NotifyMemoryChange( TInt aAvailableMemory )
       
  2173     {
       
  2174     if ( iEncodedBitmap )
       
  2175         {
       
  2176         if ( aAvailableMemory>= iEncodedBitmap->Size() )
       
  2177             {
       
  2178             TInt err = iDispatcher->DispatchOutgoingMessage(iEncodedBitmap,
       
  2179                                 KScreenshotServiceUid);
       
  2180 
       
  2181             if ( err == KErrNone)
       
  2182                 {
       
  2183                 iEncodedBitmap = NULL;
       
  2184                 iDispatcher->RemoveMemoryObserver( this );
       
  2185                 }
       
  2186             else if ( err != KErrNoMemory )
       
  2187                 {
       
  2188                 delete iEncodedBitmap;
       
  2189                 iEncodedBitmap = NULL;
       
  2190                 iDispatcher->RemoveMemoryObserver( this );
       
  2191                 }
       
  2192             }
       
  2193         }
       
  2194     else
       
  2195         {
       
  2196         //some error, should not be called
       
  2197         iDispatcher->RemoveMemoryObserver(this);
       
  2198         }
       
  2199     }
       
  2200 
       
  2201 // ----------------------------------------------------------------------------
       
  2202 void CHtiScreenshotServicePlugin::SeriesShotCompletedL(HBufC8* aMsg)
       
  2203     {
       
  2204     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::SeriesShotCompletedL" );
       
  2205     User::LeaveIfError( iDispatcher->DispatchOutgoingMessage(
       
  2206                         aMsg,
       
  2207                         KScreenshotServiceUid) );
       
  2208     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::SeriesShotCompletedL" );
       
  2209     }
       
  2210 
       
  2211 // ----------------------------------------------------------------------------
       
  2212 TBool CHtiScreenshotServicePlugin::StartShotL(TRect aRegion, TDisplayMode aDisplayMode, TDesC8 &aMimeType)
       
  2213     {
       
  2214     HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::StartShot" );
       
  2215     CreateBitmapL( aRegion, aDisplayMode );
       
  2216 
       
  2217     if ( aMimeType.Length()==0 )
       
  2218         EncodeBitmapL(); //use default encoder BMP
       
  2219     else
       
  2220         EncodeBitmapL( aMimeType );
       
  2221 
       
  2222     HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::StartShot" );
       
  2223     return iScreen ? ETrue : EFalse;
       
  2224     }
       
  2225 
       
  2226 // ----------------------------------------------------------------------------
       
  2227 void CHtiScreenshotServicePlugin::SetScreenNumber(TInt aScreenNumber)
       
  2228     {
       
  2229     HTI_LOG_FUNC_IN("CHtiScreenshotServicePlugin::SetScreenNumber");
       
  2230     TInt currentScreen = iScreenDevice->GetScreenNumber();
       
  2231     HTI_LOG_FORMAT("current screen: %d", currentScreen);
       
  2232     HTI_LOG_FORMAT("new screen number: %d", aScreenNumber);
       
  2233     if(aScreenNumber == currentScreen)
       
  2234         {
       
  2235         return;
       
  2236         }
       
  2237 
       
  2238     // Clear the previous delta bitmap to avoid error
       
  2239     iPreviousBitmap->Reset();
       
  2240     //delete old screendevice and create a new one
       
  2241     delete iScreenDevice;
       
  2242     iScreenDevice = NULL;
       
  2243     iScreenDevice = new (ELeave) CWsScreenDevice(iWs);
       
  2244     User::LeaveIfError(iScreenDevice->Construct(aScreenNumber));
       
  2245     HTI_LOG_FUNC_OUT("CHtiScreenshotServicePlugin::SetScreenNumber");
       
  2246     }
       
  2247 
       
  2248 // ----------------------------------------------------------------------------
       
  2249 CSeriesShot* CSeriesShot::NewL( MSeriesShotObserver* aServicePlugin )
       
  2250     {
       
  2251     HTI_LOG_FUNC_IN( "CSeriesShot::NewL" );
       
  2252     CSeriesShot* self = new (ELeave) CSeriesShot( aServicePlugin );
       
  2253     CleanupStack::PushL (self);
       
  2254     self->ConstructL();
       
  2255     CleanupStack::Pop();
       
  2256     HTI_LOG_FUNC_OUT( "CSeriesShot::NewL" );
       
  2257     return self;
       
  2258     }
       
  2259 
       
  2260 // ----------------------------------------------------------------------------
       
  2261 void CSeriesShot::ConstructL()
       
  2262     {
       
  2263     User::LeaveIfError(iFs.Connect());
       
  2264     }
       
  2265 
       
  2266 // ----------------------------------------------------------------------------
       
  2267 CSeriesShot::CSeriesShot( MSeriesShotObserver* aServicePluginObserver ):
       
  2268     iServicePluginObserver( aServicePluginObserver ),
       
  2269     iDurationTimer( NULL ),
       
  2270     iIntervalTimer( NULL ),
       
  2271     isEncoding( EFalse )
       
  2272     {
       
  2273     }
       
  2274 
       
  2275 // ----------------------------------------------------------------------------
       
  2276 CSeriesShot::~CSeriesShot()
       
  2277     {
       
  2278     Cancel();
       
  2279     iFs.Close();
       
  2280     }
       
  2281 
       
  2282 // ----------------------------------------------------------------------------
       
  2283 void CSeriesShot::ClearShots()
       
  2284     {
       
  2285     HTI_LOG_FUNC_IN( "CSeriesShot::ClearShots" );
       
  2286 
       
  2287     iFs.MkDirAll( KSeriesShotPath );
       
  2288 
       
  2289     // Delete all files
       
  2290     TFileName files;
       
  2291     files.Append( KSeriesShotPath );
       
  2292     files.Append( _L( "*.*" ) );
       
  2293     HTI_LOG_DES(files);
       
  2294 
       
  2295 
       
  2296     CFileMan *fileman = CFileMan::NewL( iFs );
       
  2297     TInt err = fileman->Delete( files );
       
  2298     HTI_LOG_FORMAT( "delete %d", err );
       
  2299     if ( err != KErrNotFound )
       
  2300         User::LeaveIfError( err );
       
  2301     delete fileman;
       
  2302 
       
  2303 
       
  2304     HTI_LOG_FUNC_OUT( "CSeriesShot::ClearShots" );
       
  2305     }
       
  2306 
       
  2307 // ----------------------------------------------------------------------------
       
  2308 void CSeriesShot::StartL( TTimeIntervalMicroSeconds32 aDuration,
       
  2309                          TTimeIntervalMicroSeconds32 aInterval,
       
  2310                          TDisplayMode aDisplayMode,
       
  2311                          TRect aRegion,
       
  2312                          TPtrC8 aMime )
       
  2313     {
       
  2314     HTI_LOG_FUNC_IN( "CSeriesShot::StartL" );
       
  2315     HTI_LOG_FORMAT( "Duration      : %d microseconds", aDuration.Int() );
       
  2316     HTI_LOG_FORMAT( "Interval      : %d microseconds", aInterval.Int() );
       
  2317     HTI_LOG_FORMAT( "Displaymode   : %d", aDisplayMode );
       
  2318     HTI_LOG_FORMAT( "TopLeft X     : %d", aRegion.iTl.iX );
       
  2319     HTI_LOG_FORMAT( "TopLeft Y     : %d", aRegion.iTl.iY );
       
  2320     HTI_LOG_FORMAT( "BottomRight X : %d", aRegion.iBr.iX );
       
  2321     HTI_LOG_FORMAT( "BottomRight Y : %d", aRegion.iBr.iY );
       
  2322 
       
  2323     iDisplayMode = aDisplayMode;
       
  2324     iRegion = aRegion;
       
  2325     iIndex = 0;
       
  2326 
       
  2327     iMimeType.Zero();
       
  2328     iMimeType.Append( aMime );
       
  2329     HTI_LOG_DES( iMimeType );
       
  2330 
       
  2331 #ifdef __ENABLE_LOGGING__
       
  2332     HTI_LOG_TEXT( "Supported MIME types:" );
       
  2333     RFileExtensionMIMETypeArray array;
       
  2334     CImageEncoder::GetFileTypesL( array );
       
  2335     for ( TInt i = 0; i < array.Count(); i++ )
       
  2336         HTI_LOG_DES( array[i]->MIMEType() );
       
  2337     array.ResetAndDestroy();
       
  2338 #endif
       
  2339 
       
  2340     iExtension.Zero();
       
  2341     if ( iMimeType.Length() == 0 )
       
  2342         iExtension.Append( _L( ".bmp" ) );
       
  2343     else
       
  2344         GetMIMEExtension( iMimeType, iExtension );
       
  2345 
       
  2346     ClearShots();
       
  2347 
       
  2348     iDurationTimer = CSeriesShotTimer::NewL( this, EDuration, aDuration );
       
  2349     iIntervalTimer = CSeriesShotTimer::NewL( this, EInterval, aInterval );
       
  2350     iDurationTimer->Start();
       
  2351     TimerExpired( EInterval ); // trigger first shot immidietly
       
  2352 
       
  2353     HTI_LOG_FUNC_OUT( "CSeriesShot::StartL" );
       
  2354     }
       
  2355 
       
  2356 void CSeriesShot::TimerExpired( TInt aId )
       
  2357     {
       
  2358     HTI_LOG_FUNC_IN( "CSeriesShot::TimerExpired" );
       
  2359     switch ( aId )
       
  2360         {
       
  2361         case EDuration:
       
  2362             HTI_LOG_TEXT( "EDuration" );
       
  2363 
       
  2364             delete iDurationTimer;
       
  2365             iDurationTimer = NULL;
       
  2366 
       
  2367             if ( iIntervalTimer ) // I'm paranoid
       
  2368                 {
       
  2369                 delete iIntervalTimer;
       
  2370                 iIntervalTimer = NULL;
       
  2371                 }
       
  2372             // SeriesShot can complete here and in CHtiScreenshotServicePlugin::ICLComplete
       
  2373             if ( isEncoding == EFalse )
       
  2374                 iServicePluginObserver->SeriesShotCompletedL( ConstructCompletedMessageL() );
       
  2375 
       
  2376             break;
       
  2377 
       
  2378         case EInterval:
       
  2379             HTI_LOG_TEXT( "EInterval" );
       
  2380 
       
  2381             isEncoding = iServicePluginObserver->StartShotL( iRegion, iDisplayMode, iMimeType );
       
  2382 
       
  2383             break;
       
  2384 
       
  2385         default:
       
  2386             break;
       
  2387         }
       
  2388     HTI_LOG_FUNC_OUT( "CSeriesShot::TimerExpired" );
       
  2389     }
       
  2390 
       
  2391 // ----------------------------------------------------------------------------
       
  2392 TBool CSeriesShot::IsOngoing()
       
  2393     {
       
  2394     // It still might be encoding when duration timer has expired
       
  2395     return ( iDurationTimer || isEncoding ) ? ETrue : EFalse;
       
  2396     }
       
  2397 
       
  2398 // ----------------------------------------------------------------------------
       
  2399 void CSeriesShot::SaveImage( TDesC8* aImage, TBool isCompressed )
       
  2400     {
       
  2401     HTI_LOG_FUNC_IN( "CSeriesShot::SaveImage" );
       
  2402 
       
  2403     isEncoding = EFalse;
       
  2404 
       
  2405     TFileName filename( KSeriesShotPath );
       
  2406     filename.AppendFormat( _L( "%04d" ), iIndex );
       
  2407     iIndex++;
       
  2408     filename.Append( iExtension );
       
  2409     if ( isCompressed )
       
  2410         filename.Append( _L( "z" ) );
       
  2411     HTI_LOG_DES( filename );
       
  2412 
       
  2413     RFile file;
       
  2414     User::LeaveIfError( file.Create( iFs, filename, EFileWrite ) );
       
  2415     User::LeaveIfError( file.Write( *aImage ) );
       
  2416     file.Close();
       
  2417 
       
  2418     HTI_LOG_FUNC_IN( "CSeriesShot::SaveImage" );
       
  2419     }
       
  2420 
       
  2421 // ----------------------------------------------------------------------------
       
  2422 void CSeriesShot::TriggerNewShot()
       
  2423     {
       
  2424     if ( iDurationTimer )
       
  2425         iIntervalTimer->Start();
       
  2426     }
       
  2427 
       
  2428 // ----------------------------------------------------------------------------
       
  2429 void CSeriesShot::Cancel()
       
  2430     {
       
  2431     if ( iDurationTimer )
       
  2432         {
       
  2433         delete iDurationTimer;
       
  2434         iDurationTimer = NULL;
       
  2435         }
       
  2436     if ( iIntervalTimer )
       
  2437         {
       
  2438         delete iIntervalTimer;
       
  2439         iIntervalTimer = NULL;
       
  2440         }
       
  2441     ClearShots();
       
  2442     }
       
  2443 
       
  2444 // ----------------------------------------------------------------------------
       
  2445 void CSeriesShot::EncodeCompleted()
       
  2446     {
       
  2447     isEncoding = EFalse;
       
  2448     }
       
  2449 
       
  2450 // ----------------------------------------------------------------------------
       
  2451 void CSeriesShot::GetMIMEExtension( TDesC8 &aMime, TDes &aExt )
       
  2452     {
       
  2453     RFileExtensionMIMETypeArray array;
       
  2454     CImageEncoder::GetFileTypesL( array );
       
  2455     for ( TInt i = 0; i < array.Count(); i++ )
       
  2456         {
       
  2457         if ( array[i]->MIMEType() == aMime )
       
  2458             aExt.Append( array[i]->FileExtension() );
       
  2459         }
       
  2460     array.ResetAndDestroy();
       
  2461 
       
  2462     if ( aExt == KNullDesC ) // should not happen
       
  2463         aExt.Append( _L( ".xxx" ) );
       
  2464     }
       
  2465 
       
  2466 // ----------------------------------------------------------------------------
       
  2467 HBufC8* CSeriesShot::ConstructCompletedMessageL()
       
  2468     {
       
  2469     HTI_LOG_FUNC_IN( "CSeriesShot::ConstructCompletedMessageL" );
       
  2470     // Serialshot completed send ok message.
       
  2471 
       
  2472     CDir* dir = NULL;
       
  2473     User::LeaveIfError( iFs.GetDir(
       
  2474         KSeriesShotPath, KEntryAttNormal, ESortByName, dir ) );
       
  2475 
       
  2476     TInt msgSize = 0;
       
  2477 
       
  2478     if ( dir->Count() == 0 )
       
  2479         {
       
  2480         HTI_LOG_TEXT( "No shots found! Leaving..." );
       
  2481         User::Leave( KErrNotFound );
       
  2482         }
       
  2483 
       
  2484     for ( TInt i = 0; i < dir->Count(); i++ )
       
  2485         {
       
  2486         msgSize += 1; // for length field
       
  2487         msgSize += KSeriesShotPath().Length();
       
  2488         msgSize += (*dir)[i].iName.Length();
       
  2489         }
       
  2490 
       
  2491     HBufC8* msg = HBufC8::NewL( msgSize );
       
  2492 
       
  2493     for ( TInt i = 0; i < dir->Count(); i++ )
       
  2494         {
       
  2495         msg->Des().Append( KSeriesShotPath().Length() + (*dir)[i].iName.Length() );
       
  2496         msg->Des().Append( KSeriesShotPath );
       
  2497         msg->Des().Append( (*dir)[i].iName );
       
  2498         }
       
  2499 
       
  2500     delete dir;
       
  2501 
       
  2502     HTI_LOG_FUNC_OUT( "CSeriesShot::ConstructCompletedMessageL" );
       
  2503     return msg;
       
  2504     }
       
  2505 
       
  2506 // ----------------------------------------------------------------------------
       
  2507 CSeriesShotTimer* CSeriesShotTimer::NewL( MSeriesShotTimerObserver* aObserver,
       
  2508                                         TInt aId,
       
  2509                                         TTimeIntervalMicroSeconds32 aTime )
       
  2510     {
       
  2511     HTI_LOG_FUNC_IN( "CSeriesShotTimer::NewL" );
       
  2512     CSeriesShotTimer* self = new (ELeave) CSeriesShotTimer( aObserver, aId, aTime );
       
  2513     CleanupStack::PushL( self );
       
  2514     self->ConstructL();
       
  2515     CleanupStack::Pop();
       
  2516     HTI_LOG_FUNC_OUT( "CSeriesShotTimer::NewL" );
       
  2517     return self;
       
  2518     }
       
  2519 
       
  2520 // ----------------------------------------------------------------------------
       
  2521 void CSeriesShotTimer::ConstructL()
       
  2522     {
       
  2523     HTI_LOG_FUNC_IN( "CSeriesShotTimer::ConstructL" );
       
  2524     CTimer::ConstructL();
       
  2525     if ( !IsAdded() ) // CTimer should add it but it seems that it does NOT!
       
  2526         {
       
  2527         CActiveScheduler::Add( this );
       
  2528         }
       
  2529     HTI_LOG_FUNC_OUT( "CSeriesShotTimer::ConstructL" );
       
  2530     }
       
  2531 
       
  2532 // ----------------------------------------------------------------------------
       
  2533 CSeriesShotTimer::CSeriesShotTimer( MSeriesShotTimerObserver* aObserver,
       
  2534                                   TInt aId,
       
  2535                                   TTimeIntervalMicroSeconds32 aTime ):
       
  2536     CTimer( EPriorityStandard ),
       
  2537     iObserver( aObserver ),
       
  2538     iId( aId ),
       
  2539     iTime( aTime )
       
  2540     {
       
  2541     }
       
  2542 
       
  2543 // ----------------------------------------------------------------------------
       
  2544 CSeriesShotTimer::~CSeriesShotTimer()
       
  2545     {
       
  2546     }
       
  2547 
       
  2548 // ----------------------------------------------------------------------------
       
  2549 void CSeriesShotTimer::RunL()
       
  2550     {
       
  2551     iObserver->TimerExpired( iId );
       
  2552     }
       
  2553 
       
  2554 // ----------------------------------------------------------------------------
       
  2555 void CSeriesShotTimer::Start()
       
  2556     {
       
  2557     HTI_LOG_FORMAT( "Start CSeriesShotTimer : %d microseconds", iTime.Int() );
       
  2558     After( iTime );
       
  2559     }