diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/ServerCore/Src/alfappsrvsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/ServerCore/Src/alfappsrvsession.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,2837 @@ +/* +* Copyright (c) 2006 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: Server session +* +*/ + + +#include +#include "alfappsrvsession.h" +#include "alf/alfappserver.h" +#include "alf/alfappui.h" +#include "alf/alfconstants.h" +#include "alf/alfclientwindow.h" +#include "alfsrvdisplaysubsession.h" +#include "alfsrvcontrolgroupsubsession.h" +#include "alfsrvsettingshandler.h" +#include "alfsrvtranseffect.h" +#include "alf/alfsrveffectenv.h" +#include "alf/alfserverutils.h" +#include "alflogger.h" +#include "alfclientserver.h" +#include "alfsrvtexturemanager.h" +#include "alfsrvscreenbuffermanager.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +_LIT( KAlfFPSLogDir, "alf"); // remember to create the c:\logs\alf in order to enable logging +_LIT( KAlfFPSLogFile, "alffpslog.txt"); + + +const TReal32 KAlfUseDefaultFrameRate = 0.f; + +TBool RealCompare( + TReal32 aCompare1, + TReal32 aCompare2, + TReal32 aEpsilon = 0.001f ) + { + if ( Abs(aCompare1 - aCompare2) < aEpsilon ) + { + return ETrue; + } + return EFalse; + } + +/** + * Size of command batch buffer allocated from stack. + * (This is used if all else fails) + */ +const TInt KAlfStackBatchBufferSize = 128; + +// bitmap provider + +NONSHARABLE_CLASS(CSharedBitmapProvider) : public CBase, public MHuiBitmapProvider + { +public: + CSharedBitmapProvider(); + CSharedBitmapProvider(TInt aBitmapHandle, TInt aMaskHandle); + ~CSharedBitmapProvider(); + // from MHuiBitmapProvider + void ProvideBitmapL(TInt aId, CFbsBitmap*& aBitmap, CFbsBitmap*& aMaskBitmap); +private: + TInt iBitmapHandle; + TInt iMaskHandle; + }; + +CSharedBitmapProvider::CSharedBitmapProvider() + { + + } + +CSharedBitmapProvider::CSharedBitmapProvider(TInt aBitmapHandle, TInt aMaskHandle) + { + iBitmapHandle = aBitmapHandle; + iMaskHandle = aMaskHandle; + } + +CSharedBitmapProvider::~CSharedBitmapProvider() + { + } + +void CSharedBitmapProvider::ProvideBitmapL(TInt /*aId*/, CFbsBitmap*& aBitmap, CFbsBitmap*& aBitmapMask) + { + CFbsBitmap* bitmap(0); + CFbsBitmap* mask(0); + + if (iBitmapHandle) // mandatory + { + bitmap = new (ELeave) CFbsBitmap; + CleanupStack::PushL(bitmap); + bitmap->Reset(); + User::LeaveIfError(bitmap->Duplicate(iBitmapHandle)); + } + else + { + User::Leave(KErrArgument); + } + + if ( iMaskHandle ) // optional + { + mask = new (ELeave) CFbsBitmap; + CleanupStack::PushL(mask); + mask->Reset(); + User::LeaveIfError(mask->Duplicate(iMaskHandle)); + CleanupStack::Pop(); // mask + } + + CleanupStack::Pop(); // bitmap + aBitmapMask = mask; + aBitmap = bitmap; + } + + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CAlfAppSrvSession::CAlfAppSrvSession(const CAlfAppServer* aServer) + : CAlfAppSrvSessionBase(aServer), + iExecutionFlags( + EAlfExecuteUsingDynamicBuffer + EAlfExecuteUsingCommonBuffer ) + { + } + +CAlfAppSrvSession* CAlfAppSrvSession::NewL(const CAlfAppServer* aServer) + { + CAlfAppSrvSession* me = new (ELeave) CAlfAppSrvSession(aServer); + CleanupStack::PushL(me); + me->ConstructL(); + CleanupStack::Pop(); + return me; + } + +void CAlfAppSrvSession::ConstructL() + { + BaseConstructL(); + + AlfServer()->SetWindowChangeObserverL(this, TInt(this)); + + iRefreshMode = EHuiRefreshModeAutomatic; + iMaxFrameRate = KAlfUseDefaultFrameRate; + iIdleThreshold = 10 * 1000; // 10 from HuiEnv as seconds + iEffectEnv = CAlfSrvEffectEnv::NewL(*this); + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CAlfAppSrvSession::~CAlfAppSrvSession() + { + iOwnershipItems.ResetAndDestroy(); + + if ( iTextureOwnedIdSet ) + { + CAlfSrvTextureManager& manager = AlfTextureManager(); + TProcessId ownerId = TextureOwnerId(); + manager.DestroyDeletedTextureIds( ownerId ); + manager.RemoveClient( *this ); + } + iTextures.ResetAndDestroy(); + iAnimatedTextures.ResetAndDestroy(); + + delete iEffectEnv; + iEffectEnv = NULL; + + iTextureInfo.Close(); + + iControlGroupOrder.Close(); + } + + +TRect CAlfAppSrvSession::ClientDrawingArea() const + { + return iClientDisplayRect; + } + +void CAlfAppSrvSession::SetClientDrawingArea( const TRect& aRect ) + { + TRAP_IGNORE(SetClientDrawingAreaL(aRect)) + } + +void CAlfAppSrvSession::SetClientDrawingAreaL( const TRect& aRect ) + { + iClientDisplayRect = aRect; + + // Update all the control groups + RPointerArray groups; + CleanupClosePushL( groups ); + GetSubsessionsByTypeL( groups, EHuiObjectTypeControlGroup ); + for ( TInt g = 0 ; g < groups.Count() ; g++ ) + { + CHuiControlGroup* group = groups[g]->AsHuiControlCroup(); + ASSERT( group ); + CHuiLayout* hostContainer = group->Control(0).ContainerLayout( NULL ); + + hostContainer->SetSize( iClientDisplayRect.Size() ); + hostContainer->SetPos( iClientDisplayRect.iTl ); + } + CleanupStack::PopAndDestroy( &groups ); // groups.Close() + } + +// --------------------------------------------------------------------------- +// From class CAlfAppSrvSessionBase. +// Called when client receives focus. +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::FocusGainedL( TBool aDoTransitionEffect ) + { + iFocused = ETrue; + DeliverTextureInfo(); + + // update frame rate + if ( RealCompare( iMaxFrameRate, KAlfUseDefaultFrameRate ) ) + { + SharedHuiEnv()->SetMaxFrameRate( + TReal32(AlfAppUi()->SettingsHandler().DefaultFramerate()) ); + } + else + { + SharedHuiEnv()->SetMaxFrameRate( iMaxFrameRate ); + } + + // update refresh mode + if ( SharedHuiEnv()->RefreshMode() != iRefreshMode ) + { + SharedHuiEnv()->SetRefreshMode( iRefreshMode ); + } + + // update idle threshold + SharedHuiEnv()->SetIdleThreshold( iIdleThreshold ); + + // update display attributes for each display + CHuiDisplay* display = NULL; + RPointerArray displays; + CleanupClosePushL( displays ); + GetSubsessionsByTypeL( displays, EHuiObjectTypeDisplay ); + for ( TInt d = 0 ; d < displays.Count() ; d++ ) + { + CAlfSrvDisplaySubSession* displaySubSession = + static_cast( displays[d] ); + displaySubSession->SetSessionFocused(); + if ( !display && !displaySubSession->IsTvOut()) + { + display = &displaySubSession->Display(); + } + } + CleanupStack::PopAndDestroy( &displays ); // displays.Close() + + if ( !display ) + { + return; + } + + // Enable animated textures for the session + for (TInt index = 0; index < iAnimatedTextures.Count(); index++) + { + iAnimatedTextures.operator[](index)->EnableAnimation(ETrue); + } + + if ( aDoTransitionEffect && AlfServer()->TransitionEffects()->IsEnabled() && + (display->DisplayType() != CHuiDisplay::EDisplayOffScreenBuffer)) + { + ASSERT(AlfServer()->TransitionEffects() != NULL); + AlfServer()->TransitionEffects()->StartPhase( MAlfTransEffectPlugin::EFirstPhase, + aDoTransitionEffect, *iEffectEnv ); + + iControlGroupOrder.Reset(); + } + else + { + ShowControlGroupsInOrderL(*display); + } + + // This is needed for Huitk BitBlit() to succeed + +#ifdef SYMBIAN_BUILD_GCE + SharedHuiEnv()->ContinueRefresh(); +#else + AlfAppUi()->Container()->DrawNow(); +#endif + } + +// --------------------------------------------------------------------------- +// From class CAlfAppSrvSessionBase. +// Called when client loses focus. +// --------------------------------------------------------------------------- +// +TBool CAlfAppSrvSession::FocusLostL( TBool aDoTransitionEffect ) + { + iFocused = EFalse; + + TBool didTransition = EFalse; + + if ( !SharedHuiEnv()->DisplayCount() ) + { + return EFalse; + } + + // Notify displays about losing focus so that tv out can be released + CHuiDisplay* display = NULL; + RPointerArray displays; + CleanupClosePushL( displays ); + GetSubsessionsByTypeL( displays, EHuiObjectTypeDisplay ); + for ( TInt d = 0 ; d < displays.Count() ; d++ ) + { + CAlfSrvDisplaySubSession* displaySubSession = + static_cast( displays[d] ); + displaySubSession->SetSessionFocused(EFalse); + if ( !display && !displaySubSession->IsTvOut()) + { + display = &displaySubSession->Display(); + } + + } + CleanupStack::PopAndDestroy( &displays ); // displays.Close() + + if ( !display ) + { + return didTransition; + } + +/* +#ifdef HUI_FX +*/ + if (display->DisplayType() != CHuiDisplay::EDisplayOffScreenBuffer) + { + // Disable all animated textures for the session + for (TInt index = 0; index < iAnimatedTextures.Count(); index++) + { + iAnimatedTextures.operator[](index)->EnableAnimation(EFalse); + } + + StoreControlGroupOrderL(*display, EFalse ); // do not hide + // background must be drawn as long as the effect is displayed + // as the background will be visible if the effect does not cover full screen + // or is partially transparent. + } +/* +#else + // Do not hide or set transparency if this is off-screen buffer + if (display->DisplayType() != CHuiDisplay::EDisplayOffScreenBuffer) + { + // Disable all animated textures for the session + for (TInt index = 0; index < iAnimatedTextures.Count(); index++) + { + iAnimatedTextures.operator[](index)->EnableAnimation(EFalse); + } + + if ( aDoTransitionEffect && AlfServer()->TransitionEffects()->IsEnabled() ) + { + StoreControlGroupOrderL(*display, EFalse ); // do not hide + ASSERT(AlfServer()->TransitionEffects() != NULL); + AlfServer()->TransitionEffects()->StartPhase( MAlfTransEffectPlugin::EFirstPhase, + aDoTransitionEffect, *iEffectEnv ); + didTransition = ETrue; + } + // Hide control groups + else + { + StoreControlGroupOrderL(*display, ETrue ); // hide as well + } + +#ifdef SYMBIAN_BUILD_GCE + // When alf application is not focused we dont draw background because it is + // not visible as the alf application is not visible either (its controlgroups + // were just hidden in the code above). + display->SetClearBackgroundL(CHuiDisplay::EClearNone); +#endif + } +#endif +*/ + + return didTransition; + } + +void CAlfAppSrvSession::StoreControlGroupOrderL(CHuiDisplay& aDisplay, TBool aAlsoHide ) + { + for ( TInt g = 0 ; g < aDisplay.Roster().Count() ; g++ ) + { + // first append the bottom one + CHuiControlGroup& group = aDisplay.Roster().ControlGroup( g ); + + // make sure we only store control groups for this session + if ( GetHandleFromInterface(EHuiObjectTypeControlGroup, &group) != KErrNotFound ) + { + iControlGroupOrder.AppendL( &group ); + } + } + // at the end the lowest index the bottom most and the biggest index the top most. + + // hide at the end so it does not affect the order of the group in the roster + if ( aAlsoHide ) + { + for ( TInt i = 0 ; i < iControlGroupOrder.Count() ; i++ ) + { + CHuiLayout* hostContainer = iControlGroupOrder[i]->Control(0).ContainerLayout( NULL ); + hostContainer->iOpacity.Set(0.f); + aDisplay.Roster().Hide( *iControlGroupOrder[i] ); + } + } + } + +void CAlfAppSrvSession::ShowControlGroupsInOrderL(CHuiDisplay& aDisplay) + { + while ( iControlGroupOrder.Count() ) + { + CHuiControlGroup& group = *iControlGroupOrder[iControlGroupOrder.Count()-1]; + + // make sure that the group still exists. + if ( GetHandleFromInterface(EHuiObjectTypeControlGroup, &group) != KErrNotFound ) + { + CHuiLayout* hostContainer = group.Control(0).ContainerLayout( NULL ); + hostContainer->iOpacity.Set(1.f); +#ifdef SYMBIAN_BUILD_GCE + AlfAppUi()->ShowControlGroupL(aDisplay.Roster(), group, KAlfRosterShowAtBottom, 0); +#else + aDisplay.Roster().ShowL( group, KAlfRosterShowAtBottom ); +#endif + iControlGroupOrder.Remove(iControlGroupOrder.Count()-1); + } + } + iControlGroupOrder.Reset(); + } + +void CAlfAppSrvSession::ReOrderControlGroupSessionsL( RPointerArray& aGroupSessions ) + { + if ( iControlGroupOrder.Count() && aGroupSessions.Count() > 1 ) + { + // go through the items from bottom to top + for ( TInt g = iControlGroupOrder.Count() -1 ; g >= 0 ; g-- ) + { + CHuiControlGroup* nextGroupFromBottom = iControlGroupOrder[g]; + + // Find the session and move it into first position + for ( TInt s = 0 ; s < aGroupSessions.Count() ; s++ ) + { + CAlfSrvControlGroupSubSession* controlGroupSubSession = static_cast( aGroupSessions[s] ); + if ( &controlGroupSubSession->ControlGroup() == nextGroupFromBottom ) + { + // move into g:th position + aGroupSessions.Remove( s ); + User::LeaveIfError( aGroupSessions.Insert( controlGroupSubSession, 0 ) ); + } + } + } + } + } + +void CAlfAppSrvSession::SetBackgroundMaxFps( TBool aBackground ) + { + + TReal32 newMaxFrameRate = 0; + + // update frame rate + if ( RealCompare( iMaxFrameRate, KAlfUseDefaultFrameRate ) ) + { + newMaxFrameRate = TReal32( AlfAppUi()->SettingsHandler().DefaultFramerate() ); + SharedHuiEnv()->SetMaxFrameRate( + TReal32(AlfAppUi()->SettingsHandler().DefaultFramerate()) ); + } + else + { + newMaxFrameRate = iMaxFrameRate; + } + + if( aBackground ) + { + newMaxFrameRate /= 2; + } + SharedHuiEnv()->SetMaxFrameRate( newMaxFrameRate ); + } + + +// --------------------------------------------------------------------------- +// Is client application focused? +// --------------------------------------------------------------------------- +// +TBool CAlfAppSrvSession::IsFocused() const + { + return iFocused; + } + + +// --------------------------------------------------------------------------- +// From class MWindowVisibilityObserver. +// Called when window becomes fully visible. +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::WindowFullyVisible() + { + iPartiallyVisible = ETrue; + DeliverTextureInfo(); + } + +// --------------------------------------------------------------------------- +// From class MWindowVisibilityObserver. +// Called when window becomes partially visible. +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::WindowPartiallyVisible() + { + iPartiallyVisible = ETrue; + DeliverTextureInfo(); + } + +// --------------------------------------------------------------------------- +// From class MWindowVisibilityObserver. +// Called when window becomes fully invisible. +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::WindowNotVisible() + { + // already not shown... + if ( !iPartiallyVisible ) + { + return; + } + iPartiallyVisible = EFalse; + } + +// --------------------------------------------------------------------------- +// From class MWindowVisibilityObserver. +// Returns window-owning control. +// --------------------------------------------------------------------------- +// +CCoeControl* CAlfAppSrvSession::CoeControl() + { + return NULL;//iCoeDisplay; + } + +CAlfAppServer::TAlfWGPostion CAlfAppSrvSession::PreferredWindowGroupPosition() const + { + if ( iUsesFullScreen ) + { + return CAlfAppServer::EOnTopOfParent; + } + else + { + return CAlfAppServer::EBehindOfParent; + } + } + +THuiRefreshMode CAlfAppSrvSession::PreferredRefreshMode() const + { + return iRefreshMode; + } + + +// --------------------------------------------------------------------------- +// From class CAlfAppSrvSessionBase. +// Called when a message is received from the client. +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::DoHandleCommandL(const RMessage2& aMessage) + { + switch( aMessage.Function() ) + { + case EAlfQtCommandBuffer: + { + PostQtCommandBufferL( aMessage ); + break; + } + + case EAlfEnvSetRefreshMode: + { + EnvSetRefreshModeL( aMessage ); + break; + } + + case EAlfEnvSetMaxFrameRate: + { + EnvSetMaxFrameRateL( aMessage ); + break; + } + + case EAlfEnvContinueRefresh: + { + EnvContinueRefreshL( aMessage ); + break; + } + + case EAlfEnvPauseRefresh: + { + EnvPauseRefreshL( aMessage ); + break; + } + + case EAlfEnvRefreshCallBack: + { + EnvRefreshCallBackL( aMessage ); + break; + } + + case EAlfEnvRenderer: + { + EnvRendererL( aMessage ); + break; + } + case EAlfEnvSetIdleThreshold: + { + EnvSetIdleThresholdL( aMessage ); + break; + } + + case EAlfRosterShow: + { + + // Parse parameters + // 0: control group handle (in) + const TInt cntrlGroupHandle = aMessage.Int0(); + CAlfSrvSubSessionBase& subSession1 = SubSession( cntrlGroupHandle ); + CAlfSrvControlGroupSubSession& controlGroupSubSession = + static_cast(subSession1); + CHuiControlGroup& controlGroup = controlGroupSubSession.ControlGroup(); + + // 1: where (in) + const TInt where = aMessage.Int1(); + // 2: display handle (in) + const TInt displayHandle = aMessage.Int2(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + controlGroupSubSession.SetIsShown( ETrue ); + controlGroupSubSession.PreferredPos() = where; + + // Show only if session is focused, otherwise delay until focus is gained + if (iFocused) + { +#ifdef SYMBIAN_BUILD_GCE + AlfAppUi()->ShowControlGroupL(display.Roster(), controlGroup, where, 0); +#else + display.Roster().ShowL(controlGroup, where); +#endif + AlfServer()->AdjustWindowGroupPositionL( + *CHuiStatic::RootWin(), + ClientWindowGroup(), + PreferredWindowGroupPosition() ); + + } + else + { + if (where == KHuiRosterShowAtTop) + { + if (iControlGroupOrder.Count()) + { + iControlGroupOrder.InsertL(&controlGroup, 0); + } + else + { + iControlGroupOrder.AppendL(&controlGroup); + } + } + else if (where == KHuiRosterShowAtBottom) + { + iControlGroupOrder.AppendL(&controlGroup); + } + else + { + if (iControlGroupOrder.Count() < where) + { + iControlGroupOrder.AppendL(&controlGroup); + } + else + { + iControlGroupOrder.InsertL(&controlGroup, where); + } + } + } + + break; + } + + case EAlfRosterHide: + { + RosterHideL(aMessage); + break; + } + + case EAlfRosterShowVisual: + { + RosterShowVisualL(aMessage); + break; + } + + case EAlfRosterHideVisual: + { + RosterHideVisualL(aMessage); + break; + } + case EAlfRosterMoveVisualToFront: + { + RosterMoveVisualToFrontL(aMessage); + break; + } + case EAlfRosterSetPointerEventFlags: + { + RosterSetPointerEventFlagsL(aMessage); + break; + } + case EAlfRosterAddPointerEventObserver: + { + RosterAddPointerEventObserverL(aMessage); + break; + } + case EAlfRosterRemovePointerEventObserver: + { + RosterRemovePointerEventObserverL(aMessage); + break; + } + case EAlfRosterSetPointerDragTreshold: + { + RosterSetPointerDragTresholdL(aMessage); + break; + } + case EAlfRosterDisableLongTapEventsWhenDragging: + { + RosterDisableLongTapEventWhenDraggingL(aMessage); + break; + } + case EAlfTextureStopAnimation: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureStopAnimation(aMessage); + } + break; + } + case EAlfTextureStartAnimation: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureStartAnimation(aMessage); + } + break; + } + case EAlfTextureCreateAnimated: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureCreateAnimatedL(aMessage); + } + break; + } + case EAlfTextureCreate: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureCreateL(aMessage); + } + break; + } + + case EAlfTextureUnload: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureUnload(aMessage); + } + break; + } + case EAlfTextureDelete: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureDelete(aMessage); + } + break; + } + case EAlfTextureRelease: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureRelease(aMessage); + } + break; + } + case EAlfTextureRestore: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureRestore(aMessage); + } + break; + } + case EAlfTextureNotifySkinChanged: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureNotifySkinChanged(aMessage); + } + break; + } + case EAlfTextureLoad: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureLoadL(aMessage); + } + break; + } + case EAlfTextureBlur: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureBlurL(aMessage); + } + break; + } + case EAlfTextureHasContent: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureHasContentL(aMessage); + } + break; + } + case EAlfTextureUpdateOwnerId: + { + UpdateTextureOwnerIdL( aMessage ); + break; + } + case EAlfTextureSetAutoSizeParams: + { + if ( RequireTextureOwnerId( aMessage ) ) + { + TextureSetAutoSizeParamsL( aMessage ); + } + break; + } + + + case EAlfNotifyAppVisibility: + { + TBool foreground = aMessage.Int0(); + if (ClientWindowGroup() != KErrNotFound) // if Alf client have not set wg, treat it like non-Alf app + { + if ( foreground ) + { +#ifdef SYMBIAN_BUILD_GCE + ActivateContainerLayoutL(ETrue); +#endif + AlfServer()->FocusedWindowGroupChangedL( this ); + AlfServer()->AppUi()->UpdateActiveSession(this); + + // Make sure that Env will refresh the screen + // when we gain focus + AlfServer()->AppUi()->HuiEnv().ContinueRefresh(); + } + else + { + // check if there is some other alf application on top of this one and set + // that application's session as a activesession + CAlfAppSrvSessionBase* newFocusSession = AlfServer()->UpMostClientAboveWg( ClientWindowGroup() ); + + if( newFocusSession ) + { + AlfServer()->FocusedWindowGroupChangedL( newFocusSession ); + } + else + { + // do the "event window" repositioning immediately + AlfServer()->FocusedWindowGroupChangedL( NULL ); + } + + AlfServer()->AppUi()->UpdateActiveSession( newFocusSession ); + + // The following line removes the flickering (=drawing and empty frame) + // when non-alfred application is exited to appshell. +#ifndef SYMBIAN_BUILD_GCE + AlfServer()->AppUi()->Container()->DrawDeferred(); +#endif + } + } + break; + } + + case EAlfGetPointerEvent: + { + TriggerPointerEvent(&aMessage); + return; // don't complete message here + } + + case EAlfCancelPtrEvents: + { + CancelPointerEvents(); + break; + } + + case EAlfGetSystemEvent: + { + GetSystemEvents(&aMessage); + return; // don't complete message here + } + + case EAlfCancelSystemEvents: + { + CancelSystemEvents(); + break; + } + + case ESetFullScreenDrawing: + { + iUsesFullScreen = aMessage.Int0(); + break; + } + case EAlfLayoutMetricsTextStyleData: + { + LayoutMetricsTextStyleDataL(aMessage); + break; + } + + case EAlfSetWgParent: + { + SetParentWindowGroupId(aMessage.Int0()); + break; + } + case EAlfSBufAddObserver: + { + AlfServer()->ScreenBufferManager().AddScreenBufferObserver(this, aMessage); + return; // message is completed in the method above + } + case EAlfSBufRemoveObserver: + { + AlfServer()->ScreenBufferManager().RemoveScreenBufferObserver(this, aMessage); + break; + } + case EAlfSBufRequestNextBuffer: + { + AlfServer()->ScreenBufferManager().RequestNextBuffer(this, aMessage); + return; // message is completed in the method above + } + case EAlfSBufRequestBufferDraw: + { + AlfServer()->ScreenBufferManager().RequestBufferDraw(this, aMessage); + return; // message is completed in the method above + } + case EAlfSBufRequestEvent: + { + AlfServer()->ScreenBufferManager().RequestScreenBufferEvent(this, aMessage); + return; // don't complete message here + } + + case EAlfDoSubSessionBatchCmd: + { + ExecuteBatchCommandsL(aMessage); + break; + } + + case EAlfConfigureBatchCmd: + { + ConfigureBatchCommandExecutionL( aMessage ); + break; + } + + case EAlfNotifyTextureInfo: + { + NotifyTextureInfo( aMessage ); + } + return; + + case EAlfCancelNotifyTextureInfo: + { + if ( !iTextureInfoEvent.IsNull() ) + { + iTextureInfoEvent.Complete( KErrCancel ); + } + } + break; + case EAlfDirectClientFPSCounterOn: + { + ReportFrameRateBegin( aMessage ); + break; + } + case EAlfDirectClientFPSCounterOff: + { + ReportFrameRateEnd( aMessage ); + break; + } + case EAlfEnableLowMemoryState: + { + EnvEnableLowMemoryState( aMessage ); + break; + } + + case EAlfForceSwRendering: + { + EnvForceSwRendering( aMessage ); + break; + } + + + default: + User::Leave( KErrNotSupported ); + } + + if ( !aMessage.IsNull() ) + { + aMessage.Complete( KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : SetRefreshMode +// param 0 : IN refresh mode in THuiRefreshMode +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvSetRefreshModeL(const RMessage2& aMessage) + { + // 0: refresh mode (in) + const THuiRefreshMode newMode = static_cast(aMessage.Int0()); + + if ( iRefreshMode != newMode ) + { + iRefreshMode = newMode; + + if ( iFocused ) + { + SharedHuiEnv()->SetRefreshMode( iRefreshMode ); + } + } + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : SetMaxFrameRate +// param 0 : IN framerate in Int +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvSetMaxFrameRateL(const RMessage2& aMessage) + { + // 0: max framerate in TPckgC (in) + TReal32 newRate = KAlfUseDefaultFrameRate; + TPckg frameRatePckg(newRate); + aMessage.Read(0,frameRatePckg); + + if ( !RealCompare( iMaxFrameRate, newRate ) ) + { + iMaxFrameRate = newRate; + + if ( iFocused ) + { + if ( RealCompare( iMaxFrameRate, KAlfUseDefaultFrameRate ) ) + { + SharedHuiEnv()->SetMaxFrameRate( + TReal32(AlfAppUi()->SettingsHandler().DefaultFramerate() ) ); + } + else + { + SharedHuiEnv()->SetMaxFrameRate( iMaxFrameRate ); + } + } + } + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : ContinueRefresh +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvContinueRefreshL(const RMessage2& /*aMessage*/) + { + SharedHuiEnv()->ContinueRefresh(); + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : PauseRefresh +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvPauseRefreshL(const RMessage2& /*aMessage*/) + { + SharedHuiEnv()->PauseRefresh(); + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : RefreshCallBack +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvRefreshCallBackL(const RMessage2& /*aMessage*/) + { + CHuiEnv::RefreshCallBack( SharedHuiEnv() ); + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : SetIdleThreshold +// param 0 : IN Idle threshold time in milliseconds +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvSetIdleThresholdL(const RMessage2& aMessage) + { + // 0: time in milliseconds (in) + const TInt time = (TInt)aMessage.Int0(); + + if ( iIdleThreshold != time ) + { + iIdleThreshold = time; + + if ( iFocused ) + { + SharedHuiEnv()->SetIdleThreshold( iIdleThreshold ); + } + } + } + +// --------------------------------------------------------------------------- +// class : CHuiEnv +// function : Renderer +// param 0 : IN/OUT renderer +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvRendererL(const RMessage2& aMessage) + { + // Parse parameters + + // 0: renderer (in/out) + TInt renderer = 0; + TPckg rendererPckg(renderer); + aMessage.Read(0,rendererPckg); + renderer = SharedHuiEnv()->Renderer(); + aMessage.Write(0,rendererPckg); + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : Hide +// param 0 : IN Handle to CHuiControlGroup object +// param 1 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterHideL(const RMessage2& aMessage) + { + // Parse parameters + // 0: control group handle (in) + const TInt cntrlGroupHandle = aMessage.Int0(); + CAlfSrvSubSessionBase& subSession1 = SubSession( cntrlGroupHandle ); + CAlfSrvControlGroupSubSession& controlGroupSubSession = + static_cast(subSession1); + CHuiControlGroup& controlGroup = controlGroupSubSession.ControlGroup(); + + // 1: display handle (in) + const TInt displayHandle = aMessage.Int1(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + // hide + controlGroupSubSession.SetIsShown( EFalse ); + + // hide from the roster only if session is focused + if ( iFocused ) + { + display.Roster().Hide(controlGroup); + } + else // otherwise remove from the iControlGroupOrder array + { + TInt index = iControlGroupOrder.Find( &controlGroup ); + if( index != KErrNotFound) + { + iControlGroupOrder.Remove( index ); + } + } + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : ShowVisualL +// param 0 : IN Handle to CHuiVisual object +// param 1 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterShowVisualL(const RMessage2& aMessage) + { + // Parse parameters + // 0: visual handle (in) + TAny* huiVisualAnyPtr = GetInterfaceL( EHuiObjectTypeVisual, aMessage.Int0() ); + CHuiVisual* huiVisual = static_cast(huiVisualAnyPtr); + + // 1: display handle (in) + const TInt displayHandle = aMessage.Int1(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + // show visual + display.Roster().ShowVisualL(huiVisual); + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : HideVisual +// param 0 : IN Handle to CHuiVisual object +// param 1 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterHideVisualL(const RMessage2& aMessage) + { + // Parse parameters + // 0: visual handle (in) + TAny* huiVisualAnyPtr = GetInterfaceL( EHuiObjectTypeVisual, aMessage.Int0() ); + CHuiVisual* huiVisual = static_cast(huiVisualAnyPtr); + + // 1: display handle (in) + const TInt displayHandle = aMessage.Int1(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + // show visual + display.Roster().HideVisual(huiVisual); + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : MoveVisualToFront +// param 0 : IN Handle to CHuiVisual object +// param 1 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterMoveVisualToFrontL(const RMessage2& aMessage) + { + // Parse parameters + // 0: visual handle (in) + TAny* huiVisualAnyPtr = GetInterfaceL( EHuiObjectTypeVisual, aMessage.Int0() ); + CHuiVisual* huiVisual = static_cast(huiVisualAnyPtr); + + // 1: display handle (in) + const TInt displayHandle = aMessage.Int1(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + // move visual to front +#ifdef SYMBIAN_BUILD_GCE + TInt firstAlfPositionInRoster = AlfAppUi()->FirstAlfControlGroupIndex(); + display.Roster().Move(huiVisual, firstAlfPositionInRoster); + +#else + display.Roster().MoveVisualToFront(huiVisual); +#endif + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : Observers().AppendIfNotFoundL, Observers.RemoveIfFound +// param 0 : IN flags +// param 1 : IN Handle to CHuiControl object +// param 2 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterSetPointerEventFlagsL(const RMessage2& aMessage) + { + // 0: flags (in) + const TInt flags = aMessage.Int0(); + + // 1: control handle (in) + TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int1() ); + CHuiControl* huiControl = static_cast(huiControlAnyPtr); + + // 2: display handle (in) + const TInt displayHandle = aMessage.Int2(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + if ( flags & EAlfPointerEventReportDrag ) + { + display.Roster().Observers(EHuiInputPointerDrag).AppendIfNotFoundL(*huiControl); + } + else + { + display.Roster().Observers(EHuiInputPointerDrag).RemoveIfFound(*huiControl); + } + + if ( flags & EAlfPointerEventReportLongTap ) + { + display.Roster().Observers(EHuiInputPointerLongTap).AppendIfNotFoundL(*huiControl); + } + else + { + display.Roster().Observers(EHuiInputPointerLongTap).RemoveIfFound(*huiControl); + } + + if ( flags & EAlfPointerEventReportUnhandled ) + { + display.Roster().Observers(EHuiInputPointerUnhandled).AppendIfNotFoundL(*huiControl); + } + else + { + display.Roster().Observers(EHuiInputPointerUnhandled).RemoveIfFound(*huiControl); + } + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : Observers().AppendIfNotFoundL +// param 0 : IN TAlfPointerEventFlags +// param 1 : IN Handle to CHuiControl object +// param 2 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterAddPointerEventObserverL(const RMessage2& aMessage) + { + // 0: observer (in) + const TAlfPointerEventFlags observer = (TAlfPointerEventFlags)aMessage.Int0(); + + // 1: control handle (in) + TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int1() ); + CHuiControl* huiControl = static_cast(huiControlAnyPtr); + + // 2: display handle (in) + const TInt displayHandle = aMessage.Int2(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + // add observer + THuiInputType huiType = EHuiInputPointerDrag; + switch ( observer ) + { + case EAlfPointerEventReportDrag: + huiType = EHuiInputPointerDrag; + break; + case EAlfPointerEventReportLongTap: + huiType = EHuiInputPointerLongTap; + break; + case EAlfPointerEventReportUnhandled: + huiType = EHuiInputPointerUnhandled; + break; + default: + User::Leave( KErrNotSupported ); + } + + display.Roster().Observers(huiType).AppendIfNotFoundL(*huiControl); + } + + // --------------------------------------------------------------------------- +// class : CHuiRoster +// function : Observers.RemoveIfFound +// param 0 : IN TAlfPointerEventFlags +// param 1 : IN Handle to CHuiControl object +// param 2 : IN Handle to CHuiDisplay object +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterRemovePointerEventObserverL(const RMessage2& aMessage) + { + // 0: observer (in) + const TAlfPointerEventFlags observer = (TAlfPointerEventFlags)aMessage.Int0(); + + // 1: control handle (in) + TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int1() ); + CHuiControl* huiControl = static_cast(huiControlAnyPtr); + + // 2: display handle (in) + const TInt displayHandle = aMessage.Int2(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + // remove observer + THuiInputType huiType = EHuiInputPointerDrag; + switch ( observer ) + { + case EAlfPointerEventReportDrag: + huiType = EHuiInputPointerDrag; + break; + case EAlfPointerEventReportLongTap: + huiType = EHuiInputPointerLongTap; + break; + case EAlfPointerEventReportUnhandled: + huiType = EHuiInputPointerUnhandled; + break; + default: + User::Leave( KErrNotSupported ); + } + + display.Roster().Observers(huiType).RemoveIfFound(*huiControl); + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : +// param 0 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterSetPointerDragTresholdL(const RMessage2& aMessage) + { + // Parse parameters + TAlfPointerEventDragTreshold params; + TPckg paramsPckg(params); + aMessage.Read(0,paramsPckg); + + // control handle + TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, params.iControlHandle ); + CHuiControl* huiControl = static_cast(huiControlAnyPtr); + + // display handle + CAlfSrvSubSessionBase& subSession2 = SubSession( params.iDisplayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + THuiXYMetric huiXYMetric; + AlfXYMetricUtility::CopyMetric(params.iXYMetric, huiXYMetric); + + display.Roster().SetPointerDragThresholdL(*huiControl, huiXYMetric ); + + } + +// --------------------------------------------------------------------------- +// class : CHuiRoster +// function : +// param 0 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::RosterDisableLongTapEventWhenDraggingL(const RMessage2& aMessage) + { + // Parse parameters + // control handle (in) + TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int0() ); + CHuiControl* huiControl = static_cast(huiControlAnyPtr); + + // observer (in) + const TBool disable = (TBool)aMessage.Int1(); + + // display handle (in) + const TInt displayHandle = aMessage.Int2(); + CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle ); + CAlfSrvDisplaySubSession& displaySubSession = + static_cast(subSession2); + CHuiDisplay& display = displaySubSession.Display(); + + display.Roster().DisableLongTapEventsWhenDraggingL(*huiControl, disable); + } + +// --------------------------------------------------------------------------- +// class : +// function : +// param 0 : +// param 1 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureCreateL(const RMessage2& aMessage) + { + // Owner id is stored in UpdateTextureOwnerIdL via IPC command + // EAlfTextureUpdateOwnerId. + + // Parse parameters + + // 0: handle (in/out) + TInt handle; + TPckg handlePckg(handle); + aMessage.Read(0,handlePckg); + + // 1: TAlfTextureCreateParams (in) + TAlfCreateTextureParams params; + TPckg paramsPckg(params); + aMessage.Read(1,paramsPckg); + + + CHuiEnv* env = SharedHuiEnv(); + if (params.iBitmapHandle && params.iId != 0) + { + const TInt bitmapHandle = params.iBitmapHandle; + const TInt maskHandle = params.iMaskBitmapHandle; + const TInt flags = params.iFlags; + const TInt managerId = params.iManagerId; + const TInt id = + AlfTextureManager().CreateTextureId( + TextureOwnerId(), + params.iId, + managerId, + ETrue ); + + CSharedBitmapProvider* provider = new (ELeave) CSharedBitmapProvider(bitmapHandle, maskHandle); + CleanupStack::PushL(provider); + + // Convert the TAlfTextureFlags to THuiTextureUploadFlags + TInt inputFlags = flags; + inputFlags &= ~EAlfTextureFlagSkinContent; + inputFlags &= ~EAlfTextureFlagAutoSize; + inputFlags &= ~EAlfTextureFlagLoadAnimAsImage; + + TBool textureAlreadyExists = (env->TextureManager().Texture(id) != &env->TextureManager().BlankTexture()); + + CHuiTexture& texture = env->TextureManager().CreateTextureL(id, + provider, + (THuiTextureUploadFlags)inputFlags); + + // If we are reusing deleted texture, remove it from "deleted" array + TInt index = iTextures.Find(&texture); + if (index != KErrNotFound) + { + iTextures.Remove(index); + } + + + // Add texture to skin content + texture.SetSkinContent((flags & EAlfTextureFlagSkinContent) != 0); + + // Add texture to automatic dynamic size calculations + texture.EnableAutoSizeCalculation((flags & EAlfTextureFlagAutoSize) != 0); + + // Check if texture already existed, if yes then we need to update its content + // because + if (textureAlreadyExists) + { + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + provider->ProvideBitmapL(0, bitmap, mask); + CleanupStack::PushL(bitmap); + CleanupStack::PushL(mask); + texture.EnableShadow((flags & EHuiTextureUploadFlagGenerateShadow) != 0); + TSize bitmapSize = bitmap->SizeInPixels(); + if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0) + { + // This uses direct upload if possible and specified in the upload flags + TRAPD(err, env->TextureManager().UpdateTextureFromBitmapL(id, provider)) + + if (err != KErrNone) + { + // We do this because texture may be in undetermined state (?) + texture.Reset(); + User::Leave(err); + } + } + texture.SetSize(bitmap->SizeInPixels()); + CleanupStack::PopAndDestroy(2); // bitmap, mask + } + + // We delete provider here, because the release/restore + // is supported in the client library. There is currently + // no need to restore textures in the server. + CleanupStack::PopAndDestroy(); // provider; + + // Write parameters + handle = TInt((MHuiTexture*)(&texture)); + aMessage.Write(0,handlePckg); + } + else + { + CHuiTexture& texture = env->TextureManager().BlankTexture(); + // Write parameters + handle = TInt((MHuiTexture*)(&texture)); + aMessage.Write(0,handlePckg); + } + } + +void CAlfAppSrvSession::TextureCreateAnimatedL(const RMessage2& aMessage) + { + // Parse parameters + + // 0: handle (in/out) + TInt handle = 0; + TPckg handlePckg(handle); + aMessage.Read(0,handlePckg); + + // 1: TAlfTextureCreateParams (in) + TAlfCreateTextureAnimatedParams params; + TPckg paramsPckg(params); + aMessage.Read(1,paramsPckg); + CHuiEnv* env = SharedHuiEnv(); + + CHuiGifAnimationTexture* animtext = CHuiGifAnimationTexture::NewL(params.iFilename,env->TextureManager(),params.iId, (THuiTextureUploadFlags)(params.iFlags)); + //MHuiTexture* foo = dynamic_cast(animtext); + iAnimatedTextures.Append(animtext); + handle = TInt((MHuiTexture*)(animtext)); + aMessage.Write(0,handlePckg); + } + + + + +// --------------------------------------------------------------------------- +// class : +// function : +// param 0 : +// param 1 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureLoadL(const RMessage2& aMessage) + { + // Owner id is stored in UpdateTextureOwnerIdL via IPC command + // EAlfTextureUpdateOwnerId. + + // 0: handle (in/out) + TInt handle = 0; + TPckg handlePckg(handle); + aMessage.Read(0,handlePckg); + + // 1: TAlfTextureLoadParams (in) + TAlfLoadTextureParams params; + TPckg paramsPckg(params); + aMessage.Read(1,paramsPckg); + + const TInt bitmapHandle = params.iBitmapHandle; + const TInt maskHandle = params.iMaskBitmapHandle; + const TInt flags = params.iFlags; + const TInt managerId = params.iManagerId; + const TInt id = + AlfTextureManager().CreateTextureId( + TextureOwnerId(), + params.iId, + managerId, + ETrue ); + + CHuiEnv* env = SharedHuiEnv(); + if (bitmapHandle && params.iId != 0) + { + CSharedBitmapProvider* provider = + new (ELeave) CSharedBitmapProvider(bitmapHandle, maskHandle); + CleanupStack::PushL(provider); + + // Convert the TAlfTextureFlags to THuiTextureUploadFlags + TInt inputFlags = (THuiTextureUploadFlags)flags; + inputFlags &= ~EAlfTextureFlagSkinContent; + inputFlags &= ~EAlfTextureFlagAutoSize; + inputFlags &= ~EAlfTextureFlagLoadAnimAsImage; + + TBool textureAlreadyExists = (env->TextureManager().Texture(id) != &env->TextureManager().BlankTexture()); + + // Make sure texture exists + CHuiTexture& textureRef = env->TextureManager().CreateTextureL(id, provider, THuiTextureUploadFlags(inputFlags)); + + // If we are reusing deleted texture, remove it from "deleted" array + TInt index = iTextures.Find(&textureRef); + if (index != KErrNotFound) + { + iTextures.Remove(index); + } + + // Add texture to skin content + textureRef.SetSkinContent((flags & EAlfTextureFlagSkinContent) != 0); + + // Add texture to automatic dynamic size calculations + textureRef.EnableAutoSizeCalculation((flags & EAlfTextureFlagAutoSize) != 0); + + // Upload texture, this is needed because CreateTexture does not necessarely do anything if texture + // already exists. + if (textureAlreadyExists) + { + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + provider->ProvideBitmapL(id, bitmap, mask); + CleanupStack::PushL(bitmap); + CleanupStack::PushL(mask); + textureRef.EnableShadow((flags & EHuiTextureUploadFlagGenerateShadow) != 0); + TSize bitmapSize = bitmap->SizeInPixels(); + if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0) + { + // This uses direct upload if possible and specified in the upload flags + TRAPD(err, env->TextureManager().UpdateTextureFromBitmapL(id, provider)) + + if (err != KErrNone) + { + // We do this because texture may be in undetermined state (?) + textureRef.Reset(); + User::Leave(err); + } + } + textureRef.SetSize(bitmap->SizeInPixels()); + CleanupStack::PopAndDestroy(2); // bitmap, mask + } + // We delete provider here, because the release/restore + // is supported in the client library. There is currently + // no need to restore textures in the server. + CleanupStack::PopAndDestroy( provider ); + + + // Write parameters + handle = TInt((MHuiTexture*)(&textureRef)); + aMessage.Write(0,handlePckg); + } + else + { + CHuiTexture& texture = env->TextureManager().BlankTexture(); + // Write parameters + handle = TInt((MHuiTexture*)(&texture)); + aMessage.Write(0,handlePckg); + } + + } + +// --------------------------------------------------------------------------- +// class : CHuiTextureManager +// function : UnloadTexture +// param 0 : IN Texture id +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureUnload(const RMessage2& aMessage) + { + // Parse parameters + + // 0: id (in) + const TInt originalId = aMessage.Int0(); + const TInt managerId = aMessage.Int1(); + + if (originalId != 0) + { + const TInt id = + AlfTextureManager().ExistingTextureId( + TextureOwnerId(), originalId, managerId); + + if ( id != 0 && + AlfTextureManager().ReleaseTextureId( + TextureOwnerId(), originalId, managerId ) == 0) + { + if ( !managerId ) + { + RemoveTextureInfo( originalId ); + } + + CHuiEnv* env = SharedHuiEnv(); + env->TextureManager().UnloadTexture(id); + } + } + } + +// --------------------------------------------------------------------------- +// class : +// function : +// param 0 : IN Texture id +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureDelete(const RMessage2& aMessage) + { + // Parse parameters + + // 0: id (in) + const TInt originalId = aMessage.Int0(); + const TInt managerId = aMessage.Int1(); + + if (originalId != 0) + { + const TInt id = + AlfTextureManager().ExistingTextureId( + TextureOwnerId(), originalId, managerId ); + + if ( id != 0 && + AlfTextureManager().ReleaseTextureId( + TextureOwnerId(), originalId, managerId ) == 0) + { + CHuiEnv* env = SharedHuiEnv(); + env->TextureManager().UnloadTexture(id); + + if ( !managerId ) + { + RemoveTextureInfo( originalId ); + } + + if ( AlfTextureManager().DeleteTextureId( + TextureOwnerId(), originalId, managerId) == 0 ) + { + // For now just unload textures, actual deletion happens + // when session is closed (for safety reasons). + CHuiTexture* texture = env->TextureManager().Texture(id); + if (texture) + { + // We should set texture attributes to default values + // here if we recycle hui-textures during this session. + texture->SetAutoSizeParams(THuiTextureAutoSizeParams()); + texture->EnableShadow(EFalse); + texture->SetSkinContent(EFalse); + + if (iTextures.Find(texture) == KErrNotFound) + { + iTextures.Append(texture); + } + } + } + } + } + } + +// --------------------------------------------------------------------------- +// class : CHuiTextureManager +// function : +// param 0 : IN Texture id +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureRelease(const RMessage2& aMessage) + { + // Parse parameters + + // 0: id (in) + const TInt originalId = aMessage.Int0(); + const TInt managerId = aMessage.Int1(); + + if (originalId != 0) + { + // Just release texture id + AlfTextureManager().ReleaseTextureId( + TextureOwnerId(), originalId, managerId ); + } + } + +// --------------------------------------------------------------------------- +// class : CHuiTextureManager +// function : +// param 0 : IN Texture id +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureRestore(const RMessage2& aMessage) + { + // Parse parameters + + // 0: id (in) + const TInt originalId = aMessage.Int0(); + const TInt managerId = aMessage.Int1(); + + if (originalId != 0) + { + // Just restore texture id + AlfTextureManager().CreateTextureId( + TextureOwnerId(), originalId, managerId, EFalse ); + } + } + +// --------------------------------------------------------------------------- +// class : CHuiTextureManager +// function : +// param 0 : IN Texture id +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureNotifySkinChanged(const RMessage2& aMessage) + { + // Parse parameters + + // 0: id (in) + const TInt originalId = aMessage.Int0(); + const TInt managerId = aMessage.Int1(); + + if (originalId != 0) + { + const TInt id = + AlfTextureManager().ExistingTextureId( + TextureOwnerId(), originalId, managerId ); + + if ( id != 0 && + AlfTextureManager().ValidateSkinForTextureId( + TextureOwnerId(), originalId, managerId ) == 0) + { + CHuiEnv* env = SharedHuiEnv(); + env->TextureManager().UnloadTexture(id); + } + } + } + +static CHuiTexture* CastTexture( MHuiTexture* aMHuiTexture ) + { + CHuiTexture* resultCHuiTexture = NULL; + if ( aMHuiTexture ) + { + // only CHuiTexture implements the MHuiShadowedTexture interface + MHuiShadowedTexture* shadowedTexture = aMHuiTexture->ShadowedTexture(); + if ( shadowedTexture ) + { + resultCHuiTexture = static_cast( shadowedTexture ); + } + } + + return resultCHuiTexture; + } + +// --------------------------------------------------------------------------- +// class : +// function : +// param 0 : +// param 1 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureBlurL(const RMessage2& aMessage) + { + // Parse parameters + + // 0: TAlfBlurTextureParams (in) + TAlfBlurTextureParams params; + TPckg paramsPckg(params); + aMessage.Read(0,paramsPckg); + + CHuiEnv* env = SharedHuiEnv(); + if (params.iServerSideSrcHandle && params.iServerSideDstHandle) + { + CHuiTexture* srcTexture = CastTexture(reinterpret_cast(params.iServerSideSrcHandle)); + CHuiTexture* dstTexture = CastTexture(reinterpret_cast(params.iServerSideDstHandle)); + + if (srcTexture && dstTexture) + { + + const THuiTextureHandle srcHandle = srcTexture->Handle(); + THuiTextureHandle dstHandle = dstTexture->Handle(); + const TSize size = params.iPreferredSize; + + env->TextureManager().Processor().BlurL(srcHandle, + dstHandle, + size, + params.iFilterSize, + params.iFlag); + } + else + { + User::Leave(KErrArgument); + } + } + } + +// --------------------------------------------------------------------------- +// class : +// function : +// param 0 : +// param 1 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureHasContentL(const RMessage2& aMessage) + { + + // 0: ret val (in/out) + TBool retVal = EFalse; + TPckg retValPckg(retVal); + aMessage.Read(0,retValPckg); + + // 1: id (in) + const TInt originalId = aMessage.Int1(); + + // 2: manager id (in) + const TInt managerId = aMessage.Int2(); + + if (originalId != 0) + { + const TInt id = + AlfTextureManager().ExistingTextureId( + TextureOwnerId(), originalId, managerId, ETrue); + + if (id != 0) + { + CHuiEnv* env = SharedHuiEnv(); + CHuiTexture* tex = env->TextureManager().Texture(id); + if (tex) + { + retVal = tex->HasContent(); + } + } + } + aMessage.Write(0,retValPckg); + } + +void CAlfAppSrvSession::TextureStartAnimation(const RMessage2& aMessage) + { + TInt id = aMessage.Int0(); + CHuiGifAnimationTexture* tex = NULL; + for (TInt index = 0; index < iAnimatedTextures.Count(); index++) + { + tex = iAnimatedTextures.operator[](index); + if (tex->Id() == id) + { + tex->Start(); + break; + } + } + } + +void CAlfAppSrvSession::TextureStopAnimation(const RMessage2& aMessage) + { + TInt id = aMessage.Int0(); + CHuiGifAnimationTexture* tex = NULL; + for (TInt index = 0; index < iAnimatedTextures.Count(); index++) + { + tex = iAnimatedTextures.operator[](index); + if (tex->Id() == id) + { + tex->Stop(); + break; + } + } + } + +// --------------------------------------------------------------------------- +// class : +// function : +// param 0 : +// param 1 : +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::TextureSetAutoSizeParamsL(const RMessage2& aMessage) + { + + // 0: id (in) + const TInt originalId = aMessage.Int0(); + + // 1: manager id (in) + const TInt managerId = aMessage.Int1(); + + // 2: params (in) + TAlfTextureAutoSizeParams params; + TPckg paramPckg(params); + aMessage.Read(2,paramPckg); + + + if (originalId != 0) + { + const TInt id = + AlfTextureManager().ExistingTextureId( + TextureOwnerId(), originalId, managerId, ETrue); + + if (id != 0) + { + CHuiEnv* env = SharedHuiEnv(); + CHuiTexture* tex = env->TextureManager().Texture(id); + if (tex) + { + THuiTextureAutoSizeParams* huiparams = (THuiTextureAutoSizeParams*) ¶ms; + tex->SetAutoSizeParams(*huiparams); + } + } + } + } + +void CAlfAppSrvSession::LayoutMetricsTextStyleDataL(const RMessage2& aMessage) + { + // 0: ret val (in/out) + TInt retVal = 0; + TPckg retValPckg(retVal); + aMessage.Read(0,retValPckg); + + // 1: textStyle (in) + const TInt textStyle = aMessage.Int1(); + + CHuiEnv* env = SharedHuiEnv(); + retVal = env->TextStyleManager().TextStyle(textStyle)->FontStyleId(); + + aMessage.Write(0,retValPckg); + } + +TBool CAlfAppSrvSession::RequireTextureOwnerId(const RMessage2& aMessage) + { + if ( !iTextureOwnedIdSet ) + { + AlfPanicClient( aMessage, EAlfSrvTexturePanicTextureOwnerIdNotUpdated ); + } + + return iTextureOwnedIdSet; + } + +void CAlfAppSrvSession::UpdateTextureOwnerIdL(const RMessage2& aMessage) + { + if ( !iTextureOwnedIdSet ) + { + // Open process, get id and then close. + RThread client; + User::LeaveIfError( aMessage.Client(client) ); + CleanupClosePushL( client ); + RProcess process; + User::LeaveIfError( client.Process( process ) ); + TProcessId id = process.Id(); + process.Close(); + CleanupStack::PopAndDestroy( &client ); + + // Register & then store owner id. + AlfTextureManager().AddClientL( id, *this ); + iTextureOwnedIdSet = ETrue; + iTextureOwnerId = id; + } + } + +inline TProcessId CAlfAppSrvSession::TextureOwnerId() const + { + __ASSERT_ALWAYS( iTextureOwnedIdSet, USER_INVARIANT() ); + return iTextureOwnerId; + } + +void CAlfAppSrvSession::ConfigureBatchCommandExecutionL( + const RMessage2& aMessage ) + { + // This should be called only by unit tests. Anyway, + // this has impact on this session only, so it does + // not cause any problems. + __ALFLOGSTRING1( "ConfigureBatchCommandExecutionL: %x", aMessage.Int0() ) + iExecutionFlags = aMessage.Int0(); + } + +void CAlfAppSrvSession::ExecuteBatchCommandsL(const RMessage2& aMessage) + { + // First, let's try to execute using dynamic buffer.. + if ( !AllowExecuteUsingDynamicBuffer() || + !ExecuteBatchCommandsUsingDynamicBufferL( aMessage ) ) + { + // If that fails, then try with fixed buffer. + ExecuteBatchCommandsUsingFixedBufferL( aMessage ); + } + } + +TBool CAlfAppSrvSession::ExecuteBatchCommandsUsingDynamicBufferL( + const RMessage2& aMessage ) + { + TBool result = EFalse; + + CAlfAppServer* server = AlfServer(); + + const TInt commonBatchBufferLength = + server->CommonCommandBatchBufferMaxLength(); + + const TInt requiredBufferLength = aMessage.GetDesLengthL(0); + + TBool commonBatchBufferAcquired = EFalse; + + // This will finally hold reference to buffer to be used for + // reading message from client side. + TPtr8 ptrBuffer( 0, 0 ); + + // First, try to acquire common command batch buffer + // (if it's not in use and it has sufficient space) + if ( AllowExecuteUsingCommonBuffer() && + ( commonBatchBufferLength >= requiredBufferLength ) ) + { + commonBatchBufferAcquired = + server->AcquireCommonCommandBatchBuffer( ptrBuffer ); + } + + // If common command batch buffer were not usable, + // let's try to allocate bigger buffer. + HBufC8* memoryBuffer = NULL; + if ( commonBatchBufferAcquired ) + { + result = ETrue; + } + else + { + memoryBuffer = HBufC8::New( requiredBufferLength ); + if ( memoryBuffer ) + { + result = ETrue; + ptrBuffer.Set( memoryBuffer->Des() ); + } + } + + if ( result ) + { + TInt err = aMessage.Read( 0, ptrBuffer ); + + if ( err != KErrNone ) + { + // Release and then leave. + if ( memoryBuffer ) + { + delete memoryBuffer; + memoryBuffer = NULL; + } + if ( commonBatchBufferAcquired ) + { + server->ReleaseCommonCommandBatchBuffer(); + } + + User::Leave( err ); + } + + TInt dummy; + TInt length = 0; + + // Note - this method is implemented so that this works even in OOM, that's + // why TRAP is used here intentionally. + TRAP( err, length = ExecuteCommandsFromDescriptorL( ptrBuffer, dummy ) ); + const TInt ptrBufferLength = ptrBuffer.Length(); + + // Release - note that buffer length must be fetched before deletion. + if ( memoryBuffer ) + { + delete memoryBuffer; + memoryBuffer = NULL; + } + if ( commonBatchBufferAcquired ) + { + server->ReleaseCommonCommandBatchBuffer(); + } + +#ifdef _ALF_LOGGING + if ( err != KErrNone ) + { + __ALFLOGSTRING3( + "ExecuteBatchCommandsUsingDynamicBufferL execution failed, err=%d (%d,%d)", + err, length, ptrBufferLength ) + } +#endif // _ALF_LOGGING + + if ( !err && ( length != ptrBufferLength ) ) + { + // All commands were not executed! + __ALFLOGSTRING2( + "ExecuteBatchCommandsUsingDynamicBufferL corrupted buffer (%d,%d)", + length, ptrBufferLength ) + err = KErrCorrupt; + } + + User::LeaveIfError( err ); + } + + return result; + } + +void CAlfAppSrvSession::ExecuteBatchCommandsUsingFixedBufferL( + const RMessage2& aMessage ) + { + CAlfAppServer* server = AlfServer(); + const TInt messageLength = aMessage.GetDesLengthL(0); + + TBufC8< KAlfStackBatchBufferSize > stackBuffer; + TPtr8 ptrBuffer( stackBuffer.Des() ); + + TBool commonBatchBufferAcquired = EFalse; + if ( AllowExecuteUsingCommonBuffer() ) + { + commonBatchBufferAcquired = + server->AcquireCommonCommandBatchBuffer( ptrBuffer ); + } + + TInt length = 0; + + // Note - this method is implemented so that this works even in OOM, that's + // why TRAP is used here intentionally. + TRAPD( err, length = + ExecuteBatchCommandsUsingBufferL( ptrBuffer, messageLength, aMessage ) ); + + if ( commonBatchBufferAcquired ) + { + server->ReleaseCommonCommandBatchBuffer(); + } + +#ifdef _ALF_LOGGING + if ( err != KErrNone ) + { + __ALFLOGSTRING3( + "ExecuteBatchCommandsUsingFixedBufferL execution failed, err=%d (%d,%d)", + err, length, messageLength ) + } +#endif // _ALF_LOGGING + + if ( !err && ( length != messageLength ) ) + { + // All commands were not executed! + __ALFLOGSTRING2( + "ExecuteBatchCommandsUsingFixedBufferL corrupted buffer (%d,%d)", + length, messageLength ) + + err = KErrCorrupt; + } + + User::LeaveIfError( err ); + } + +TInt CAlfAppSrvSession::ExecuteBatchCommandsUsingBufferL( + TDes8& aBuffer, + TInt aMessageLength, + const RMessage2& aMessage ) + { + const TInt bufferMaxLength = aBuffer.MaxLength(); + + // It is assumed that bufferMaxLength > command header length. + // If you check ExecuteBatchCommandsUsingFixedBufferL, you can see + // that this assumption holds. + + TInt offset = 0; + TBool failed = EFalse; + + while ( !failed && ( offset < aMessageLength ) ) + { + aMessage.ReadL( 0, aBuffer, offset ); + + TInt spaceNeeded = 0; + offset += ExecuteCommandsFromDescriptorL( aBuffer, spaceNeeded ); + + if ( spaceNeeded > ( aMessageLength - offset ) ) + { + // More space is needed than there is left in message. + failed = ETrue; + } + else if ( spaceNeeded > bufferMaxLength ) + { + // Too bad, message does not fit to our fixed size buffer. + // Let's try to allocate buffer for this. + + HBufC8* buffer = HBufC8::NewLC( spaceNeeded ); + TPtr8 bufferPtr = buffer->Des(); + + aMessage.ReadL( 0, bufferPtr, offset ); + + // Maximum length of buffer may be larger than spaceNeeded, + // thus bufferPtr may be larger as well. But to keep this + // simple, let's constraint to one message. + if ( bufferPtr.Length() > spaceNeeded ) + { + bufferPtr.SetLength( spaceNeeded ); + } + + if ( bufferPtr.Length() == spaceNeeded ) + { + TInt dummy; + TInt offsetDelta = + ExecuteCommandsFromDescriptorL( bufferPtr, dummy ); + + if ( offsetDelta == spaceNeeded ) + { + // Move offset forward. + offset += offsetDelta; + } + else + { + // There was supposed to be exactly one message + // in buffer, but now there is not. + failed = ETrue; + } + } + else + { + // spaceNeeded amount of bytes were required for + // next message, but somehow we did not get that many bytes. + failed = ETrue; + } + + CleanupStack::PopAndDestroy( buffer ); + } + else + { + // Do nothing - we can continue reading next part of buffer. + } + } + + return offset; + } + +TInt CAlfAppSrvSession::ExecuteCommandsFromDescriptorL( + const TDesC8& aSource, + TInt& aSpaceNeeded ) + { + TPtrC8 unreadArea( aSource ); + aSpaceNeeded = 0; + + while ( !aSpaceNeeded && ( unreadArea.Length() > 0 ) ) + { + TInt3 params(0,0,0); + TPckg paramsPckg( params ); + + // Check if there is complete parameter structure in unreadArea. + const TInt paddedParamsPckgMaxLength = + AlfPaddedLength( paramsPckg.MaxLength() ); + if ( paddedParamsPckgMaxLength > unreadArea.Length() ) + { + // Bail out from while loop. + aSpaceNeeded = paddedParamsPckgMaxLength; + } + else + { + // Copy to local parameters. + paramsPckg.Copy( unreadArea.Left( paramsPckg.MaxLength() ) ); + + // Read parameters + const TInt operation = params.iInt1; + const TInt subSessionHandle = params.iInt2; + const TInt inputBufferLength = params.iInt3; + + if ( inputBufferLength < 0 ) + { + // Input buffer length must not be negative. + __ALFLOGSTRING1( + "ExecuteCommandsFromDescriptorL corrupted: neg. length %d", + inputBufferLength ) + User::Leave( KErrCorrupt ); + } + + const TInt paddedInputBufferLength = + AlfPaddedLength( inputBufferLength ); + + if ( paddedParamsPckgMaxLength + paddedInputBufferLength < 0 ) + { + // There must NOT be overflow. + __ALFLOGSTRING1( + "ExecuteCommandsFromDescriptorL corrupted: length %d", + inputBufferLength ) + User::Leave( KErrCorrupt ); + } + + // Check if there is complete input buffer in unreadArea. + if ( paddedParamsPckgMaxLength + paddedInputBufferLength > + unreadArea.Length() ) + { + // Bail out from while loop. + aSpaceNeeded = paddedParamsPckgMaxLength + paddedInputBufferLength; + } + else + { + // Now we know that all data is available. + // It's time to execute command. + + // Skip over parameters (already read above) + unreadArea.Set( unreadArea.Mid( paddedParamsPckgMaxLength ) ); + + // Read input buffer + TPtrC8 inputbuffer = unreadArea.Left( inputBufferLength ); + unreadArea.Set( unreadArea.Mid( paddedInputBufferLength ) ); + + if ( !CAlfAppSrvSessionBase::HasSession( subSessionHandle ) ) + { + // Subsession handle must exist. + __ALFLOGSTRING1( + "ExecuteCommandsFromDescriptorL corrupted: handle %d", + subSessionHandle ) + User::Leave( KErrCorrupt ); + } + + // Execute command + CAlfSrvSubSessionBase& subsession = + CAlfAppSrvSessionBase::SubSession( subSessionHandle ); + MAlfExtension* subsessionEx = subsession.AsCommandHandler(); + + if ( !subsessionEx ) + { + // Instance implementing extension interface must exist. + __ALFLOGSTRING1( + "ExecuteCommandsFromDescriptorL corrupted: no ext, handle %d", + subSessionHandle ) + User::Leave( KErrCorrupt ); + } + + TBuf8<1> dummy; +#ifdef _ALF_LOGGING + TRAPD( err, + subsessionEx->HandleCmdL( operation, inputbuffer, dummy ) ); + if ( err != KErrNone ) + { + __ALFLOGSTRING3( + "ExecuteCommandsFromDescriptorL HandleCmdL fail %d (subsession %d, operation %d)", + err, subSessionHandle, operation ) + } + User::LeaveIfError( err ); +#else + subsessionEx->HandleCmdL( operation, inputbuffer, dummy ); +#endif // _ALF_LOGGING + } + } + } + + return aSource.Length() - unreadArea.Length(); + } + +inline TBool CAlfAppSrvSession::AllowExecuteUsingDynamicBuffer() const + { + return ( iExecutionFlags & EAlfExecuteUsingDynamicBuffer ); + } + +inline TBool CAlfAppSrvSession::AllowExecuteUsingCommonBuffer() const + { + return ( iExecutionFlags & EAlfExecuteUsingCommonBuffer ); + } + +inline CAlfSrvTextureManager& CAlfAppSrvSession::AlfTextureManager() + { + return AlfServer()->TextureManager(); + } + +void CAlfAppSrvSession::NotifyTextureInfo( const RMessage2& aMessage ) + { + if ( iTextureInfoEvent.IsNull() ) + { + iTextureInfoEvent = aMessage; + + // If there has been texture info updates, + // complete immediately. + DeliverTextureInfo(); + } + else + { + aMessage.Complete( KErrInUse ); + } + } + +inline TBool CAlfAppSrvSession::HasPendingTextureInfo() const + { + TBool found = EFalse; + + for ( TInt i = 0; i < iTextureInfo.Count(); i++ ) + { + const TAlfTextureInfo& info = iTextureInfo[ i ]; + if ( info.iFlags & TAlfTextureInfo::EAlfFlagTextureSizeChanged ) + { + found = ETrue; + break; + } + } + + return found; + } + +void CAlfAppSrvSession::DeliverTextureInfo() + { + if ( !(iFocused || iPartiallyVisible) || + iTextureInfoEvent.IsNull() || !HasPendingTextureInfo() ) + { + // Events are not delivered if + // - application does not have focus not partially visible + // - there is no pending notification + // - there is no texture info events to be delivered. + return; + } + + const TInt maxLength = iTextureInfoEvent.GetDesMaxLength( 0 ); + + TAlfTextureInfoEvent event; + TPckgC eventPckg( event ); + const TInt eventPckgLength = eventPckg.Length(); + + if ( maxLength <= eventPckgLength ) + { + // Max length is less than size of one event buffer. + // So bail out. + iTextureInfoEvent.Complete( KErrBadDescriptor ); + } + else + { + HBufC8* buffer = HBufC8::New( maxLength ); + if ( buffer ) + { + TPtr8 ptr = buffer->Des(); + + TInt priority = 0; + TInt foundTexturePos = 0; + + const TInt totalTextureInfo = iTextureInfo.Count(); + + while ( ( foundTexturePos != KErrNotFound ) && + ( maxLength - ptr.Length() >= eventPckgLength ) ) + { + // As long as there is space and another texture, + // append to buffer. + + // Find using current priority. + foundTexturePos = + FindNextTextureInfoForDelivery( priority, foundTexturePos ); + if ( ( foundTexturePos == KErrNotFound ) && !priority ) + { + // If not found and priority was high, try + // with lower priority. + priority++; + foundTexturePos = 0; + + foundTexturePos = FindNextTextureInfoForDelivery( + priority, foundTexturePos ); + } + + if ( foundTexturePos != KErrNotFound ) + { + TAlfTextureInfo& current = iTextureInfo[ foundTexturePos ]; + current.iFlags |= + TAlfTextureInfo::EAlfFlagTextureDelivered; + current.iFlags &= + ~TAlfTextureInfo::EAlfFlagTextureSizeChanged; + + // Append event data + event.iTextureId = current.iTextureId; + event.iTextureSize = current.iTextureSize; + ptr.Append( eventPckg ); + + foundTexturePos++; // this has been delivered, skip to next + } + } + + iTextureInfoEvent.Write( 0, ptr ); + iTextureInfoEvent.Complete( KErrNone ); + + delete buffer; + buffer = NULL; + } + else + { + // It is expected that maxLength is relatively small value. + // So it's better to try again a bit later. + } + } + } + +TInt CAlfAppSrvSession::FindNextTextureInfoForDelivery( + TBool aPriority, TInt aStartPos ) const + { + const TInt count = iTextureInfo.Count(); + TInt result = KErrNotFound; + + for ( TInt index = aStartPos; index < count; index++ ) + { + const TAlfTextureInfo& current = iTextureInfo[ index ]; + + if ( ( current.iFlags & TAlfTextureInfo::EAlfFlagTextureSizeChanged ) && + ( current.iDeliveryPriority == aPriority ) ) + { + result = index; + break; + } + } + + return result; + } + +TInt CAlfAppSrvSession::FindTextureInfoById( TInt aTextureId ) const + { + const TInt count = iTextureInfo.Count(); + + // Optimization to handle the case that this method is called + // several times using the same texture id. + if ( iPreviousTextureInfoIndex < count ) + { + if ( iTextureInfo[ iPreviousTextureInfoIndex ].iTextureId == + aTextureId ) + { + return iPreviousTextureInfoIndex; + } + } + + + TInt pos = KErrNotFound; + + for ( TInt i = 0; i < count; i++ ) + { + if ( aTextureId == iTextureInfo[ i ].iTextureId ) + { + pos = i; + iPreviousTextureInfoIndex = pos; + break; + } + } + + return pos; + } + +void CAlfAppSrvSession::RemoveTextureInfo( TInt aTextureId ) + { + const TInt pos = FindTextureInfoById( aTextureId ); + if ( pos != KErrNotFound ) + { + iTextureInfo.Remove( pos ); + } + } + +TInt CAlfAppSrvSession::GetTextureSize( + TInt aTextureId, + TSize& aTextureSize, + TBool& aHasBeenDelivered ) + { + TInt pos = FindTextureInfoById( aTextureId ); + if ( pos != KErrNotFound ) + { + // TAlfTextureInfo struct was found - pos >= 0 + aTextureSize = iTextureInfo[ pos ].iTextureSize; + aHasBeenDelivered = iTextureInfo[ pos ].iFlags & + TAlfTextureInfo::EAlfFlagTextureDelivered; + } + + return pos != KErrNotFound; + } + +void CAlfAppSrvSession::SetTextureSize( + TInt aTextureId, + const TSize& aTextureSize, + TInt aPriority ) + { + const TBool highPriority = ( aPriority < 0 ); + aPriority = Max( 0, aPriority ); + aPriority = Min( 1, aPriority ); + + TInt pos = FindTextureInfoById( aTextureId ); + if ( pos != KErrNotFound ) + { + // TAlfTextureInfo struct was found - pos >= 0 + TAlfTextureInfo& info = iTextureInfo[ pos ]; + info.iTextureSize = aTextureSize; + info.iFlags |= TAlfTextureInfo::EAlfFlagTextureSizeChanged; + info.iFlags &= ~TAlfTextureInfo::EAlfFlagTextureDelivered; + info.iDeliveryPriority = aPriority; + + if ( highPriority ) + { + // Move to the beginning. After this, above info + // struct is invalid. + TAlfTextureInfo tmp = iTextureInfo[ pos ]; + iTextureInfo.Remove( pos ); + iTextureInfo.Insert( tmp, 0 ); + } + } + else + { + // TAlfTextureInfo struct was not found - append a new one. + TAlfTextureInfo info; + info.iFlags = TAlfTextureInfo::EAlfFlagTextureSizeChanged; + info.iTextureId = aTextureId; + info.iTextureSize = aTextureSize; + info.iDeliveryPriority = aPriority; + + if ( highPriority ) + { + iTextureInfo.Insert( info, 0 ); + } + else + { + iTextureInfo.Append( info ); + } + } + } + +void CAlfAppSrvSession::RemoveTextureSize( TInt aTextureId ) + { + RemoveTextureInfo( aTextureId ); + } + +void CAlfAppSrvSession::TextureSizeChangesCompleted() + { + DeliverTextureInfo(); + } + +// --------------------------------------------------------------------------- +// PostQtCommandBufferL +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::PostQtCommandBufferL( const RMessage2& aMessage ) + { + TAlfQtCommandBufferParams params; + TPckg paramsPckg(params); + aMessage.Read(0,paramsPckg); + AlfAppUi()->PostQTCommandBufferL( params ); + } + +// --------------------------------------------------------------------------- +// ReportFrameRateBeginL +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::ReportFrameRateBegin( const RMessage2& aMessage ) + { + TInt32 id = aMessage.Int0(); + TFrameStamp* stamp = iFPSMeasurementArray.Find( id ); + // remove existing id, if any + if ( stamp ) + { + iFPSMeasurementArray.Remove(id); + } + iFPSMeasurementArray.Insert( id, TFrameStamp( CHuiStatic::FrameCount() )); + } + +// --------------------------------------------------------------------------- +// ReportFrameRateEndL +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::ReportFrameRateEnd( const RMessage2& aMessage ) + { + TInt32 id = aMessage.Int0(); + TFrameStamp FPSMeasurementEnd= TFrameStamp( CHuiStatic::FrameCount() ); + TBuf<40> logText; + + TFrameStamp* begin = iFPSMeasurementArray.Find( id ); + if ( begin ) + { + TReal32 fps = FPSMeasurementEnd.FrameRate( *begin ); + iFPSMeasurementArray.Remove(id); + + logText.Format( _L("%d\t%4.2f"), id, fps ); + RFileLogger::Write( KLogsDir, KAlfFPSLogFile, EFileLoggingModeAppend, logText ); + } + else + { + logText.Format( _L("Id %d not found"), id ); + RFileLogger::Write( KAlfFPSLogDir, KAlfFPSLogFile, EFileLoggingModeAppend, logText ); + } + RDebug::Print(_L("CAlfAppSrvSession::ReportFrameRateL - %S"), &logText ); + } + + +// --------------------------------------------------------------------------- +// EnvEnableLowMemoryState +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvEnableLowMemoryState(const RMessage2& aMessage) + { + TBool mode = aMessage.Int0(); + AlfAppUi()->NotifyLowMemory(mode); + } + +// --------------------------------------------------------------------------- +// EnvForceSwRendering +// --------------------------------------------------------------------------- +// +void CAlfAppSrvSession::EnvForceSwRendering(const RMessage2& aMessage) + { + TBool enabled = aMessage.Int0(); + TInt err = AlfAppUi()->ForceSwRendering( enabled ); + aMessage.Complete( err ); + } + +// End of file