diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfwplugins/displaysourceplugin/src/displayserviceuilayout.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfwplugins/displaysourceplugin/src/displayserviceuilayout.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,520 @@ +/* +* Copyright (c) 2009-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CDisplayServiceUILayout class implementation. +* +*/ + + +// SYSTEM INCLUDES +#include +#include +#include +#include + +// USER INCLUDES +#include "displayserviceuilayout.h" +#include "displaysourcecontextdef.h" +#include "displaysourcepluginpanic.h" +#include "trace.h" + +// ======================== LOCAL FUNCTIONS ======================== + +#ifdef _DEBUG + +/** Rotation constants */ +_LIT( KGraphicsOrientationNormal, "Normal" ); +_LIT( KGraphicsOrientationRotated90, "Rotated 90" ); +_LIT( KGraphicsOrientationRotated180, "Rotated 180" ); +_LIT( KGraphicsOrientationRotated270, "Rotated 270" ); + +LOCAL_C const TDesC& RotationAsDesC( TInt aRotation ) + { + switch( aRotation ) + { + case CFbsBitGc::EGraphicsOrientationNormal: + { + return KGraphicsOrientationNormal; + } + case CFbsBitGc::EGraphicsOrientationRotated90: + { + return KGraphicsOrientationRotated90; + } + case CFbsBitGc::EGraphicsOrientationRotated180: + { + return KGraphicsOrientationRotated180; + } + case CFbsBitGc::EGraphicsOrientationRotated270: + { + return KGraphicsOrientationRotated270; + } + default: + { + return KNullDesC; + } + } + } + +#endif + +// ======================== MEMBER FUNCTIONS ======================== + +// ======================== CDisplayServiceUILayout ======================== + +// --------------------------------------------------------------------------- +// C++ constructor. +// --------------------------------------------------------------------------- +// +CDisplayServiceUILayout::CDisplayServiceUILayout( MCFContextInterface& aCF ): + CDisplayServiceBase( CDisplayServiceBase::EDisplayUILayout, aCF ), + iCurrentLayout( EUILayoutValueUnknown ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor. +// --------------------------------------------------------------------------- +// +void CDisplayServiceUILayout::ConstructL() + { + FUNC_LOG; + + // Call base class + CDisplayServiceBase::ConstructL(); + + // Configure context source and type + iContext->SetSourceL( KDisplaySource ); + iContext->SetTypeL( KDisplayUILayoutType ); + + // Define context: + // Device: Display.UI.Layout + TInt err = iCF.DefineContext( + KDisplaySource, KDisplayUILayoutType, KDisplayUILayoutSec ); + User::LeaveIfError( err ); + + // Define context: + // Device: Display.UI.Rotation + err = iCF.DefineContext( + KDisplaySource, KDisplayUIRotationType, KDisplayUIRotationSec ); + User::LeaveIfError( err ); + + // Create window server event handler + iWsEventHandler = CWsEventHandler::NewL( *this ); + } + +// --------------------------------------------------------------------------- +// Symbian two phased constructor. +// --------------------------------------------------------------------------- +// +CDisplayServiceUILayout* CDisplayServiceUILayout::NewL( + MCFContextInterface& aCF ) + { + FUNC_LOG; + + CDisplayServiceUILayout* self = CDisplayServiceUILayout::NewLC( aCF ); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------------------------- +// Symbian two phased constructor. +// Leaves pointer in the cleanup stack. +// --------------------------------------------------------------------------- +// +CDisplayServiceUILayout* CDisplayServiceUILayout::NewLC( + MCFContextInterface& aCF ) + { + FUNC_LOG; + + CDisplayServiceUILayout* self = + new ( ELeave ) CDisplayServiceUILayout( aCF ); + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + +// --------------------------------------------------------------------------- +// C++ destructor. +// --------------------------------------------------------------------------- +// +CDisplayServiceUILayout::~CDisplayServiceUILayout() + { + FUNC_LOG; + + delete iWsEventHandler; + } + +//------------------------------------------------------------------------------ +// CDisplayServiceUILayout::StartL +//------------------------------------------------------------------------------ +// +void CDisplayServiceUILayout::StartL() + { + FUNC_LOG; + + // Get initial values + TDisplayUILayoutValues layout; + CFbsBitGc::TGraphicsOrientation rotation; + iWsEventHandler->ResolveUILayout( layout, rotation ); + + // Publish initial UI layout context value + PublishContextL( layout, ETrue ); + + // Publish initial UI rotation context value + PublishContextL( rotation, ETrue ); + + // Start listening window server events + iWsEventHandler->IssueRequest(); + } + +//------------------------------------------------------------------------------ +// CDisplayServiceUILayout::Stop +//------------------------------------------------------------------------------ +// +void CDisplayServiceUILayout::Stop() + { + FUNC_LOG; + + iWsEventHandler->Cancel(); + } + +//------------------------------------------------------------------------------ +// CDisplayServiceUILayout::HandleWsEventL +//------------------------------------------------------------------------------ +// +void CDisplayServiceUILayout::HandleWsEventL( const TWsEvent &aEvent ) + { + FUNC_LOG; + + INFO_1( "New window server event received: Event: [%d]", aEvent.Type() ); + + // New window server event received, solve the event type + switch( aEvent.Type() ) + { + case EEventWindowGroupsChanged: + case EEventScreenDeviceChanged: + { + TDisplayUILayoutValues layout = EUILayoutValueUnknown; + CFbsBitGc::TGraphicsOrientation rotation = + CFbsBitGc::EGraphicsOrientationNormal; + iWsEventHandler->ResolveUILayout( layout, rotation ); + PublishContextL( layout ); + PublishContextL( rotation ); + break; + } + default: + { + // Nothing to do here + break; + } + } + } + +//------------------------------------------------------------------------------ +// CDisplayServiceUILayout::HandleWsEventErrorL +//------------------------------------------------------------------------------ +// +void CDisplayServiceUILayout::HandleWsEventErrorL( TInt aError ) + { + FUNC_LOG; + + // Remove warnings in urel builds + (void)aError; + + ERROR( aError, + "Window server event error occured. UI layout set to 'unknown" ); + + // Error occured and it is impossible to know the current UI layout. + // Publish context: + // Device: Display.UI.Layout: Unknown + iContext->SetValueL( TPtrC( + KDisplayUILayoutValues[EUILayoutValueUnknown] ) ); + iCF.PublishContext( *iContext, iThread ); + } + +//------------------------------------------------------------------------------ +// CDisplayServiceUILayout::PublishContextL +//------------------------------------------------------------------------------ +// +void CDisplayServiceUILayout::PublishContextL( TDisplayUILayoutValues aLayout, + TBool aForce ) + { + FUNC_LOG; + + if( aLayout != iCurrentLayout || aForce ) + { + iContext->SetTypeL( KDisplayUILayoutType ); + iContext->SetValueL( TPtrC( KDisplayUILayoutValues[aLayout] ) ); + iCF.PublishContext( *iContext, iThread ); + iCurrentLayout = aLayout; + } + } + +//------------------------------------------------------------------------------ +// CDisplayServiceUILayout::PublishContextL +//------------------------------------------------------------------------------ +// +void CDisplayServiceUILayout::PublishContextL( + CFbsBitGc::TGraphicsOrientation aRotation, + TBool aForce ) + { + FUNC_LOG; + + if( aRotation != iCurrentRotation || aForce ) + { + iContext->SetTypeL( KDisplayUIRotationType ); + iContext->SetValueL( TPtrC( KDisplayUIRotationValues[aRotation] ) ); + iCF.PublishContext( *iContext, iThread ); + iCurrentRotation = aRotation; + } + } + +// ======================== CWsEventHandler ======================== + +// --------------------------------------------------------------------------- +// C++ constructor. +// --------------------------------------------------------------------------- +// +CWsEventHandler::CWsEventHandler( MWsEventObserver& aObserver ): + CActive( CActive::EPriorityStandard ), + iObserver( aObserver ) + { + FUNC_LOG; + + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor. +// --------------------------------------------------------------------------- +// +void CWsEventHandler::ConstructL() + { + FUNC_LOG; + + // Connect to window server server + User::LeaveIfError( iWsSession.Connect() ); + + // Construct window group + iWindowGroup = new( ELeave ) RWindowGroup( iWsSession ); + User::LeaveIfError( iWindowGroup->Construct( (TUint32)this, EFalse ) ); + User::LeaveIfError( iWindowGroup->EnableScreenChangeEvents() ); + User::LeaveIfError( iWindowGroup->EnableGroupChangeEvents() ); + iWindowGroup->SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront ); + iWindowGroup->EnableReceiptOfFocus( EFalse ); + + // Hide the invisible window from the task manager + iWindowGroupName = CApaWindowGroupName::NewL( iWsSession ); + iWindowGroupName->SetHidden( ETrue ); + iWindowGroupName->SetWindowGroupName( *iWindowGroup ); + + // Construct screen device + iWsScreenDevice = new( ELeave ) CWsScreenDevice( iWsSession ); + User::LeaveIfError( iWsScreenDevice->Construct() ); + } + +// --------------------------------------------------------------------------- +// Symbian two phased constructor. +// --------------------------------------------------------------------------- +// +CWsEventHandler* CWsEventHandler::NewL( MWsEventObserver& aObserver ) + { + FUNC_LOG; + + CWsEventHandler* self = CWsEventHandler::NewLC( aObserver ); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------------------------- +// Symbian two phased constructor. +// Leaves pointer in the cleanup stack. +// --------------------------------------------------------------------------- +// +CWsEventHandler* CWsEventHandler::NewLC( MWsEventObserver& aObserver ) + { + FUNC_LOG; + + CWsEventHandler* self = new ( ELeave ) CWsEventHandler( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + +// --------------------------------------------------------------------------- +// C++ destructor. +// --------------------------------------------------------------------------- +// +CWsEventHandler::~CWsEventHandler() + { + FUNC_LOG; + + Cancel(); + + // Cleanup screen device + delete iWsScreenDevice; + + // Cleanup window group name + delete iWindowGroupName; + + // Cleanup window group + if( iWindowGroup ) + { + iWindowGroup->DisableGroupChangeEvents(); + iWindowGroup->DisableScreenChangeEvents(); + iWindowGroup->Close(); + delete iWindowGroup; + } + + // Cleanup window server session + iWsSession.Close(); + } + +//------------------------------------------------------------------------------ +// CWsEventHandler::IssueRequest +//------------------------------------------------------------------------------ +// +void CWsEventHandler::IssueRequest() + { + FUNC_LOG; + + __ASSERT_DEBUG( !IsActive(), Panic( ERequestAlreadyIssued ) ); + + // Request events from window server + iWsSession.EventReady( &iStatus ); + SetActive(); + } + +//------------------------------------------------------------------------------ +// CWsEventHandler::ResolveUILayout +//------------------------------------------------------------------------------ +// +void CWsEventHandler::ResolveUILayout( TDisplayUILayoutValues& aLayout, + CFbsBitGc::TGraphicsOrientation& aRotation ) const + { + FUNC_LOG; + + // Resolve the current UI layout from screen dimensions + TInt mode = iWsScreenDevice->CurrentScreenMode(); + INFO_1( "Current screen mode: [%d]", mode ); + + TPixelsAndRotation pixelsAndRotation; + iWsScreenDevice->GetScreenModeSizeAndRotation( mode, pixelsAndRotation ); + INFO_3( "Current screen mode size and rotation: Size: [W=%d, H=%d], Rotation: [%S]", + pixelsAndRotation.iPixelSize.iWidth, + pixelsAndRotation.iPixelSize.iHeight, + &RotationAsDesC( pixelsAndRotation.iRotation ) ); + + // Resolve current UI rotation + aRotation = pixelsAndRotation.iRotation; + + // Resovle current UI layout mode + TSize screenSize( pixelsAndRotation.iPixelSize ); + if( screenSize.iWidth < screenSize.iHeight ) + { + // Assuming portrait layout + INFO( "Current UI layout resolved to be in 'Portrait' mode" ); + aLayout = EUILayoutValuePortrait; + } + else if( screenSize.iWidth > screenSize.iHeight ) + { + // Assuming landscape layout + INFO( "Current UI layout resolved to be in 'Landscape' mode" ); + aLayout = EUILayoutValueLandscape; + } + else + { + // Need to check the rotation even though this might not be correct + // if wsini.ini has not been configured properly. + CFbsBitGc::TGraphicsOrientation orientation( + pixelsAndRotation.iRotation ); + if( orientation == CFbsBitGc::EGraphicsOrientationNormal || + orientation == CFbsBitGc::EGraphicsOrientationRotated180 ) + { + // Assuming portrait layout + INFO( "Current UI layout resolved to be in 'Portrait' mode" ); + aLayout = EUILayoutValuePortrait; + } + else + { + // Assuming landscape layout + INFO( "Current UI layout resolved to be in 'Landscape' mode" ); + aLayout = EUILayoutValueLandscape; + } + } + } + +//------------------------------------------------------------------------------ +// CWsEventHandler::RunL +//------------------------------------------------------------------------------ +// +void CWsEventHandler::RunL() + { + FUNC_LOG; + + TInt err = iStatus.Int(); + if( err == KErrNone ) + { + // No errors occured, fetch event + TWsEvent wsEvent; + iWsSession.GetEvent( wsEvent ); + + // Continue listening + IssueRequest(); + + // Forward event to observer + iObserver.HandleWsEventL( wsEvent ); + } + else + { + // Continue listening + IssueRequest(); + + // Forward error to observer + iObserver.HandleWsEventErrorL( err ); + } + } + +//------------------------------------------------------------------------------ +// CWsEventHandler::DoCancel +//------------------------------------------------------------------------------ +// +void CWsEventHandler::DoCancel() + { + FUNC_LOG; + + // Cancel event ready from window server + iWsSession.EventReadyCancel(); + } + +//------------------------------------------------------------------------------ +// CWsEventHandler::RunError +//------------------------------------------------------------------------------ +// +TInt CWsEventHandler::RunError( TInt /*aError*/ ) + { + FUNC_LOG; + + // Issue a new request, other error handling is not performed since the + // problem has occured in the observer code + IssueRequest(); + + return KErrNone; + } + +// End of file