diff -r 000000000000 -r bde4ae8d615e os/graphics/windowing/windowserver/nga/SERVER/openwfc/wnredraw.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/windowing/windowserver/nga/SERVER/openwfc/wnredraw.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,964 @@ +// Copyright (c) 1995-2010 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: +// Window redraw code, three sorts of redrawing are supported +// Sending a redraw message to the client (see redrawmsgwindow.cpp) +// Drawing from backup bitmap +// Simply clearing the window +// +// + +#include "wnredraw.h" +#include "server.h" +#include "playbackgc.h" +#include "wstop.h" +#include "ANIM.H" +#include "EVQUEUE.H" +#include +#include +#include "panics.h" +#include "inifile.h" +#include "rootwin.h" +#include "EVENT.H" +#include "wstypes.h" +#include +#include +#include +#include "windowelementset.h" + +struct TFadingParams + { + TUint8 blackMap; + TUint8 whiteMap; + }; + +CWsWindowRedraw::CWsWindowRedraw(CWsWindow *aWin) : iWsWin(aWin) + { + } + +CWsWindowRedraw::~CWsWindowRedraw() + { + if (iWsWin->WsOwner()) + { + iWsWin->WsOwner()->RedrawQueue()->RemoveInvalid(this); + } + if (HasElement()) + { + iWsWin->Screen()->WindowElements().ReleaseAllElements(*CliWin()); + } + } + +void CWsWindowRedraw::ConstructL() + { + } + +const TRegion& CWsWindowRedraw::InvalidArea() const + { + return(nullRegion); + } + +const TRegion &CWsWindowRedraw::BaseDrawRegion() const + { + return(iWsWin->VisibleRegion()); + } + +void CWsWindowRedraw::ClipInvalidRegion(const TRect &) + { + } + +void CWsWindowRedraw::Resize(const TSize &, const TSize &) + { + } + +void CWsWindowRedraw::SetReply(TInt aReply) + { + iWsWin->WsOwner()->SetReply(aReply); + } + +void CWsWindowRedraw::OwnerPanic(TClientPanic aPanic) + { + iWsWin->OwnerPanic(aPanic); + } + +CWsBackedUpWindow *CWsWindowRedraw::Backup() const + { + return(NULL); + } + +void CWsWindowRedraw::Scroll(const TRect &, const TPoint &,const TRect &) + { + } + +void CWsWindowRedraw::UpdateAnimArea() + { + } + +void CWsWindowRedraw::PrepareForResizeL(const TSize& /* aNewSize */, TSize& /* aOldSize */) + { + } + +TBool CWsWindowRedraw::DrawCommand(CWsGc*,const TAny*) + { + return ETrue; + } + +void CWsWindowRedraw::GcAttributeChange(CWsGc*,const TAny*) + { + } + +void CWsWindowRedraw::GcDeactivate(CWsGc*) + { + } + +CFbsDevice* CWsWindowRedraw::OutputDevice() const + { + return NULL; + } + +void CWsWindowRedraw::ClientExposing() + { + } + +void CWsWindowRedraw::ClearRedrawStore(TBool) + {} + +void CWsWindowRedraw::PreDrawWindow(MWsGraphicsContext* aGc, const TRegion& aWindowRegion) + { + WS_ASSERT_DEBUG(iRedrawRegion == NULL, EWsPanicScheduledRedraw); + iRedrawRegion = &aWindowRegion; + CPlaybackGc::Instance()->SetTargetRegion(iRedrawRegion); + CWsClient::iCurrentCommand.iOpcode=0; + CPlaybackGc::Instance()->Activate(CliWin(), aGc, iRedrawRegion); + } + +void CWsWindowRedraw::PostDrawWindow(MWsGraphicsContext* aGc, const TRegion& aWindowChildNodeRegion) + { + WS_ASSERT_DEBUG(iRedrawRegion, EWsPanicScheduledRedraw); + CPlaybackGc::Instance()->Deactivate(); + CPlaybackGc::Instance()->SetTargetRegion(NULL); + + if(!Screen()->ChangeTracking()) + { + DoFade(*iRedrawRegion); + } + + AnnotateWindowRedrawEnd(*iWsWin); + + DrawWindowAnims(aGc, aWindowChildNodeRegion); + DrawCursorAndSprites(aGc, aWindowChildNodeRegion); + iRedrawRegion = 0; + } + +void CWsWindowRedraw::Fade(MWsGraphicsContext * aGc, const TRegion& aRegion) + { + LOG_WINDOW_FADE_START(WsWin()); + AnnotateWindowRedrawStart(*iWsWin, aRegion); + + aGc->Reset(); + DoFade(aRegion); + + AnnotateWindowRedrawEnd(*iWsWin); + LOG_WINDOW_FADE_END(WsWin()); + } + +void CWsWindowRedraw::DoFade(const TRegion& aRegion) + { + if( CWsTop::IsFadeEnabled() && iWsWin && iWsWin->FadeCount()>0 && !(iWsWin->IsNonFading()) && !(iWsWin->FadableRegion().IsEmpty()) && !(iWsWin->IsDSAHost()) ) + { + MWsFader* fader = static_cast(iWsWin->Screen()->ResolveObjectInterface(KMWsFader)); + if(fader) + { + TFadingParams parameters; + iWsWin->GetFadingParams(parameters.blackMap,parameters.whiteMap); + TPckgBuf buf(parameters); + fader->SetFadingParameters(buf); + // Only fade the region that hasn't been faded before + STACK_REGION fdRgn; + fdRgn.Copy( aRegion ); + fdRgn.Intersect( iWsWin->FadableRegion() ); + if(!fdRgn.CheckError()) + { + fader->FadeArea( fdRgn ); + LOG_WINDOW_FADE_REGION(&fdRgn); + } + fdRgn.Close(); + } + } + } + +void CWsWindowRedraw::DrawWindowAnims(MWsGraphicsContext * aGc, const TRegion& aRegion) + { + if (iWsWin->iAnimList) + { + // If an anim panics, it will leave and set the panic flag on the client + // The client itself won't actually panic yet, and we don't want to leave from here. + TRAP_IGNORE(DrawWindowAnimsL(aGc, aRegion)); + } + } + +void CWsWindowRedraw::DrawWindowAnimsL(MWsGraphicsContext * aGc, const TRegion& aRegion) + { + for (CWsAnim * anim = iWsWin->iAnimList; anim; anim = anim->Next()) + { + AnnotateWindowAnimRedrawStart(*iWsWin, *anim, aRegion); + + //Animate and redraw + TRAPD(err,anim->RedrawWindowAnimL(Screen()->Now(), aGc, &aRegion)); + if(err!=KErrNone) + { + AnnotateWindowAnimRedrawEnd(*iWsWin, *anim); + anim->Panic(EWservPanicAnimLeave); + return; + } + + AnnotateWindowAnimRedrawEnd(*iWsWin, *anim); + } + } + +void CWsWindowRedraw::DrawCursorAndSprites(MWsGraphicsContext * aGc, const TRegion& aRegion) + { + // Draw standard text cursor if required + RWsTextCursor* const cursor = CWsTop::CurrentTextCursor(); + if (!iWsWin->Screen()->ChangeTracking() && cursor && cursor->Win() == iWsWin && cursor->IsStandardCursorActive()) + { + // Standard text cursor is active on this window + const TBool flashing = cursor->IsFlashing(); + TFlashState flashState = EFlashOn; + if (flashing) + { + flashState = cursor->CurrentCursorFlashState(); + } + if (flashState == EFlashOn) + { + // Cursor should be visible, so draw it + cursor->Draw(aRegion); + } + if (flashing) + { + // Reschedule to flash the standard cursor on or off + Screen()->ScheduleAnimation(ETextCursor, cursor->RectRelativeToScreen(), Screen()->SpriteManager()->NextCursorFlashStateChange(), 0, 0, iWsWin); + } + } + + for (CWsSpriteBase * sprite = iWsWin->iSpriteList; sprite; sprite = sprite->Next()) + { + TBool hasRedrawBegun = EFalse; + STACK_REGION redrawRegion; + sprite->CalcRedrawRegion(aRegion, redrawRegion); + if(redrawRegion.CheckError() || !redrawRegion.IsEmpty()) + { + if (sprite->IsFlashingEnabled() || sprite->IsDirty() || sprite->HasAnimation()) + { + if (sprite->IsDirty() || sprite->HasAnimation()) + { + AnnotateSpriteRedrawStart(*iWsWin, *sprite, redrawRegion); + hasRedrawBegun = ETrue; + } + + if(sprite->HasAnimation()) + { + CWsAnim* anim = static_cast(sprite)->iAnim; + WS_ASSERT_DEBUG(anim,EWsPanicAnim); + + //Animate and... + TRAPD(err, anim->AnimateSpriteAnimL(Screen()->Now())); + if(err!=KErrNone) + { + AnnotateSpriteRedrawEnd(*iWsWin, *sprite); + anim->Panic(EWservPanicAnimLeave); + return; + } + } + + //...call Redraw on the sprite + if (hasRedrawBegun) + { + aGc->Reset(); + } + sprite->Redraw(aGc, redrawRegion); + + if (hasRedrawBegun) + { + AnnotateSpriteRedrawEnd(*iWsWin, *sprite); + } + } + } + redrawRegion.Close(); + } + } + +TBool CWsWindowRedraw::Contains(const TArray& /*aDrawers*/,const TRegion& aRegion) const + { + // if in doubt, assume we do + return !aRegion.IsEmpty(); + } + +TInt CWsWindowRedraw::DrawBackgroundColor(const TRegion& aRegion, TBool aDoFillColor) + { + if (BackColor().Alpha() == 0 && !HasElement()) + return KErrNone; + + if(aRegion.IsEmpty()) + return KErrNone; + + TRect winAbs(CliWin()->AbsRect()); //fill size for background color fill + TRect surfaceAbs(0,0,0,0); //fill size for background surface fill - initially disabled + + if (HasElement()) + { + TBackgroundAttributes* backgroundAttributes = CliWin()->Screen()->WindowElements().FindBackgroundElement(*CliWin()); + WS_ASSERT_DEBUG(backgroundAttributes,EWsPanicNoWindowElement); + + if (backgroundAttributes->iElement) + { + if (backgroundAttributes->ExplicitExtent()) + { + backgroundAttributes->iElement->GetDestinationRectangle(surfaceAbs); + surfaceAbs.Intersection(winAbs); + if (surfaceAbs==winAbs) + { + winAbs.iBr.iX=winAbs.iTl.iX; //disable background color fill + } + } + else + { + surfaceAbs=winAbs; + winAbs.iBr.iX=winAbs.iTl.iX; //disable background color fill + } + } + if (!aDoFillColor) + { + winAbs.iBr.iX=winAbs.iTl.iX; //disable background color fill + } + } + + CPlaybackGc* playback = CPlaybackGc::Instance(); + MWsGraphicsContext* gc = static_cast(playback->ResolveObjectInterface(KMWsGraphicsContext)); + gc->SetClippingRegion(aRegion); + gc->SetBrushStyle(MWsGraphicsContext::ESolidBrush); + gc->SetPenStyle(MWsGraphicsContext::ENullPen); + TInt err = KErrNone; + if (!winAbs.IsEmpty()) + { + gc->SetBrushColor(BackColor()); + gc->DrawRect(winAbs); + } + if (!surfaceAbs.IsEmpty()) + { + gc->SetDrawMode(MWsGraphicsContext::EDrawModeWriteAlpha); + gc->SetBrushColor(TRgb(0,0,0,0)); + gc->DrawRect(surfaceAbs); + gc->SetBrushColor(BackColor()); //leave in a sensible state + gc->SetDrawMode(MWsGraphicsContext::EDrawModePEN); + } + gc->ResetClippingRegion(); + return err; + } + +TBool CWsWindowRedraw::ReleaseMemory(MWsMemoryRelease::TMemoryReleaseLevel) + { + return EFalse; + } + +void CWsWindowRedraw::VisibleRegionChange() + { + } + +TBool CWsWindowRedraw::ReadyToDraw() const + { + return ETrue; + } + +TBool CWsWindowRedraw::RedrawingInProgress() const + { + return EFalse; + } + +void CWsWindowRedraw::WindowClosing() + { + ReleaseBackgroundElement(); + } + +TBool CWsWindowRedraw::HasDsaElement() const + { + TBool hasDsaElement = EFalse; + + if (HasElement()) + { + CWsClientWindow* cliWin = CliWin(); + CWindowElementSet& set = cliWin->Screen()->WindowElements(); + TBackgroundAttributes* backgroundAttributes = set.FindBackgroundElement(*cliWin); + WS_ASSERT_DEBUG(backgroundAttributes,EWsPanicNoWindowElement); + + if (backgroundAttributes->iElement) + { + MWsElement& element = *(backgroundAttributes->iElement); + hasDsaElement = (element.ConnectedSurface() == cliWin->Screen()->DsaSurface()); + } + } + + return hasDsaElement; + } + +void CWsWindowRedraw::SetDsaElementL() + { + TRect extent(TPoint(0,0), WsWin()->Screen()->DSASizeInPixels()); + MWsDisplayMapping *dispMap = WsWin()->Screen()->DisplayMapping(); + TRect extentOut; + TRect extentInDSA; + if(dispMap) + { + dispMap->MapCoordinates(EDirectScreenAccessSpace,extent,EApplicationSpace,extentOut); + //DSA extent in application space intersects window extent in application space + extentOut.Intersection(WsWin()->FullRect()); + if(extentOut.IsEmpty()) + { + extentOut.SetRect(0,0,0,0); + } + //use DSA coordinates to determine the viewport + dispMap->MapCoordinates(EApplicationSpace, extentOut, EDirectScreenAccessSpace, extentInDSA); + } + else + { + extentOut = extent; + extentInDSA = extent; + extentOut.Intersection(WsWin()->FullRect()); + } + if (!HasDsaElement()) + { + WsWin()->Screen()->ClearDsaSurface(extent, BackColor()); + } + + TSurfaceConfiguration sc; + sc.SetSurfaceId(WsWin()->Screen()->DsaSurface()); + sc.SetExtent(extentOut.Size()); + sc.SetViewport(extentInDSA); + + SetBackgroundSurfaceL(sc, ETrue, ETrue); + } + +TBackgroundAttributes& CWsWindowRedraw::AcquireBackgroundElementL() + { + // Only client windows can have elements set + WS_ASSERT_DEBUG(iWsWin->WinType() == EWinTypeClient,EWsPanicWindowType); + CWsClientWindow* cliWin = static_cast(iWsWin); + CScreen* screen = cliWin->Screen(); + WS_ASSERT_DEBUG(screen,EWsPanicNoScreen); + + CWindowElementSet& set = screen->WindowElements(); + SetHasElement(EFalse); + TBackgroundAttributes& backgroundAttributes = set.AcquireBackgroundElementL(*cliWin); + MWsElement& element = *(backgroundAttributes.iElement); + element.SetGlobalAlpha(cliWin->IsVisible() ? 0xFF : 0); + SetHasElement(ETrue); + screen->ElementAdded(); + + return backgroundAttributes; + } + +void CWsWindowRedraw::SetBackgroundSurfaceL(const TSurfaceId& aSurface) + { + if (aSurface.Type() == TSurfaceId::EScreenSurface || aSurface.IsNull()) + { + OwnerPanic(EWservPanicInvalidSurface); + } + + CWsClientWindow* cliWin = CliWin(); + CScreen* screen = cliWin->Screen(); + CWindowElementSet& set = screen->WindowElements(); + TBackgroundAttributes& backgroundAttributes = AcquireBackgroundElementL(); + MWsElement& element = *(backgroundAttributes.iElement); + TInt err = set.RegisterSurface(aSurface); + if (err != KErrNone) + { + ReleaseBackgroundElement(); + User::Leave(err); + } + err = element.ConnectSurface(aSurface); + if (err != KErrNone) + { + set.UnregisterSurface(aSurface); + ReleaseBackgroundElement(); + User::Leave(err); + } + + TRect winExtent = cliWin->FullRect(); + element.SetDestinationRectangle(winExtent); + + // By default Element's source rectangle is set to its surface rectangle + TRect srcRect; + element.GetSourceRectangle(srcRect); + cliWin->SetOriginalSrcElementRect(srcRect); + cliWin->SetOriginalDestElementRect(winExtent); + + SetMayContainElementFlags(); + + MWsWindowTreeObserver* windowTreeObserver = Screen()->WindowTreeObserver(); + if (windowTreeObserver) + { + windowTreeObserver->ElementAdded(*iWsWin, element); + } + } + +void CWsWindowRedraw::SetBackgroundSurfaceL(const TSurfaceConfiguration& aConfiguration, TBool aTriggerRedraw, TBool aAllowScreenSurface) + { + if (aConfiguration.Size() < sizeof(TSurfaceConfiguration)) + { + __ASSERT_COMPILE(sizeof(TSurfaceConfiguration2)==sizeof(TSurfaceConfiguration)); + if (aConfiguration.Size() != sizeof(TSurfaceConfiguration1)) + { + OwnerPanic(EWservPanicInvalidSurfaceConfiguration); + } + } + + TSurfaceId surfaceId; + aConfiguration.GetSurfaceId(surfaceId); + if ((surfaceId.Type() == TSurfaceId::EScreenSurface && !aAllowScreenSurface) || surfaceId.IsNull()) + { + OwnerPanic(EWservPanicInvalidSurface); + } + + CFbsBitGc::TGraphicsOrientation tempOrientation = aConfiguration.Orientation(); + __ASSERT_COMPILE(CFbsBitGc::EGraphicsOrientationNormal==0 && + CFbsBitGc::EGraphicsOrientationRotated270 == 3); + if(tempOrientation < CFbsBitGc::EGraphicsOrientationNormal || + tempOrientation > CFbsBitGc::EGraphicsOrientationRotated270) + { + OwnerPanic(EWservPanicInvalidSurfaceConfiguration); + } + + CWsClientWindow* cliWin = CliWin(); + CScreen* screen = cliWin->Screen(); + __ASSERT_DEBUG(screen, Panic(EWsPanicNoScreen)); + + CWindowElementSet& set = screen->WindowElements(); + TBool mustRegister = ETrue; + TRect oldExtent(0,0,0,0); + MWsElement::TElementRotation oldRotation = MWsElement::EElementAntiClockwise0; + TBool oldFlip = EFalse; + TRect oldViewport(0,0,0,0); + TSurfaceId oldSurfaceId = TSurfaceId::CreateNullId(); + + // If a element has already been set + if (HasElement()) + { + TBackgroundAttributes* backgroundAttributes = set.FindBackgroundElement(*cliWin); + WS_ASSERT_DEBUG(backgroundAttributes,EWsPanicNoWindowElement); + + if (backgroundAttributes->iElement) + { + MWsElement& element = *(backgroundAttributes->iElement); + element.GetDestinationRectangle(oldExtent); + element.GetSourceRectangle(oldViewport); + oldRotation = element.SourceRotation(); + oldFlip = element.SourceFlipping(); + oldSurfaceId = element.ConnectedSurface(); + mustRegister = EFalse; + // If it is a different surface, flag to register the new surface + if (element.ConnectedSurface() != surfaceId) + { + mustRegister = ETrue; + } + } + } + + //the call to AcquireBackgroundElementL() will remove any existing background element + TBackgroundAttributes& backgroundAttributes = mustRegister ? + AcquireBackgroundElementL() : *(set.FindBackgroundElement(*cliWin)); + MWsElement& element = *(backgroundAttributes.iElement); + TInt err = KErrNone; + if (mustRegister) + { + err = set.RegisterSurface(surfaceId); + switch(err) + { + case KErrBadHandle: + // Invalid surface IDs have to return KErrArgument + err = KErrArgument; + // drop through + case KErrNoMemory: + case KErrArgument: + ReleaseBackgroundElement(); + User::Leave(err); + case KErrNone: + break; + default: + // No need to release layer here since session closure will do it + // automatically when the client thread is panicked. + OwnerPanic(EWservPanicInvalidSurface); + } + + err = element.ConnectSurface(surfaceId); + if (err != KErrNone) + { + set.UnregisterSurface(surfaceId); + ReleaseBackgroundElement(); //Releasing new empty element + User::Leave(err); + } + + if (screen->DsaSurface() == surfaceId) + { + TUint32 flags; + element.GetRenderStageFlags(flags); + flags |= MWsElement::EElementIsDirectlyRenderedUserInterface; + element.SetRenderStageFlags(flags); + } + } + + SetHasElement(ETrue); //set element flag + SetMayContainElementFlags(); + + err = CWindowElement::SetElement(element,aConfiguration,ETrue); //set viewport and orientation + if (err == KErrArgument) + { + OwnerPanic(EWservPanicInvalidSurfaceConfiguration); + } + TRect srcRect; + aConfiguration.GetViewport(srcRect); + if (!srcRect.IsEmpty()) + backgroundAttributes.SetExplicitViewPort(); + element.GetSourceRectangle(srcRect); + cliWin->SetOriginalSrcElementRect(srcRect); + + //Set Extent + TRect newExtent; + aConfiguration.GetExtent(newExtent); + SetElementExtentL(newExtent, backgroundAttributes); + cliWin->SetOriginalDestElementRect(newExtent); + + MWsWindowTreeObserver* windowTreeObserver = Screen()->WindowTreeObserver(); + if (windowTreeObserver && mustRegister) + { + windowTreeObserver->ElementAdded(*iWsWin, element); + } + + //If set, redraw + if (aTriggerRedraw) + { + TRect newViewport; + aConfiguration.GetViewport(newViewport); + CFbsBitGc::TGraphicsOrientation orientation = aConfiguration.Orientation(); + MWsElement::TElementRotation newRotation = GcToElementRotation(orientation); + TBool newFlip = aConfiguration.Flip(); + + //The following parameter guarantees that update will be scheduled. + //This will trigger the composition. + TBool alwaysScheduleUpdate = (oldSurfaceId != surfaceId) || + (oldExtent != newExtent) || + (oldViewport != newViewport) || + (oldRotation != newRotation)|| + (oldFlip != newFlip); + + ElementRedraw(oldExtent,newExtent,alwaysScheduleUpdate); + } + } + +/** +Sets the EMayContainElement flag for parent window. +Sets the flag for all ancestor windows. +**/ +void CWsWindowRedraw::SetMayContainElementFlags() + { + CWsWindowBase* parent = CliWin()->BaseParent(); + TInt type = parent->WinType(); + while(type ==EWinTypeClient) + { + CWsClientWindow* win = static_cast(parent); + win->Redraw()->iStateFlags |= EMayContainElement; + parent=parent->BaseParent(); + type = parent->WinType(); + } + } + +void CWsWindowRedraw::SetElementExtentL(TRect& aNewExtent, TBackgroundAttributes& aAttributes) + { + CWsClientWindow* cliWin = CliWin(); + MWsElement& element = *(aAttributes.iElement); + if (aNewExtent.IsEmpty()) + { + aNewExtent = cliWin->FullRect(); + aAttributes.SetExplicitExtent(EFalse); + } + else + { + TRect tempWindowPosition = cliWin->FullRect(); //get window absolute coordinates + aNewExtent.Move(tempWindowPosition.iTl); //shift user defined extent to absolute coordinates + aAttributes.SetExplicitExtent(ETrue); + } + element.SetDestinationRectangle(aNewExtent); + } + +void CWsWindowRedraw::ElementRedraw(const TRect& aOldExtent, const TRect& aNewExtent, TBool aAlwaysScheduleUpdate) + { + if (!aOldExtent.IsEmpty()) + { + //If the previous extent was different + if (aOldExtent != aNewExtent) + { + STACK_REGION tempRegion; + tempRegion.AddRect(aOldExtent); + tempRegion.AddRect(aNewExtent); + + //Calculate the difference between + TRect tempRect = aOldExtent; + tempRect.Intersection(aNewExtent); //intersect both regions + tempRegion.SubRect(tempRect); //cut unaltered region + Screen()->ScheduleRegionUpdate(&tempRegion); + + tempRegion.Close(); + } + else + { + if(aAlwaysScheduleUpdate) + { + TTimeIntervalMicroSeconds interval(0); + Screen()->ScheduleRender(interval); + } + } + } + else + { + TRegionFix<1> region(aNewExtent); + Screen()->ScheduleRegionUpdate(®ion); + } + } + +void CWsWindowRedraw::RemoveBackgroundSurface(TBool aTriggerRedraw) + { + if (HasElement()) + { + TBackgroundAttributes* backgroundAttributes = CliWin()->Screen()-> + WindowElements().FindBackgroundElement(*CliWin()); + WS_ASSERT_DEBUG(backgroundAttributes,EWsPanicNoWindowElement); + if (backgroundAttributes->iElement) + { + RemoveBackgroundElement(aTriggerRedraw); + } + } + } + +void CWsWindowRedraw::RemoveBackgroundElement(TBool aTriggerRedraw) + { + CWsClientWindow* cliWin = CliWin(); + CScreen* screen = cliWin->Screen(); + TRect tempRect; + if (aTriggerRedraw) + { + TBackgroundAttributes* backgroundAttributes = screen->WindowElements().FindBackgroundElement(*CliWin()); + WS_ASSERT_DEBUG(backgroundAttributes,EWsPanicNoWindowElement); + if (backgroundAttributes->ExplicitExtent()) + { + backgroundAttributes->iElement->GetDestinationRectangle(tempRect); + backgroundAttributes->SetExplicitExtent(EFalse); + } + else + { + tempRect = cliWin->FullRect(); + } + } + ReleaseBackgroundElement(); + if (aTriggerRedraw) + { + if (screen->ChangeTracking()) + { + TTimeIntervalMicroSeconds interval(0); + screen->ScheduleRender(interval); + } + else + { + TRegionFix<1> region(tempRect); + screen->ScheduleRegionUpdate(®ion); + } + } + } + +void CWsWindowRedraw::GetBackgroundSurfaceL(TSurfaceConfiguration& aConfiguration) + { + if (aConfiguration.Size() < sizeof(TSurfaceConfiguration)) + { + __ASSERT_COMPILE(sizeof(TSurfaceConfiguration2)==sizeof(TSurfaceConfiguration)); + if (aConfiguration.Size() != sizeof(TSurfaceConfiguration1)) + { + OwnerPanic(EWservPanicInvalidSurfaceConfiguration); + } + } + + CWsClientWindow* cliWin = CliWin(); + TBackgroundAttributes* backgroundAttributes = NULL; + + if (HasElement()) + { + backgroundAttributes = cliWin->Screen()->WindowElements().FindBackgroundElement(*cliWin); + WS_ASSERT_DEBUG(backgroundAttributes,EWsPanicNoWindowElement); + if (!backgroundAttributes->iElement) + { + User::Leave(KErrNotFound); + } + } + else + { + User::Leave(KErrNotFound); + } + + MWsElement& element = *(backgroundAttributes->iElement); + + TInt errCode=CWindowElementSet::GetConfiguration(aConfiguration,element); + + // Get source rect + if (errCode>=KErrNone) + { + if (!backgroundAttributes->ExplicitViewPort()) + { + aConfiguration.SetViewport(TRect()); + } + else + { + TRect tempExtent = cliWin->GetOriginalSrcElementRect(); + aConfiguration.SetViewport(tempExtent); + } + } + + //Convert and copy extent + if (errCode>=KErrNone) + { + if (!backgroundAttributes->ExplicitExtent()) + { + aConfiguration.SetExtent(TRect()); + } + else //translate to window coordinates + { + TRect tempExtent = cliWin->GetOriginalDestElementRect(); + tempExtent.Move(-cliWin->Origin()); + aConfiguration.SetExtent(tempExtent); + } + } + } + +void CWsWindowRedraw::ReleaseBackgroundElement() + { + if (HasElement()) + { + CWsClientWindow* cliWin = CliWin(); + CScreen* screen = cliWin->Screen(); + screen->WindowElements().ReleaseBackgroundElement(*cliWin, ETrue); + screen->ElementRemoved(); + } + } + +// +// Blank window // +// + +CWsBlankWindow::CWsBlankWindow(CWsWindow *aWin) : CWsWindowRedraw(aWin), iColor(iWsWin->RootWindow()->DefaultBackgroundColor()), iNoColor(EFalse) + { + } + +CWsBlankWindow::~CWsBlankWindow() + { + } + +void CWsBlankWindow::ConstructL() + { + CWsWindowRedraw::ConstructL(); + if (Screen()->ChangeTracking()) + { + STACK_REGION dirtyRegion; + dirtyRegion.Copy(iWsWin->WindowArea()); + dirtyRegion.Offset(-iWsWin->Origin()); + iWsWin->AddDirtyWindowRegion(dirtyRegion); + dirtyRegion.Close(); + } + } + +void CWsBlankWindow::SetColor(TRgb aColor) + { + iColor=aColor; + iNoColor=EFalse; + if (Screen()->ChangeTracking()) + { + STACK_REGION dirtyRegion; + dirtyRegion.Copy(iWsWin->WindowArea()); + dirtyRegion.Offset(-iWsWin->Origin()); + iWsWin->AddDirtyWindowRegion(dirtyRegion); + dirtyRegion.Close(); + + if (iWsWin->IsActive() && iWsWin->IsVisible()) + { + Screen()->ScheduleWindow(iWsWin); + } + } + else + { + Screen()->AddRedrawRegion(iWsWin->VisibleRegion()); + } + } + +TBool CWsBlankWindow::CommandL(TInt aOpcode, TWsWinCmdUnion &aCmd) + { + switch(aOpcode) + { + case EWsWinOpSetBackgroundSurface: + SetBackgroundSurfaceL(*aCmd.Surface); + break; + case EWsWinOpSetBackgroundSurfaceConfig: + SetBackgroundSurfaceL(aCmd.SurfaceConfigurationAndTrigger->surfaceConfig, aCmd.SurfaceConfigurationAndTrigger->triggerRedraw, EFalse); + break; + case EWsWinOpRemoveBackgroundSurface: + RemoveBackgroundSurface(*aCmd.Bool); + break; + case EWsWinOpGetBackgroundSurfaceConfig: + { + TSurfaceConfiguration tempConfiguration = *aCmd.SurfaceConfiguration; + GetBackgroundSurfaceL(tempConfiguration); + TInt tempSize = aCmd.SurfaceConfiguration->Size(); + if (sizeof(TSurfaceConfiguration)iAnimList) + iWsWin->Screen()->AddRedrawRegion(iWsWin->VisibleRegion()); + return(EFalse); + } + +TBool CWsBlankWindow::NeedsRedraw() const + { + return(EFalse); + } + +void CWsBlankWindow::DrawWindow() + { + if ((!iNoColor)||HasElement()) + { + DrawBackgroundColor(*iRedrawRegion,!iNoColor); + } + }