diff -r 000000000000 -r bde4ae8d615e os/graphics/windowing/windowserver/nga/SERVER/openwfc/ANIMDLL.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/windowing/windowserver/nga/SERVER/openwfc/ANIMDLL.CPP Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,1232 @@ +// Copyright (c) 1995-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: +// Interface code for animated DLL's +// +// + +#include +#include "server.h" +#include "gc.h" +#include "rootwin.h" +#include "windowgroup.h" +#include "ANIM.H" +#include "wstop.h" +#include "EVENT.H" +#include "ScrDev.H" +#include "panics.h" +#include "wsfont.h" +#include "pointer.h" + +GLREF_D CDebugLogBase *wsDebugLog; + +static const TInt64 KFlashOnTime(700000); +static const TInt64 KFlashOffTime(300000); +static const TInt64 KOneSecond(1000000); +static const TInt64 KOneMinute(60 * KOneSecond); +static const TInt64 KOneDay(24 * 60 * 60 * KOneSecond); +static const TInt64 KOneHalfSecond(500000); + +enum {EWindowUpdate=0x0001}; + +// Anim DLL code // +CWsAnim::CWsAnim(CWsAnimDll *aDll) : iClient(aDll->WsOwner()), iAnimAddedInHandler(EFalse), iLastFrame(-1) + { + __DECLARE_NAME(_S("CWsAnim")); + iBitFlags.Set(EFlashOn); + } + +void CWsAnim::WindowClosing(CWsAnim *aWsAnim) + { + CWsAnim *anim=aWsAnim; + CWsAnim *next; + + while(anim) + { + next=anim->iNextWin; + CloseAnim(anim); + anim=next; + } + } + +void CWsAnim::CloseAnim(CWsAnim *aWsAnim) + { + if(aWsAnim) + { + TInt handle=aWsAnim->iAnimDll->AnimObjectHandle(aWsAnim); + if (handle<0) + delete aWsAnim; + else + aWsAnim->iAnimDll->Remove(handle); + } + } + +CWsAnim::~CWsAnim() + { + if (iWindow) // In case it never got linked + { + iWindow->SetupVisibleRegionTracking(EFalse); + MWsWindowTreeObserver* windowTreeObserver = iClient->Screen()->WindowTreeObserver(); + if (windowTreeObserver && (iBitFlags.IsSet(EWinAnimConstructed))) + { + windowTreeObserver->NodeReleased(*this); + iBitFlags.Clear(EWinAnimConstructed); + } + CWsAnim **pAnim; + for(pAnim= &iWindow->iAnimList;(*pAnim)!=NULL && (*pAnim)!=this;pAnim= &(*pAnim)->iNextWin) + {} + *pAnim=iNextWin; + + } + else if (iSprite) + { + // coverity[extend_simple_error] + iSprite->iAnim=NULL; + iSprite->SetHasAnimation(EFalse); + if(iSprite->Win()) + iSprite->Win()->SetupVisibleRegionTracking(EFalse); + } + // force the anim for the event handler list. + TWindowServerEvent::RemoveEventHandler(Anim()); + TWindowServerEvent::RemoveNotificationHandler(Anim()); + delete iAnim.iWindowAnim; + delete iAnimGc; + // coverity[extend_simple_error] + TWindowServerEvent::PotentialEventHandlerL(-1); //PotentialEventHandler cannot leave when passed a negative parameter. + } + +void CWsAnim::Connect(CWsClientWindow *aWindow) + { + //coverity[var_compare_op] + WS_ASSERT_DEBUG(aWindow,EWsPanicWindowNull); + if ((iSprite)) + Panic(); + + iWindow=aWindow; + iNextWin=aWindow->iAnimList; + aWindow->iAnimList=this; + iBitFlags.Assign(EAdvancedPointersEnabled, aWindow->AdvancedPointersEnabled()); + iWindow->SetupVisibleRegionTracking(ETrue); + } + +void CWsAnim::Connect(CWsSprite *aSprite) + { + WS_ASSERT_DEBUG(aSprite,EWsPanicNoSprite); + if (iWindow) + Panic(); + iSprite=aSprite; + iSprite->iAnim=this; + iSprite->SetHasAnimation(ETrue); + iBitFlags.Assign(EAdvancedPointersEnabled, aSprite->AdvancedPointersEnabled()); + if(iSprite->Win()) + { + iSprite->Win()->SetupVisibleRegionTracking(ETrue); + } + } + +LOCAL_C void HandleLeaveInCWsAnimConstructL(TAny* aAnim) + { + STATIC_CAST(CWsAnim*,aAnim)->SetMessage(NULL); + STATIC_CAST(CWsAnim*,aAnim)->UserDeactivateAnimGc(); + } + +void CWsAnim::ConstructL(CAnim *aAnim, TAny *aArgs, CWsAnimDll *aAnimDll, TBool aIsWindow) + { + TBool isFocused=(iSprite!=NULL); + if (!isFocused) + isFocused=CWsTop::FocusWindowGroup()==iWindow->WinGroup(); + iAnimDll=aAnimDll; + iAnimSync=ESyncNone; + if(!aAnim) + { + RDebug::Printf("CreateInstanceL did not create an anim instance."); + Panic(); + } + aAnim->iFunctions=this; + SetMessage(&iClient->ClientMessage()); + CleanupStack::PushL(TCleanupItem(HandleLeaveInCWsAnimConstructL,this)); + if (aIsWindow) + { + iAnim.iWindowAnim = static_cast(aAnim); + iAnimGc = new (ELeave) CWsAnimGc(*this); + iAnim.iWindowAnim->iWindowFunctions=this; + iAnim.iWindowAnim->iGc=iAnimGc; + iAnim.iWindowAnim->ConstructL(aArgs, isFocused); + iBitFlags.Set(EWinAnimConstructed); + WS_ASSERT_DEBUG(iClient->Screen(), EWsPanicNoScreen); + if (iClient->Screen()) + { + MWsWindowTreeObserver* windowTreeObserver = iClient->Screen()->WindowTreeObserver(); + if (windowTreeObserver) + { + windowTreeObserver->NodeCreated(*this, ParentNode()); + const TRect rect = BestRect(); + windowTreeObserver->NodeExtentChanged(*this, rect); + windowTreeObserver->NodeActivated(*this); //window-anim inherits activate status from iWindow + } + } + } + else + { + iAnim.iSpriteAnim = static_cast(aAnim); + iAnim.iSpriteAnim->iSpriteFunctions=this; + iAnim.iSpriteAnim->ConstructL(aArgs); + } + CleanupStack::PopAndDestroy(this); // doesn't really destroy "this" - it actually calls HandleLeaveInCWsAnimConstructL + } + +/** +This function should only be called in the context of a redraw (i.e. CScreenRedraw::OnAnimation) +@panic EWsPanicAnim will be raised in debug build if this function is called in the wrong context. +*/ +void CWsAnim::RedrawWindowAnimL(const TTime& aTimeNow, MWsGraphicsContext* aGc, const TRegion* aRegion) + { + WS_ASSERT_DEBUG(iWindow, EWsPanicAnimHasNoWindow); + WS_ASSERT_DEBUG(iWindow->Screen(), EWsPanicNoScreen); + WS_ASSERT_DEBUG(iWindow->Screen()->IsAnimating(), EWsPanicAnim); + iBitFlags.Set(EInRedraw); + + TInt frame; + TInt64 adjustedStart; + // Don't call AnimateL() on CFreeTimerWindowAnim animations + if(iAnimSync!=ESyncNone || iInterval!=0) + { + AnimateL(aTimeNow, frame, adjustedStart); + } + RedrawWindowAnimL(aGc, aRegion); + ReSchedule(aTimeNow, frame, adjustedStart); + + iBitFlags.Clear(EInRedraw); + } + +/** +This function should only be called in the context of a redraw (i.e. CScreenRedraw::OnAnimation) +@panic EWsPanicAnim will be raised in debug build if this function is called in the wrong context. +*/ +void CWsAnim::AnimateSpriteAnimL(const TTime& aTimeNow) + { + WS_ASSERT_DEBUG(iSprite, EWsPanicNoSprite); + WS_ASSERT_DEBUG(iSprite->Screen(), EWsPanicNoScreen); + WS_ASSERT_DEBUG(iSprite->Screen()->IsAnimating(), EWsPanicAnim); + iBitFlags.Set(EInRedraw); + + TInt frame; + TInt64 adjustedStart; + AnimateL(aTimeNow, frame, adjustedStart); + ReSchedule(aTimeNow, frame, adjustedStart); + + iBitFlags.Clear(EInRedraw); + } + +void CWsAnim::AnimateL(const TTime& aTimeNow, TInt& aFrame, TInt64& aAdjustedStart) + { + // Work out which frame we are in: + if (iLastFrame < 0) + iStartTime = aTimeNow; + TInt64 elapsed = aTimeNow.Int64() - iStartTime.Int64(); + aAdjustedStart = iStartTime.Int64(); + aFrame = 0; + switch (iAnimSync) + { + case ESyncNone: + if (iInterval > 0) + { + aFrame = elapsed / iInterval.Int64(); + } + else + { + aFrame = -1; //This would be a CFreeTimerWindowAnim + } + break; + case ESyncFlash: + { + TInt64 fraction = elapsed % (KFlashOnTime + KFlashOffTime); + aFrame = (elapsed - fraction) / (KFlashOnTime + KFlashOffTime) * 2; + if (fraction > KFlashOnTime) + { + aFrame += 1; + iBitFlags.Clear(EFlashOn); + } + else + { + iBitFlags.Set(EFlashOn); + } + } + break; + case ESyncSecond: + aAdjustedStart = iStartTime.Int64() - (iStartTime.Int64() % KOneSecond); + elapsed = aTimeNow.Int64() - aAdjustedStart; + aFrame = elapsed / KOneSecond; + break; + case ESyncMinute: + aAdjustedStart = iStartTime.Int64() - (iStartTime.Int64() % KOneMinute); + elapsed = aTimeNow.Int64() - aAdjustedStart; + aFrame = elapsed / KOneMinute; + break; + case ESyncDay: + aAdjustedStart = iStartTime.Int64() - (iStartTime.Int64() % KOneDay); + elapsed = aTimeNow.Int64() - aAdjustedStart; + aFrame = elapsed / KOneDay; + break; + } + + // If the frame has changed, animate: + if (aFrame != iLastFrame && aFrame != -1) + { + if (aFrame == iLastFrame + 1 && iLastFrame != -1) + { + Animate(NULL); //This can leave + } + else + { + TDateTime dt = aTimeNow.DateTime(); + Animate(&dt); + } + iLastFrame = aFrame; + } + } + +void CWsAnim::RedrawWindowAnimL(MWsGraphicsContext * aGc, const TRegion *aRegion) + { + WS_ASSERT_DEBUG(iWindow,EWsPanicAnimHasNoWindow); + + // We don't attempt to make use of iRect because it often isn't set up by the client code. + TWindowInfo::TRegionPair regionPair; + regionPair.iRegion1 = aRegion; + regionPair.iRegion2 = NULL; + iRedrawRegionPair = ®ionPair; + + if(iWindow && iAnim.iWindowAnim) + { + // Regardless of whether we animated or not, redraw: + iAnimGc->Activate(aRegion, aGc); + iAnim.iWindowAnim->Redraw(); //This can leave + iAnimGc->Deactivate(); + } + + iRedrawRegionPair = NULL; + } + +void CWsAnim::ReSchedule(const TTime& aTimeNow, const TInt& aFrame, const TInt64& aAdjustedStart) + { + // Schedule ourselves again (we usually only have to do this when we animate, + // but it is possible for our scheduled rectangle to get lost in a redraw): + TInt64 timeToNextFrame = 0; + switch (iAnimSync) + { + case ESyncNone: + if (iInterval > 0) + { + timeToNextFrame = iStartTime.Int64() + iInterval.Int64() * (aFrame + 1) - aTimeNow.Int64(); + } + break; + case ESyncFlash: + if (iBitFlags.IsSet(EFlashOn)) + { + timeToNextFrame = iStartTime.Int64() + (KFlashOnTime + KFlashOffTime) * aFrame / 2 + KFlashOnTime - aTimeNow.Int64(); + } + else + { + timeToNextFrame = iStartTime.Int64() + (KFlashOnTime + KFlashOffTime) * (aFrame + 1 ) / 2 - aTimeNow.Int64(); + } + break; + case ESyncSecond: + timeToNextFrame = aAdjustedStart + KOneSecond * (aFrame + 1) - aTimeNow.Int64(); + break; + case ESyncMinute: + timeToNextFrame = aAdjustedStart + KOneMinute * (aFrame + 1) - aTimeNow.Int64(); + break; + case ESyncDay: + timeToNextFrame = aAdjustedStart + KOneDay * (aFrame + 1) - aTimeNow.Int64(); + break; + } + + if (iAnimSync != ESyncNone || iInterval > 0) + { + ScheduleSelf(timeToNextFrame); + } + + } + +/** +Mark the animation area as invalid so it gets redrawn later. +*/ +void CWsAnim::ScheduleSelf(const TTimeIntervalMicroSeconds& aFrom) + { + ASSERT( (iWindow && iAnim.iWindowAnim) || (iSprite && iAnim.iSpriteAnim) ); + + if(iWindow && iAnim.iWindowAnim) + { + WS_ASSERT_DEBUG(iWindow->Screen(), EWsPanicNoScreen); + const TRect rect = BestRect(); + iWindow->Screen()->ScheduleAnimation(EWindowAnim, rect, aFrom, 0, 0, iWindow); + } + else if(iSprite && iAnim.iSpriteAnim) + { + WS_ASSERT_DEBUG(iSprite->Screen(), EWsPanicNoScreen); + const TRect rect = iSprite->Rect(); + if(iSprite->Win()) + iSprite->Screen()->ScheduleAnimation(ESpriteAnim, rect, aFrom, 0, 0, iSprite->Win()); + else + iSprite->Screen()->ScheduleAnimation(EFloatingSpriteAnim, rect, aFrom, 0, 0, NULL); + } + } + +void CWsAnim::UserDeactivateAnimGc() + { + if (iAnimGc) // For sprite anims iAnimGc is NULL + { + //If we have been receiving draw commands outside the context of + //CScreenRedraw::OnAnimation, then we need to schedule a redraw. + if (iAnimGc->IsActive() && iBitFlags.IsClear(EInRedraw)) + { + ScheduleSelf(0); + } + iAnimGc->UserDeactivate(); + } + } + +void CWsAnim::FocusChanged(TBool aNewFocusState) + { + WS_ASSERT_DEBUG(iWindow && iAnimGc && iAnim.iWindowAnim,EWsPanicAnim); + iAnim.iWindowAnim->FocusChanged(aNewFocusState); + UserDeactivateAnimGc(); + } + +void CWsAnim::Animate(TDateTime *aDateTime) + { + WS_ASSERT_DEBUG(Anim(),EWsPanicAnim); + Anim()->Animate(aDateTime); + UserDeactivateAnimGc(); + } + +// Callback functions // + +void CWsAnim::ActivateGc() + { + if (!iWindow) + Panic(); + + // Window animation drawing commands need to go through the render stage pipeline. This means + // that drawing commands issued outside animation redraws (for instance, during Animate() or + // when the animation receives a command) will mark the animation area as invalid, but the + // commands themselves will be ignored as drawing will only happen during the next WSERV redraw + // cycle (CWindowAnim::Redraw). + + // In this new situation MAnimWindowFunctions::ActivateGc doesn't need to activate the graphics + // context (drawing commands issued outside CWindowAnim::Redraw are ignored), but to avoid some + // behavior breaks (for instance, panic situations) we mark the GC as "activated by the user". + iAnimGc->UserActivate(); + } + +void CWsAnim::DeactivateGc() + { + if (!iWindow) + Panic(); + + // Window animation drawing commands need to go through the render stage pipeline. This means + // that drawing commands issued outside animation redraws (for instance, during Animate() or + // when the animation receives a command) will mark the animation area as invalid, but the + // commands themselves will be ignored as drawing will only happen during the next WSERV redraw + // cycle (CWindowAnim::Redraw). + + // In this new situation MAnimFreeTimerWindowFunctions::DeactivateGc just marks the animation + // area as invalid so it gets redrawn later. + + UserDeactivateAnimGc(); + } + +/* +Because lots of animations don't set a rectangle, or set an empty one, we need +to make a best guess at what to use rather than assuming anything. +*/ +TRect CWsAnim::BestRect() const + { + WS_ASSERT_DEBUG(iWindow,EWsPanicAnimHasNoWindow); + TRect rect; + if (iRect.IsEmpty()) + { + rect = iWindow->AbsRect(); + } + else + { + rect = iRect; + rect.Move(iWindow->Origin()); + rect.Intersection(iWindow->AbsRect()); + } + return rect; + } + +void CWsAnim::Invalidate(const TRect &aRect) + { + if (!iWindow) + { + if (iSprite) + { + iSprite->RootWindow()->InvalidateWholeScreen(); + } + return; + } + iWindow->Redraw()->ClientExposing(); + TRect rect(aRect); + rect.Move(iWindow->Origin()); + + CWsTop::TriggerRedraws(iWindow->RootWindow()); + } + +void CWsAnim::Update() + { + if (!iWindow) + Panic(); + } + +void CWsAnim::Parameters(TWindowInfo &aData) + { + if (!iWindow) + Panic(); + aData.iScreenPos=iWindow->FullRect(); + aData.iMode=iWindow->DisplayMode(); + aData.iRegionPair=iRedrawRegionPair; + } + +void CWsAnim::VisibleRegion(TRegion& aRegion) + { + if(iWindow) + { + aRegion.Copy(iWindow->VisibleRegion()); + } + } + +void CWsAnim::SetSync(TAnimSync aSyncMode) + { + if (iAnimSync != aSyncMode) + { + iAnimSync=aSyncMode; + iLastFrame = -1; + + if (iAnimSync != ESyncNone) + ScheduleSelf(0); + + if (iAnimSync == ESyncFlash) + iBitFlags.Set(EFlashOn); + } + } + +void CWsAnim::SetInterval(TInt aInterval) + { + if (iAnimSync!=ESyncNone) + Panic(); + iLastFrame = -1; + if (aInterval < 0) + aInterval = 0; + // convert intervals to milliseconds (there are two intervals per second) + iInterval = aInterval*KOneHalfSecond; + if (iInterval > 0) + { + ScheduleSelf(iInterval); + } + + } + +void CWsAnim::SetNextInterval(TInt aInterval) + { + if (iAnimSync!=ESyncNone) + Panic(); + aInterval = (aInterval <= 0) ? 1 : aInterval; + ScheduleSelf(aInterval*KOneHalfSecond); + } + +void CWsAnim::SetRect(const TRect &aRect) + { + if (!iWindow) + Panic(); + + if (iRect != aRect) + { + iRect=aRect; + iWindow->UpdateAnimArea(); // backed up windows only + + MWsWindowTreeObserver* windowTreeObserver = iClient->Screen()->WindowTreeObserver(); + if (windowTreeObserver && iBitFlags.IsSet(EWinAnimConstructed)) + { + const TRect rect = BestRect(); + windowTreeObserver->NodeExtentChanged(*this, rect); + } + } + } + +const TRect& CWsAnim::Rect() const + { + return(iRect); + } + +TDateTime CWsAnim::SystemTime() const + { + TDateTime dt=iWindow->Screen()->Now().DateTime(); + TInt hour=dt.Hour(); + TInt minute=dt.Minute(); + TInt second=dt.Second(); + TInt microSecond=dt.MicroSecond(); + switch(iAnimSync) + { + case ESyncDay: + hour=0; + minute=0; + /*Fall through*/ + case ESyncMinute: + second=0; + /*Fall through*/ + case ESyncNone: + case ESyncFlash: + case ESyncSecond: + microSecond=0; + break; + } + TDateTime dateTime; + dateTime.Set(dt.Year(),dt.Month(),dt.Day(),hour,minute,second,microSecond); + return(dateTime); + } + +TBool CWsAnim::FlashStateOn() const + { + return(iBitFlags.IsSet(EFlashOn)); + } + +const RThread &CWsAnim::Client() + { + return(iClient->Client()); + } + +void CWsAnim::ReplyBuf(const TDesC8 &aDes) + { + CWsClient::ReplyBuf(aDes); + } + +void CWsAnim::ReplyBuf(const TDesC16 &aDes) + { + CWsClient::ReplyBuf(aDes); + } + +void CWsAnim::SessionPanic() const + { + iClient->SessionPanic(EWservPanicAnimDll); + } + +void CWsAnim::Panic() const + { + iClient->PPanic(EWservPanicAnimDll); + } + +void CWsAnim::Panic(TClientPanic aPanic) const + { + iClient->PPanic(aPanic); + } + +void CWsAnim::SendState(MWsWindowTreeObserver& aWindowTreeObserver) const + { + if(iNextWin) + iNextWin->SendState(aWindowTreeObserver); + + if(iBitFlags.IsSet(EWinAnimConstructed)) + { + aWindowTreeObserver.NodeCreated(*this, ParentNode()); + const TRect rect = BestRect(); + aWindowTreeObserver.NodeExtentChanged(*this, rect); + aWindowTreeObserver.NodeActivated(*this); //window-anim inherits activate status from iWindow + } + } + +const CFbsScreenDevice *CWsAnim::ScreenDevice() + { + return NULL; // Deprecated by PREQ 2095 + } + +CFbsFont *CWsAnim::DuplicateFontL(TInt aHandle) + { + CFbsFont *font=NULL; + TInt err; + font=CAnimFbsFont::NewL(aHandle,err); + if (err!=KErrNone) + { + WS_ASSERT_DEBUG(font==NULL,EWsPanicFailedToInitialise); + if (err==KErrNoMemory) + User::Leave(err); + iClient->PPanic(EWservPanicFont); + } + return(font); + } + +void CWsAnim::CloseFont(CFbsFont *aFont) + { + if (aFont) + ((CAnimFbsFont *)aFont)->Close(); + } + +CFbsBitmap *CWsAnim::DuplicateBitmapL(TInt aHandle) + { + CFbsBitmap *bitmap=new(ELeave) CFbsBitmap(); + TInt err=bitmap->Duplicate(aHandle); + if (err!=KErrNone) + { + delete bitmap; + if (err==KErrNoMemory) + User::Leave(err); + iClient->PPanic(EWservPanicBitmap); + } + return(bitmap); + } + +TSize CWsAnim::WindowSize() const + { + if (!iWindow) + Panic(); + return(iWindow->Size()); + } + +TBool CWsAnim::IsHidden() + { + if (!iWindow) + Panic(); + + return iWindow->IsHidden(); + } + +void CWsAnim::SetVisible(TBool aState) + { + //The (iAnimGc->IsActive() && aState) part of the below if statement is in place to accomodate bc with + //the original wserv. + //We panic when we call SetVisible(ETrue) and the CWsAnimGc has been activated because the origininal wserv did. + //We don't panic when we call SetVisible(EFalse) and the CWsAnimGc is activated because the original wserv didn't. + + if( !iWindow || (iAnimGc->IsActive() && aState) ) + { + Panic(); + } + + iWindow->SetVisible(aState); + + STACK_REGION region; + VisibleRegion(region); + TRect rect = region.BoundingRect(); + region.Close(); + if(!rect.IsEmpty()) + iWindow->Screen()->ScheduleAnimation(EWindowAnim, rect,0,0,0, iWindow); + } + +MAnimGeneralFunctions::TAnimSync CWsAnim::Sync() const + { + return(iAnimSync); + } + +void CWsAnim::GetRawEvents(TBool aGetEvents) const + { + if (aGetEvents) + { + if (!iAnimAddedInHandler) + { + TWindowServerEvent::AddEventHandler(Anim(), iBitFlags.IsSet(EAdvancedPointersEnabled)); + iAnimAddedInHandler = ETrue; + } + } + else + { + if (iAnimAddedInHandler) + { + TWindowServerEvent::RemoveEventHandler(Anim()); + iAnimAddedInHandler = EFalse; + } + } + } + +void CWsAnim::PostRawEvent(const TRawEvent &aRawEvent) const + { + // Cannot remove const from aRawEvent parameter type for compatibility reasons. + if (TWsPointer::PreProcessClientEvent(const_cast(aRawEvent), iBitFlags.IsSet(EAdvancedPointersEnabled))) + { + TWindowServerEvent::ProcessRawEvent(aRawEvent); + } + } + +void CWsAnim::PostKeyEvent(const TKeyEvent &aRawEvent) const + { + TWindowServerEvent::ProcessKeyEvent(aRawEvent,0); + } + +/** +Generate repeated key events. +*/ +void CWsAnim::PostKeyEvent(const TKeyEvent& aRawEvent, TInt aRepeats) const + { + TWindowServerEvent::ProcessKeyEvent(aRawEvent,aRepeats); + } + +TInt CWsAnim::RegisterForNotifications(TUint32 aNotifications) + { + if (aNotifications) + { + return TWindowServerEvent::AddNotificationHandler(Anim(),aNotifications); + } + else + { + TWindowServerEvent::RemoveNotificationHandler(Anim()); + return KErrNone; + } + } + +const RMessagePtr2* CWsAnim::Message() + { + return iMessage; + } + +void CWsAnim::SetMessage(const RMessagePtr2* aMessage) + { + iMessage=aMessage; + } + +TInt CWsAnim::CommandReply(TInt aOpcode, TAny* aArgs) + { + SetMessage(&iClient->ClientMessage()); // ClientMessage returns a reference, so taking the address of it is okay (it it returned it by value, then taking the address would be taking the address of a temporary which would be dodgey) + TInt returnValue=0; + TRAP(returnValue,returnValue=Anim()->CommandReplyL(aOpcode, aArgs)); + SetMessage(NULL); + return returnValue; + } + +TSpriteMember *CWsAnim::GetSpriteMember(TInt aMember) const + { + if (!iSprite) + Panic(); + return REINTERPRET_CAST(TSpriteMember*,&(*iSprite->iMembers)[aMember]->iBitmap); //The 2 classes involved in the cast have exactly the same data members in the same order + } + +void CWsAnim::UpdateMember(TInt aMember,const TRect& aRect,TBool aFullUpdate) + { + if (!iSprite) + Panic(); + iSprite->Update(aMember,aRect,aFullUpdate); + } + +void CWsAnim::Activate(TBool aActive) + { + if (!iSprite) + Panic(); + if (!aActive) + iSprite->Deactivate(); + else + { + if (iSprite->IsActive()) + Panic(); + iSprite->Activate(); + } + } + +void CWsAnim::SizeChangedL() + { + if (!iSprite) + Panic(); + iSprite->CWsSpriteBase::CompleteL(); + } + +void CWsAnim::SetPosition(const TPoint &aPos) + { + iSprite->SetPos(aPos); + } + +TAny* CWsAnim::ExtendedInterface(TInt aInterface) + { + switch(aInterface) + { + case ENumberOfExtendedInterfaces: + return reinterpret_cast(EInterfaceCount-1); + case EWindowExtensionInterface: + return static_cast(this); + case EEventExtentionInterface: + return static_cast(this); + default: + return NULL; + } + } + +TInt CWsAnim::Screens() const + { + return CWsTop::NumberOfScreens(); + } + +TInt CWsAnim::FocusScreens() const + { + return CWsTop::CurrentFocusScreen()->ScreenNumber(); + } + +void CWsAnim::SetFocusScreen(TInt aScreenNo) + { + if (aScreenNo=0) + { + CWsTop::SetCurrentFocusScreen(aScreenNo); + } + else + { + Panic(); + } + } + +TInt CWsAnim::WindowGroups(TInt aScreen) const + { + return(CWsWindowGroup::NumWindowGroupsOnScreen(CWsTop::Screen(aScreen)->RootWindow()->Child(),ETrue,0)); + } + +TBool CWsAnim::WindowGroupInfo(TWindowGroupInfo& aInfo,TInt aScreen,TInt aFullOrdinalPosition) const + { + CWsWindowGroup* group=CWsTop::Screen(aScreen)->RootWindow()->WindowGroup(aFullOrdinalPosition); + if (!group) + return EFalse; + aInfo.iId=group->Identifier(); + if (group->ReceivesFocus() && group->ScreenDeviceValid()) + aInfo.iFlags=TWindowGroupInfo::EIsFocusable; + else + aInfo.iFlags=0; + aInfo.iOrdinalPriority=group->OrdinalPriority(); + HBufC* groupName=group->GroupName(); + aInfo.iNameLength=groupName?group->GroupName()->Length():0; + if (!group->IsChained(aInfo.iParentId)) + aInfo.iParentId=-1; + return ETrue; + } + +TInt CWsAnim::WindowGroupName(TPtrC& aWindowName,TInt aScreen,TInt aFullOrdinalPosition) const + { + CWsWindowGroup* group=CWsTop::Screen(aScreen)->RootWindow()->WindowGroup(aFullOrdinalPosition); + if (!group) + return EFalse; + HBufC* name=group->GroupName(); + if (name) + aWindowName.Set(*name); + else + aWindowName.Set(NULL,0); + return ETrue; + } + +TInt CWsAnim::SetOrdinalPosition(TInt aWindowGroupId,TInt aPos,TInt aOrdinalPriority) + { + CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifier(aWindowGroupId); + if (group) + { + group->SetOrdinalPriority(aPos,aOrdinalPriority); + return KErrNone; + } + return KErrNotFound; + } + +void CWsAnim::WindowConfig(TWindowConfig& aWindowConfig) const + { + aWindowConfig.iFlags = 0x00; + if (iWindow->IsTranslucent()) + { + aWindowConfig.iFlags |= TWindowConfig::ETransparencyEnabled; + if (iWindow->HasAlpha()) + { + aWindowConfig.iFlags |= TWindowConfig::EAlphaBlendedTransparency; + } + } + } + +TBool CWsAnim::SpriteCanBeSeen() const + { + if(!iSprite) + Panic(); + return iSprite->CanBeSeen(); + } + +/** @see MWsWindowTreeNode */ +MWsWindowTreeNode::TType CWsAnim::NodeType() const + { + return (iSprite) ? iSprite->NodeType() : MWsWindowTreeNode::EWinTreeNodeAnim; + } + +/** @see MWsWindowTreeNode */ +const MWsWindow* CWsAnim::Window() const + { + return NULL; + } + +/** @see MWsWindowTreeNode */ +const MWsSprite* CWsAnim::Sprite() const + { + return iSprite; + } + +/** @see MWsWindowTreeNode */ +const MWsStandardTextCursor* CWsAnim::StandardTextCursor() const + { + return NULL; + } + +/** @see MWsWindowTreeNode */ +const MWsWindowGroup* CWsAnim::WindowGroup() const + { + if (iSprite) + return iSprite->WindowGroup(); + else if (iWindow) + return iWindow->WindowGroup(); + Panic(); + return NULL; + } + +/** @see MWsWindowTreeNode */ +const MWsWindowTreeNode* CWsAnim::ParentNode() const + { + if (iSprite) + return iSprite->ParentNode(); + else if (iWindow) + return iWindow; //A window-anim is considered to be a child of the window + Panic(); + return NULL; + } + +// + +CObjectConIx* CWsAnimDll::AnimObjectConIx=NULL; + +void CWsAnimDll::InitStaticsL() + { + CWsAnimDll::AnimObjectConIx=CObjectConIx::NewL(); + } + +void CWsAnimDll::DeleteStatics() + { + delete CWsAnimDll::AnimObjectConIx; + } + +CWsAnimDll::CWsAnimDll(CWsClient *aOwner) : CWsObject(aOwner,WS_HANDLE_ANIM_DLL) + { + __DECLARE_NAME(_S("CWsAnimDll")); + } + +CWsAnimDll::~CWsAnimDll() + { + delete iInstanceIndex; + AnimObjectConIx->Remove(iInstanceCon); + delete iAnimDll; + iAnimLib.Close(); + } + +TInt CWsAnimDll::doCreateInstanceL(CWsAnim *aInstance, TInt aType, TAny *aArgs, TBool aIsWindow) + { + iInstanceCon->AddL(aInstance); + aInstance->ConstructL(iAnimDll->CreateInstanceL(aType),aArgs,this,aIsWindow); + return(iInstanceIndex->AddL(aInstance)); + } + +TInt CWsAnimDll::CreateInstanceL(TUint32 aHandle, TInt aType, TAny *aArgs, TBool aIsWindow) + { + TWindowServerEvent::PotentialEventHandlerL(1); + CWsAnim *instance=new(ELeave) CWsAnim(this); + CleanupClosePushL(*instance); + if (aIsWindow) + { + CWsClientWindow *win; + iWsOwner->HandleToClientWindow(aHandle,&win); + instance->Connect(win); + } + else + { + CWsObject *sprite=iWsOwner->HandleToObj(aHandle, WS_HANDLE_SPRITE); + if (!sprite) + OwnerPanic(EWservPanicSprite); + instance->Connect(STATIC_CAST(CWsSprite*,sprite)); + } + TInt handle=doCreateInstanceL(instance, aType, aArgs, aIsWindow); + CleanupStack::Pop(instance); + return(handle); + } + +void CWsAnimDll::LoadL(const TDesC &aDllName) + { + NewObjL(); + TFileName name(aDllName); + User::LeaveIfError(iAnimLib.Load(name)); + if (wsDebugLog) + { + TBuf<256> buf; + _LIT(KWSERVLoadedAnimDll,"Loaded Anim DLL: "); + buf.Append(KWSERVLoadedAnimDll); + buf.Append(iAnimLib.FileName()); + wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,buf); + } + TUidType uid=iAnimLib.Type(); + if (uid[1]!=KWservAnimDllUid) + User::Leave(KErrNotSupported); + CreateCAnimDll f; + f=(CreateCAnimDll)User::LeaveIfNull((TAny *)iAnimLib.Lookup(1)); + iAnimDll=(*f)(); + iInstanceIndex=CObjectIx::NewL(); + iInstanceCon=AnimObjectConIx->CreateL(); + } + +void CWsAnimDll::Remove(TInt aHandle) + { + iInstanceIndex->Remove(aHandle); + } + +void CWsAnimDll::CommandL(TInt aOpcode, const TAny *aCmdData) + { + TWsAnimDllCmdUnion pData; + + pData.any=aCmdData; + switch(aOpcode) + { + case EWsAnimDllOpFree: + delete this; + break; + case EWsAnimDllOpCreateInstance: + case EWsAnimDllOpCreateInstanceSprite: + SetReply(CreateInstanceL(*pData.UInt,*((TInt *)(pData.UInt+1)),(TAny *)(pData.UInt+2) + ,aOpcode==EWsAnimDllOpCreateInstance)); + break; + case EWsAnimDllOpCommandReply: + case EWsAnimDllOpCommand: + case EWsAnimDllOpDestroyInstance: + { + CWsAnim *anim=(CWsAnim *)iInstanceIndex->At(*pData.UInt); + TInt ret; + //Deleting a non existant Anim is allowed as the Anim will be destroyed + //when the window it is on (or a parent of) it destroyed + if (anim==NULL && aOpcode!=EWsAnimDllOpDestroyInstance) + OwnerPanic(EWservPanicAnim); + switch(aOpcode) + { + case EWsAnimDllOpCommandReply: + { + TInt reply=KErrNone; + TRAP(ret,reply=anim->CommandReply(*((TInt *)(pData.UInt+1)),(TAny *)(pData.UInt+2))); + anim->UserDeactivateAnimGc(); + if (ret!=KErrNone) + User::Leave(ret); + SetReply(reply); + } + break; + case EWsAnimDllOpCommand: + TRAP(ret,anim->Anim()->Command(*((TInt *)(pData.UInt+1)),(TAny *)(pData.UInt+2))); + if (ret!=KErrNone && ret!=CWsClient::EPanicLeave) + OwnerPanic(EWservPanicAnimLeave); + anim->UserDeactivateAnimGc(); + break; + case EWsAnimDllOpDestroyInstance: + if (anim) // Added to go with changes described above + Remove(*pData.UInt); + break; + default: + break; + } + } + break; + default: + OwnerPanic(EWservPanicOpcode); + } + } + +CAnimFbsFont::~CAnimFbsFont() + {} + +CAnimFbsFont::CAnimFbsFont() + {} + +CAnimFbsFont* CAnimFbsFont::NewL(TInt aHandle,TInt& aError) + { + CAnimFbsFont *font=new(ELeave) CAnimFbsFont(); + font->iAccessCount=1; + aError=font->Duplicate(aHandle); + if (aError!=KErrNone) + { + delete font; + font=NULL; + } + return(font); + } + +void CAnimFbsFont::Open() + { + iAccessCount++; + } + +void CAnimFbsFont::Close() + { + if (--iAccessCount==0) + delete this; + } + + +/*MAnimGeneralFunctions*/ +void MAnimGeneralFunctions::Reserved1() const + {} + +void MAnimGeneralFunctions::Reserved2() const + {} + +void MAnimGeneralFunctions::Reserved3() const + {} + + +/*MAnimGeneralFunctionsExtension*/ + +void MAnimGeneralFunctionsWindowExtension::Reserved1() const + {} + +void MAnimGeneralFunctionsWindowExtension::Reserved2() const + {} + +void MAnimGeneralFunctionsWindowExtension::Reserved3() const + {} + + +/*MAnimWindowFunctions*/ + +void MAnimWindowFunctions::Reserved() const + {} + +void MAnimWindowFunctions::Reserved1() const + {} + +void MAnimWindowFunctions::Reserved2() const + {} + +void MAnimWindowFunctions::Reserved3() const + {} + + +/*MAnimFreeTimerWindowFunctions*/ + +void MAnimFreeTimerWindowFunctions::Reserved3() const + {} + + +/*MAnimSpriteFunctions*/ + +void MAnimSpriteFunctions::Reserved() const + {} + +void MAnimSpriteFunctions::Reserved2() const + {} + +void MAnimSpriteFunctions::Reserved3() const + {} + +void MAnimSpriteFunctions::Reserved4() const + {} + +/*MAnimGeneralFunctionsEventExtension*/ + +void MAnimGeneralFunctionsEventExtension::Reserved1() const + {} + +void MAnimGeneralFunctionsEventExtension::Reserved2() const + {}