windowing/windowserver/nga/SERVER/openwfc/backedupwindow.cpp
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nga/SERVER/openwfc/backedupwindow.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,293 @@
+// 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:
+// Window redraw code, three sorts of redrawing are supported
+// This class deals with drawing from backup bitmap
+// 
+//
+
+#include "backedupwindow.h"
+#include "server.h"
+#include "gc.h"
+#include "wstop.h"
+#include "ANIM.H"
+#include "EVQUEUE.H"
+#include <s32mem.h>
+#include <gdi.h>
+#include "panics.h"
+#include "inifile.h"
+#include "rootwin.h"
+#include "EVENT.H"
+#include "playbackgc.h"
+#include "devicemap.h"
+
+CFbsBitGc *CWsBackedUpWindow::iBitGc=NULL;
+
+CWsBackedUpWindow::CWsBackedUpWindow(CWsWindow *aWin, TDisplayMode aDisplayMode) 
+	: CWsWindowRedraw(aWin), iDisplayMode(aDisplayMode)
+	{}
+
+void CWsBackedUpWindow::StaticInitL()
+	{
+	iBitGc=CFbsBitGc::NewL();
+	}
+
+void CWsBackedUpWindow::StaticDestroy()
+	{
+	delete iBitGc;
+	iBitGc = 0;
+	}
+
+void CWsBackedUpWindow::ActivateGc()
+	{
+	iBitGc->Activate(iBitmapDevice);
+	iBitGc->Reset();
+	iBitGc->SetBrushColor(BackColor());
+	}
+
+TBool CWsBackedUpWindow::DrawCommand(CWsGc*,const TAny*)
+	{
+	if (Screen()->ChangeTracking())
+		MarkDirtyAndSchedule(iCurrentRegion);
+	else
+		Screen()->AddRedrawRegion(iWsWin->VisibleRegion());
+	
+	return ETrue;
+	}
+
+void CWsBackedUpWindow::ConstructL()
+	{
+	iDisplayMode=iWsWin->SetRequiredDisplayModeL(iDisplayMode);
+	TSize size=iWsWin->Size();
+	iBitmap=new(ELeave) CFbsBitmap();
+	User::LeaveIfError(iBitmap->Create(size, iDisplayMode));
+	iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap);
+	SetSizeInTwips();
+//
+	ActivateGc();
+	iBitGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+	iBitGc->Clear(TRect(size));
+	iBitGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
+	WS_ASSERT_DEBUG(iWsWin->WinType()==EWinTypeClient,EWsPanicWindowType);
+	}
+
+void CWsBackedUpWindow::PrepareForResizeL(const TSize &aSize, TSize &aOldSize)
+	{
+	aOldSize=iBitmapDevice->SizeInPixels();
+	if (aOldSize!=aSize)
+		{
+		User::LeaveIfError(iBitmapDevice->Resize(aSize));
+		SetSizeInTwips();
+		}
+	}
+
+void CWsBackedUpWindow::Resize(const TSize &aSize, const TSize &aOldSize)
+	{
+	ActivateGc();
+	iBitGc->SetClippingRegion(NULL);
+	iBitGc->Clear(TRect(aOldSize.iWidth, 0, aSize.iWidth, aOldSize.iHeight));
+	iBitGc->Clear(TRect(0, aOldSize.iHeight,aSize.iWidth, aSize.iHeight));
+	
+	static_cast<CWsClientWindow *>(iWsWin)->ReactivateGcs();
+	
+	if(Screen()->ChangeTracking())
+		{
+		//Keep track of the region we need to refresh when we recieve draw commands
+		iCurrentRegion.Reset();
+		iCurrentRegion.Copy(iWsWin->WindowArea());
+		iCurrentRegion.Offset(-iWsWin->Origin());
+		iCurrentRegion.Tidy();
+		if(iCurrentRegion.CheckError())
+			{
+			iCurrentRegion.Reset();
+			TRegionFix<1> fallback(iWsWin->AbsRect());
+			iCurrentRegion.Copy(fallback); 
+			iCurrentRegion.Offset(-iWsWin->Origin());
+			}
+		
+		//If the window has nerver been drawn to screen, we now schedule the initial draw. This can't
+		//be done in ConstructL because BackedUpWindows are created with size(0,0). And we can't check
+		//iWsWin->IsActive() because the client might activate the window before giving it a size.
+		if (!iHasBeenScheduled)
+			{
+			iHasBeenScheduled = ETrue;
+			MarkDirtyAndSchedule(iCurrentRegion);
+			}
+		}
+	}
+
+CWsBackedUpWindow::~CWsBackedUpWindow()
+	{
+	iCurrentRegion.Reset();
+	delete iBitmapDevice;
+	delete iBitmap;
+	}
+
+TBool CWsBackedUpWindow::CommandL(TInt aOpcode, TWsWinCmdUnion &aCmd)
+	{
+	switch(aOpcode)
+		{
+		case EWsWinOpUpdateBackupBitmap:
+			break;
+		case EWsWinOpMaintainBackup:
+			break;
+		case EWsWinOpBitmapHandle:
+			SetReply(iBitmap->Handle());
+			break;
+		case EWsWinOpUpdateScreen:
+			{
+			TRegionFix<1> fixRegion(iWsWin->AbsRect());
+			UpdateScreen(fixRegion);
+			}
+			break;
+		case EWsWinOpUpdateScreenRegion:
+			{
+			RWsRegion *clientRegion=NULL;
+			TRAPD(err,clientRegion=GetRegionFromClientL(iWsWin->WsOwner(), *aCmd.Int));
+			if (err==KErrNone && !clientRegion->CheckError())
+				{
+				clientRegion->Offset(iWsWin->Origin());
+				clientRegion->ClipRect(iWsWin->AbsRect());
+				UpdateScreen(*clientRegion);
+				}
+			else
+				{
+				TRegionFix<1> fixRegion(iWsWin->AbsRect());
+				UpdateScreen(fixRegion);
+				}
+			clientRegion->Destroy();
+			}
+			break;
+		case EWsWinOpSetBackgroundSurface:
+		case EWsWinOpSetBackgroundSurfaceConfig:
+		case EWsWinOpGetBackgroundSurfaceConfig:
+			OwnerPanic(EWservPanicDrawable);	// Backed up windows don't support these
+			break;
+		default:
+			return(EFalse);
+		}
+	return(ETrue);
+	}
+
+CWsBackedUpWindow *CWsBackedUpWindow::Backup() const
+	{
+	return((CWsBackedUpWindow *)this);
+	}
+
+CFbsDevice* CWsBackedUpWindow::OutputDevice() const
+	{
+	return iBitmapDevice;
+	}
+
+TRgb CWsBackedUpWindow::BackColor() const
+	{
+	return(iWsWin->RootWindow()->DefaultBackgroundColor());
+	}
+
+void CWsBackedUpWindow::Scroll(const TRect &aClipRect, const TPoint &aOffset,const TRect &aRect)
+	{
+	TRect winBorder=TRect(iWsWin->Size());
+	TRect clipRect=aClipRect;
+	TRect srcRect = aRect;		
+	clipRect.Intersection(winBorder);	
+	if (!clipRect.IsEmpty())
+		{	// If we have to do something (a visible part will change)
+		srcRect.Intersection(clipRect);
+
+		STACK_REGION regionToClear;
+		regionToClear.AddRect(aRect);
+		regionToClear.SubRect(srcRect);
+		regionToClear.Offset(aOffset);
+		
+		ActivateGc();
+		iBitGc->SetClippingRect(clipRect);
+		iBitGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+		iBitGc->CopyRect(aOffset,srcRect);				
+		for (TInt k=0;k<regionToClear.Count();k++)
+			{
+			iBitGc->Clear(regionToClear[k]);
+			}
+		iBitGc->SetClippingRect(winBorder);
+		iBitGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
+		TRegionFix<1> fixRegion(iWsWin->AbsRect());
+		UpdateScreen(fixRegion);
+		regionToClear.Close();
+		}
+	}
+
+TBool CWsBackedUpWindow::NeedsRedraw() const
+	{
+	return(EFalse);
+	}
+
+TBool CWsBackedUpWindow::GetRedrawRect(TRect &) const
+	{
+	return(EFalse);
+	}
+
+void CWsBackedUpWindow::SetSizeInTwips()
+	{
+	TSize size=iBitmap->SizeInPixels();
+	size.iWidth=Screen()->DeviceMap().HorizontalPixelsToTwips(size.iWidth);
+	size.iHeight=Screen()->DeviceMap().VerticalPixelsToTwips(size.iHeight);
+	iBitmap->SetSizeInTwips(size);
+	}
+
+void CWsBackedUpWindow::DrawWindow()
+	{
+	MWsGraphicsContext* gc = static_cast<MWsGraphicsContext*>(CPlaybackGc::Instance()->ResolveObjectInterface(KMWsGraphicsContext));
+	
+	gc->SetOrigin(iWsWin->Origin());
+	gc->SetClippingRegion(*iRedrawRegion);
+	gc->BitBlt(TPoint(0,0), *iBitmap);
+	}
+
+/** 
+This function updates the window's dirty region and schedules a redraw if needed.
+Only used when the screen is run in CHANGETRACKING mode. 
+@param aRegion in window coordinates
+*/
+void CWsBackedUpWindow::MarkDirtyAndSchedule(const TRegion& aRegion)
+	{
+	WS_ASSERT_DEBUG(Screen()->ChangeTracking(),EWsPanicNoChangetracking);
+	
+	if(!aRegion.IsEmpty())
+		{
+		iWsWin->AddDirtyWindowRegion(aRegion);
+		if (iWsWin->IsActive() && iWsWin->IsVisible())
+			{
+			Screen()->ScheduleWindow(iWsWin);
+			}
+		}
+	}
+
+/**
+This function selects the desired behaviour depending on whether the screen is
+run in CHANGETRACKING mode or not. 
+@param aRegion in screen coordinates
+*/
+void CWsBackedUpWindow::UpdateScreen(const TRegion& aRegion)
+	{
+	if (Screen()->ChangeTracking())
+		{
+		STACK_REGION region;
+		region.Copy(aRegion);
+		region.Offset(-WsWin()->Origin()); //convert to window coordinates 
+		MarkDirtyAndSchedule(region);
+		region.Close();		
+		}
+	else
+		{
+		Screen()->AddRedrawRegion(aRegion);
+		}
+	}