htiui/HtiServicePlugins/HtiScreenshotServicePlugin/src/HtiScreenshotServicePlugin.cpp
branchRCL_3
changeset 11 454d022d514b
parent 3 2703485a934c
--- a/htiui/HtiServicePlugins/HtiScreenshotServicePlugin/src/HtiScreenshotServicePlugin.cpp	Tue Apr 27 16:38:40 2010 +0300
+++ b/htiui/HtiServicePlugins/HtiScreenshotServicePlugin/src/HtiScreenshotServicePlugin.cpp	Tue May 11 16:14:15 2010 +0300
@@ -17,6 +17,9 @@
 
 
 // INCLUDE FILES
+#include "../../../symbian_version.hrh"
+
+
 #include "HtiScreenshotServicePlugin.h"
 #include <HtiDispatcherInterface.h>
 #include <HtiLogging.h>
@@ -25,6 +28,14 @@
 #include <ezcompressor.h>
 #include <hal.h>
 
+#include <AknLayoutConfig.h>
+#include <apgtask.h> 
+#include <AknCapServerDefs.h>
+
+#if ( SYMBIAN_VERSION_SUPPORT < SYMBIAN_4 )
+#include <alf/alfdrawer.h>
+#endif
+
 // CONSTANTS
 const static TUid KScreenshotServiceUid = {0x1020DEC3};
 
@@ -55,6 +66,9 @@
 
     // Gets the current screen size and orientation
     ECmdScreenMode            = 0x3A,
+    
+    // Rotates the screen to portrait or landscape
+    ECmdRotateScreen          = 0x3B,
 
     // Screencapture on updated part of screen only
     ECmdDeltaCaptureMask           = 0x80,
@@ -91,14 +105,16 @@
 const static TInt KMinScreenRegionCmdLength = 9;
 const static TInt KScreenDisplayOffset = 1;
 const static TInt KScreenMIMEOffset = KScreenDisplayOffset + 1;
+const static TInt KScreenScreenNumber = KScreenMIMEOffset + 8;
 const static TInt KRegionDisplayOffset = KMinScreenRegionCmdLength;
 const static TInt KRegionMIMEOffset = KRegionDisplayOffset + 1;
-
+const static TInt KRegionScreenNumber = KRegionMIMEOffset + 8;
 
 const static TInt KSeriesDurationOffset = 1;
 const static TInt KSeriesIntervalOffset = KSeriesDurationOffset + 4;
 const static TInt KSeriesDisplayOffset = KSeriesIntervalOffset + 4;
 const static TInt KSeriesMIMEOffset = KSeriesDisplayOffset + 1;
+const static TInt KSeriesScreenNumber = KSeriesMIMEOffset + 8;
 const static TInt KMinSeriesCmdLength = KSeriesMIMEOffset;
 
 const static TInt KRegionSeriesTlX = KSeriesDisplayOffset + 1;
@@ -106,6 +122,7 @@
 const static TInt KRegionSeriesBlX = KRegionSeriesTlY + 2;
 const static TInt KRegionSeriesBlY = KRegionSeriesBlX + 2;
 const static TInt KRegionSeriesMIMEOffset = KRegionSeriesBlY + 2;
+const static TInt KRegionSeriesScreenNumber = KRegionSeriesMIMEOffset + 8;
 const static TInt KMinRegionSeriesCmdLength = KRegionSeriesMIMEOffset;
 
 const static TInt KDeltaResetCmdLength = 1;
@@ -113,6 +130,7 @@
 
 const static TInt KScreenNrOffset = 1;
 const static TInt KSelectScreenCmdLength = 2;
+const static TInt KRotateScreenCmdLength = 2;
 
 _LIT( KSeriesShotPath, "c:\\Hti\\SeriesShot\\" );
 
@@ -1189,11 +1207,44 @@
                         }
                     }
 
+                bool screenNumberSet = false;
+                //check screen number
+                if ( (aMessage.Length() > KScreenScreenNumber) && 
+                        ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)))
+                    {
+                    TInt screenNumber = aMessage[aMessage.Length()-1];
+                    HTI_LOG_FORMAT( "set screen number: %d", screenNumber );
+                    screenNumberSet = true;
+                    TInt screens;
+                    TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
+                    if(ret)
+                        {
+                        HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
+                        User::Leave(ret);
+                        }
+                    HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
+                    if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
+                        {
+                        iDispatcher->DispatchOutgoingErrorMessage(
+                                KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
+                        return;
+                        }
+                    SetScreenNumber(screenNumber);
+                    }
+
                 CreateBitmapL( empty, displayMode );
+
                 //check mime
                 if ( aMessage.Length() > KScreenMIMEOffset )
                     {
-                    mime.Set( aMessage.Mid( KScreenMIMEOffset ) );
+                    if(screenNumberSet)
+                        {
+                        mime.Set( aMessage.Mid( KScreenMIMEOffset, aMessage.Length()-1-KScreenMIMEOffset ) );
+                        }
+                    else
+                        {
+                        mime.Set( aMessage.Mid( KScreenMIMEOffset ) );
+                        }
                     if ( !IsMIMETypeSupported( mime ) )
                         {
                         iDispatcher->DispatchOutgoingErrorMessage(
@@ -1203,7 +1254,7 @@
                         return;
                         }
                     }
-                }
+                }              
                 break;
 
             case ECmdScreenRegion:
@@ -1211,6 +1262,30 @@
             case ECmdDeltaScreenRegion:
             case ECmdDeltaScreenRegionZip:
                 {
+                //check screen number
+                bool screenNumberSet = false;
+                if ( (aMessage.Length() > KRegionScreenNumber) && 
+                        ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)))
+                    {
+                    TInt screenNumber = aMessage[aMessage.Length()-1];
+                    screenNumberSet = true;
+                    TInt screens;
+                    TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
+                    if(ret)
+                        {
+                        HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
+                        User::Leave(ret);
+                        }
+                    HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
+                    if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
+                        {
+                        iDispatcher->DispatchOutgoingErrorMessage(
+                                KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
+                        return;
+                        }
+                    SetScreenNumber(screenNumber);
+                    }
+
                 if ( aMessage.Length() >= KMinScreenRegionCmdLength )
                     {
                     TRect region;
@@ -1271,11 +1346,18 @@
                                         KScreenshotServiceUid );
                         return;
                         }
-
+                    
                     //check mime
                     if ( aMessage.Length() > KRegionMIMEOffset )
                         {
-                        mime.Set( aMessage.Mid( KRegionMIMEOffset ) );
+                        if(!screenNumberSet)
+                            {
+                            mime.Set( aMessage.Mid( KRegionMIMEOffset ) );
+                            }
+                        else
+                            {
+                            mime.Set( aMessage.Mid( KRegionMIMEOffset, aMessage.Length()-1-KRegionMIMEOffset ) );
+                            }
                         if ( !IsMIMETypeSupported( mime ) )
                             {
                             iDispatcher->DispatchOutgoingErrorMessage(
@@ -1285,6 +1367,7 @@
                             return;
                             }
                         }
+
                     }
                 else
                     {
@@ -1308,6 +1391,30 @@
                                     KScreenshotServiceUid );
                     return;
                     }
+                
+                bool screenNumberSet = false;
+                if ( (aMessage.Length() > KSeriesScreenNumber) && 
+                        ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)) )
+                    {
+                    TInt screenNumber = aMessage[aMessage.Length()-1];
+                    screenNumberSet = true;
+                    TInt screens;
+                    TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
+                    if(ret)
+                        {
+                        HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
+                        User::Leave(ret);
+                        }
+                    HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
+                    if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
+                        {
+                        iDispatcher->DispatchOutgoingErrorMessage(
+                                KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
+                        return;
+                        }
+                    SetScreenNumber(screenNumber);
+                    }
+
                 TInt duration = ParseInt32( aMessage.Ptr() + KSeriesDurationOffset );
                 TInt interval = ParseInt32( aMessage.Ptr() + KSeriesIntervalOffset );
 
@@ -1320,10 +1427,17 @@
                                     KScreenshotServiceUid );
                     return;
                     }
-
+                
                 if ( aMessage.Length() > KSeriesMIMEOffset )
                     {
-                    mime.Set( aMessage.Mid( KSeriesMIMEOffset ) );
+                    if(screenNumberSet)
+                        {
+                        mime.Set( aMessage.Mid( KSeriesMIMEOffset, aMessage.Length()-1-KSeriesMIMEOffset ) );
+                        }
+                    else
+                        {
+                        mime.Set( aMessage.Mid( KSeriesMIMEOffset ) );
+                        }
                     if ( !IsMIMETypeSupported( mime ) )
                         {
                         iDispatcher->DispatchOutgoingErrorMessage(
@@ -1342,6 +1456,29 @@
             case ECmdScreenRegionSeries:
             case ECmdScreenRegionZipSeries:
                 {
+                bool screenNumberSet = false;
+                if ( (aMessage.Length() > KRegionSeriesScreenNumber) && 
+                        ((aMessage[aMessage.Length()-1] == 0) || (aMessage[aMessage.Length()-1] == 1)) )
+                    {
+                    TInt screenNumber = aMessage[aMessage.Length()-1];
+                    screenNumberSet = true;
+                    TInt screens;
+                    TInt ret = HAL::Get(HAL::EDisplayNumberOfScreens, screens);
+                    if(ret)
+                        {
+                        HTI_LOG_FORMAT( "HAL::Get failed %d", ret );
+                        User::Leave(ret);
+                        }
+                    HTI_LOG_FORMAT( "HAL::Get number of screens %d", screens );
+                    if( ( screenNumber>screens-1 ) || ( screenNumber<0 ) )
+                        {
+                        iDispatcher->DispatchOutgoingErrorMessage(
+                                KErrArgument, KErrDescrScreenNotSupported, KScreenshotServiceUid);
+                        return;
+                        }
+                    SetScreenNumber(screenNumber);
+                    }
+
                 if ( aMessage.Length() < KMinRegionSeriesCmdLength )
                     {
                     iDispatcher->DispatchOutgoingErrorMessage(
@@ -1403,10 +1540,17 @@
                                     KScreenshotServiceUid );
                     return;
                     }
-
+                
                 if ( aMessage.Length() > KRegionSeriesMIMEOffset )
                     {
-                    mime.Set( aMessage.Mid( KRegionSeriesMIMEOffset ) );
+                    if(screenNumberSet)
+                        {
+                        mime.Set( aMessage.Mid( KRegionSeriesMIMEOffset, aMessage.Length()-1-KRegionSeriesMIMEOffset ) );
+                        }
+                    else
+                        {
+                        mime.Set( aMessage.Mid( KRegionSeriesMIMEOffset ) );
+                        }
                     if ( !IsMIMETypeSupported( mime ) )
                         {
                         iDispatcher->DispatchOutgoingErrorMessage(
@@ -1526,7 +1670,17 @@
                     respMsg.AllocL(), KScreenshotServiceUid );
                 }
                 return;
-
+           case ECmdRotateScreen:
+               {
+               if (aMessage.Length() != KRotateScreenCmdLength)
+                   {
+                   iDispatcher->DispatchOutgoingErrorMessage(KErrArgument,
+                           KErrDescrInvalid, KScreenshotServiceUid);
+                   return;
+                   }
+               HandleRotateScreen(aMessage.Right(aMessage.Length() -1));
+               return;
+               }
             default:
                 //Error: unknown command
                 iDispatcher->DispatchOutgoingErrorMessage(
@@ -1559,7 +1713,106 @@
     HTI_LOG_FUNC_OUT( "HtiScreenshotServicePlugin::ProcessMessage" );
     }
 
+// ----------------------------------------------------------------------------
+void CHtiScreenshotServicePlugin::HandleRotateScreen(const TDesC8& aData)
+    {
+    HTI_LOG_FUNC_IN( "CHtiScreenshotServicePlugin::HandleRotateScreen" );
+             
+    TInt orientation = aData[0];
+    if (orientation > 1 || orientation < 0)
+        {
+        iDispatcher->DispatchOutgoingErrorMessage(KErrArgument,
+                KErrDescrInvalid, KScreenshotServiceUid);
+        return;
+        }
 
+    TBool isLandScape = orientation;
+
+    RWsSession ws;
+    User::LeaveIfError(ws.Connect());
+    CWsScreenDevice* screenDevice = new (ELeave) CWsScreenDevice(ws);
+    CleanupStack::PushL(screenDevice);
+    User::LeaveIfError(screenDevice->Construct());
+    TSize currentScreenSize = screenDevice->SizeInPixels();
+
+    TBool needsRotating = ETrue;
+    if (currentScreenSize.iWidth > currentScreenSize.iHeight && isLandScape)
+        {
+        // we are already in landscape 
+        HTI_LOG_TEXT("The screen are already in landscape.");
+        needsRotating = EFalse;
+        }
+    if (currentScreenSize.iWidth < currentScreenSize.iHeight
+            && (!isLandScape))
+        {
+        // we are already in portrait 
+        HTI_LOG_TEXT("The screen are already in portrait.");
+        needsRotating = EFalse;
+        }
+
+    CAknLayoutConfig* layoutConfigPtr = CAknLayoutConfig::NewL();
+    CleanupStack::PushL(layoutConfigPtr);
+
+    CAknLayoutConfig& layoutConfig = *layoutConfigPtr;
+
+    const CAknLayoutConfig::THardwareStateArray& hwStates =
+            layoutConfig.HardwareStates();
+    const CAknLayoutConfig::TScreenModeArray& screenModes =
+            layoutConfig.ScreenModes();
+
+    TInt newHwStateIndex = KErrNotFound;
+
+    // lets select alternate state from current
+    TSize newScreenSize;
+    if (needsRotating)
+        {
+        newScreenSize = TSize(currentScreenSize.iHeight,
+                currentScreenSize.iWidth);
+        HTI_LOG_FORMAT("Rotate the screen to the new width %d", newScreenSize.iWidth);
+        HTI_LOG_FORMAT("Rotate the screen to the new height %d", newScreenSize.iHeight);
+        }
+    else // basicly select current state again to ensure correct mode is informed to akncapserver
+        {
+        newScreenSize = TSize(currentScreenSize.iWidth,
+                currentScreenSize.iHeight);
+        }
+
+    for (TInt i = 0; i < hwStates.Count(); i++)
+        {
+        const CAknLayoutConfig::THardwareState hwState = hwStates.At(i);
+
+        const CAknLayoutConfig::TScreenMode normal = screenModes.Find(
+                hwState.ScreenMode());
+
+        if (normal.SizeInPixels() == newScreenSize)
+            {
+            newHwStateIndex = i;
+            break;
+            }
+        }
+
+    if (newHwStateIndex >= 0)
+        {
+        const CAknLayoutConfig::THardwareState newHwState = hwStates.At(
+                newHwStateIndex);
+        TApaTaskList taskList(ws);
+        TApaTask aknCapsrvTask = taskList.FindApp(KAknCapServerUid);
+        TInt keyCode = newHwState.KeyCode();
+        HTI_LOG_FORMAT( "Send key code %d to akncapserver", keyCode );
+        aknCapsrvTask.SendKey(keyCode, 0);
+        }
+
+    TBuf8<1> okMsg;
+    okMsg.Append(0);
+    iDispatcher->DispatchOutgoingMessage(okMsg.AllocL(),
+            KScreenshotServiceUid);
+
+    CleanupStack::PopAndDestroy(layoutConfigPtr);
+    CleanupStack::PopAndDestroy(screenDevice);
+    ws.Close();
+             
+    HTI_LOG_FUNC_OUT( "CHtiScreenshotServicePlugin::HandleRotateScreen" );
+    }
 // ----------------------------------------------------------------------------
 void CHtiScreenshotServicePlugin::CreateBitmapL( TRect& aRegion,
                                                  TDisplayMode aMode )
@@ -1577,15 +1830,25 @@
     iScreen = new( ELeave ) CFbsBitmap;
     User::LeaveIfError( iScreen->Create( imageSize, displayMode ) );
 
+	TInt err = KErrNone;
+	TRect region;
     if ( aRegion.IsEmpty() )
         {
-        iScreenDevice->CopyScreenToBitmap( iScreen );
+        err = iScreenDevice->CopyScreenToBitmap( iScreen );
+		region = imageSize;
         }
     else
         {
-        iScreenDevice->CopyScreenToBitmap( iScreen, aRegion );
+        err = iScreenDevice->CopyScreenToBitmap( iScreen, aRegion );
+		region = aRegion;
         }
-
+    if (err == KErrNoMemory)
+	    {
+		HTI_LOG_TEXT( "screenshot in camera mode" );
+#if ( SYMBIAN_VERSION_SUPPORT < SYMBIAN_4 )
+		err = CAlfDrawer::FallbackCopyScreenToBitmap(*iScreenDevice, iScreen, region);
+#endif
+		}
 
     if ( iDeltaCapture )
         {
@@ -1961,6 +2224,28 @@
     }
 
 // ----------------------------------------------------------------------------
+void CHtiScreenshotServicePlugin::SetScreenNumber(TInt aScreenNumber)
+    {
+    HTI_LOG_FUNC_IN("CHtiScreenshotServicePlugin::SetScreenNumber");
+    TInt currentScreen = iScreenDevice->GetScreenNumber();
+    HTI_LOG_FORMAT("current screen: %d", currentScreen);
+    HTI_LOG_FORMAT("new screen number: %d", aScreenNumber);
+    if(aScreenNumber == currentScreen)
+        {
+        return;
+        }
+
+    // Clear the previous delta bitmap to avoid error
+    iPreviousBitmap->Reset();
+    //delete old screendevice and create a new one
+    delete iScreenDevice;
+    iScreenDevice = NULL;
+    iScreenDevice = new (ELeave) CWsScreenDevice(iWs);
+    User::LeaveIfError(iScreenDevice->Construct(aScreenNumber));
+    HTI_LOG_FUNC_OUT("CHtiScreenshotServicePlugin::SetScreenNumber");
+    }
+
+// ----------------------------------------------------------------------------
 CSeriesShot* CSeriesShot::NewL( MSeriesShotObserver* aServicePlugin )
     {
     HTI_LOG_FUNC_IN( "CSeriesShot::NewL" );