windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp
changeset 0 5d03bc08d59c
child 84 de3e07519bb7
child 116 171fae344dd4
child 152 9f1c3fea0f87
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1467 @@
+// 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:
+// Client window functions
+// 
+//
+
+#include "W32CLICK.H"
+#include <graphics/wselement.h>
+#include "server.h"
+#include "cliwin.h"
+#include "gc.h"
+#include "rootwin.h"
+#include "windowgroup.h"
+#include "walkwindowtree.h"
+#include "ScrDev.H"
+#include "wstop.h"
+#include "EVQUEUE.H"
+#include "KEYCLICK.H"
+#include "panics.h"
+#include "password.h"
+#include "pointer.h"
+#include "EVENT.H"
+#include "backedupwindow.h"
+#include "redrawmsgwindow.h"
+#include "windowelementset.h"
+
+
+
+
+TBool CWsClientWindow::iAbsoluteFading = EFalse;
+
+const TPoint corner1[1]={TPoint(1,1)};
+const TPoint corner2[2]={TPoint(2,1),TPoint(1,1)};
+const TPoint corner3[2]={TPoint(3,1),TPoint(1,2)};
+const TPoint corner5[4]={TPoint(5,1),TPoint(3,1),TPoint(2,1),TPoint(1,2)};
+
+/*CWsClientWindow*/
+
+CWsClientWindow::CWsClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsWindow(aOwner,WS_HANDLE_WINDOW,aScreen)
+	{
+	iWinType=EWinTypeClient;
+	}
+
+void CWsClientWindow::ConstructL(const TWsClCmdCreateWindow &aCmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid)
+	{
+	CWsWindow::Construct();
+	NewObjL();
+	if (aCmd.clientHandle==NULL)
+		OwnerPanic(EWservPanicNullHandle);
+#if defined(_DEBUG)
+	if (IsClientHandleInUse(aCmd.clientHandle))
+		OwnerPanic(EWservPanicDuplicateHandle);
+#endif
+	iPointerFilter=EPointerFilterEnterExit|EPointerFilterMove|EPointerFilterDrag;
+	iClientHandle=aCmd.clientHandle;
+	CWsWindow* inherit=static_cast<CWsWindow *>(aParent);
+	if (aParent->WinType()==EWinTypeGroup)
+		inherit=RootWindow();
+	SetPointerCursor(aParent->PointerCursor());
+	iAbs=inherit->Abs();
+	iOrigin=aParent->Origin();
+	iRel.iBr.iX=inherit->Rel().iBr.iX-inherit->Rel().iTl.iX;
+	iRel.iBr.iY=inherit->Rel().iBr.iY-inherit->Rel().iTl.iY;
+	switch(aCmd.type)
+		{
+		case EWinRedraw:
+			iRedraw=new(ELeave) CWsRedrawMsgWindow(this);
+			break;
+		case EWinBackedUp:
+			iRedraw=new(ELeave) CWsBackedUpWindow(this, aCmd.displayMode);
+			iAbs.iBr=iAbs.iTl;
+			iRel.iBr=iRel.iTl;
+			break;
+		case EWinBlank:
+			iRedraw=new(ELeave) CWsBlankWindow(this);
+			break;
+		default:
+			OwnerPanic(EWservPanicRedrawType);
+		}
+	ResetHiddenFlag();
+	SetCornerTypeL(EWindowCornerSquare,0,NULL,EFalse);
+	CWsWindowBase::ConstructL(aParent);
+	if (aScreenDeviceIsInvalid)
+		{
+		iFlags|=EFlagScreenDeviceInvalid;
+		ResetHiddenFlag();
+		}
+	iRedraw->ConstructL();
+	}
+
+void CWsClientWindow::GetBaseAreaOfNode(RWsRegion &aRegion) const
+    {
+    if (iBaseArea)
+        {
+        aRegion.Copy(*iBaseArea);
+        }
+    aRegion.ClipRect(iAbs);
+    }
+
+void CWsClientWindow::ClipRegionToBaseArea(RWsRegion &aRegion) const
+    {
+    if (iBaseArea)
+        {
+        aRegion.Intersect(*iBaseArea);
+        }
+    aRegion.ClipRect(iAbs);
+    }
+
+void CWsClientWindow::GetClippedBaseArea(RWsRegion &aRegion) const
+	{
+	const CWsWindowBase* ancestor = BaseParent();	    
+	GetBaseAreaOfNode(aRegion);	
+	while (ancestor && ancestor->WinType() == EWinTypeClient)
+	    {
+	    static_cast<const CWsClientWindow*>(ancestor)->ClipRegionToBaseArea(aRegion);       
+	    ancestor = ancestor->BaseParent();
+	    }
+	}
+
+void CWsClientWindow::GetOpaqueBaseAreaOfNode(RWsRegion &aRegion) const
+    {
+    if (IsTranslucent())
+        {
+        if (iUserDefinedOpaqueRegion)
+            {
+            aRegion.Copy(*iUserDefinedOpaqueRegion);
+            aRegion.ClipRect(iAbs);
+            }
+        else
+            {
+            aRegion.Clear();
+            }
+        }
+    else
+        {
+        GetBaseAreaOfNode(aRegion);
+        }
+    }
+
+void CWsClientWindow::ClipRegionToOpaqueBaseArea(RWsRegion& aRegion) const
+    {
+    if (IsTranslucent())
+        {
+        if (iUserDefinedOpaqueRegion)
+            {
+            aRegion.Intersect(*iUserDefinedOpaqueRegion);
+            aRegion.ClipRect(iAbs);
+            }
+        else
+            {
+            aRegion.Clear();
+            }
+        }
+    else
+        {
+        ClipRegionToBaseArea(aRegion);
+        }
+    }
+
+void CWsClientWindow::GetOpaqueClippedBaseArea(RWsRegion &aRegion) const
+	{
+	const CWsWindowBase* ancestor = BaseParent();
+	GetOpaqueBaseAreaOfNode(aRegion);
+	while (ancestor && ancestor->WinType() == EWinTypeClient)
+	    {
+	    static_cast<const CWsClientWindow*>(ancestor)->ClipRegionToOpaqueBaseArea(aRegion);
+	    ancestor = ancestor->BaseParent();
+	    }
+	}
+
+TInt CWsClientWindow::GetNonOpaqueBaseAreaOfNode(RWsRegion &aRegion) const
+    {
+    aRegion.Clear();
+    if (IsTranslucent())
+        {
+        if(iUserDefinedTransparentRegion)
+            {
+            aRegion.Copy(*iUserDefinedTransparentRegion);
+            aRegion.ClipRect(iAbs);
+            return KErrNone;
+            }
+        }  
+    return KErrNotFound;
+    }
+
+void CWsClientWindow::ResetHiddenFlag()
+//
+// Reset the status of the hidden flag based on the current states of the active and invisible flags
+//
+	{
+	CWsClientWindow *parent=static_cast<CWsClientWindow*>(iParent);
+
+	TBool wasHidden = iFlags&EFlagHidden;
+	TBool nowHidden = (parent==NULL || 
+		              (parent->WinType()==EWinTypeClient && !parent->IsVisible()) ||
+	                  !(iFlags&EFlagActive) ||
+	                  (iFlags&EFlagInvisible) ||
+			          (iFlags&EFlagScreenDeviceInvalid));
+
+	if (nowHidden)
+		{
+		iFlags|=EFlagHidden;
+		iFlags&=~EFlagDrawnToScreen;
+		}
+	else
+		{
+		iFlags&=~EFlagHidden;
+		}
+	if ((!nowHidden) != (!wasHidden))
+		{
+		// intentionally call the screen directly
+		iScreen->ScheduleRegionUpdate(&iVisibleRegion);
+		
+		WS_ASSERT_DEBUG(!iDirtyWindowRegion.CheckError(),EWsPanicErrorInRegion);
+		WS_ASSERT_DEBUG(!iDirtySpriteRegion.CheckError(),EWsPanicErrorInRegion);
+	//	WS_ASSERT_DEBUG(!InvalidArea().CheckError(),EWsPanicErrorInRegion);		//error flag in invalid area may be set in OOM cases
+																				//thus the assert statement is caused to fail
+		if (wasHidden && iScreen->ChangeTracking() && 
+				(!iDirtyWindowRegion.IsEmpty() || !iDirtySpriteRegion.IsEmpty() || !InvalidArea().IsEmpty()))
+			{
+			// Window has just become visible, schedule it
+			iScreen->ScheduleWindow(this);
+			}
+		}
+	}
+	
+void CWsClientWindow::ResetHiddenFlags()
+	{
+	CWsClientWindow *win=this;
+	FOREVER
+		{
+		TUint oldHiddenFlag=win->iFlags&EFlagHidden;
+		win->ResetHiddenFlag();
+		if ((win->iFlags&EFlagHidden)!=oldHiddenFlag)	// If hidden status hasn't changed nothing to do
+			{
+			win->SetElementOpacity(IsVisible() ? 0xFF : 0x00);	// Update element visibility
+			if (win->Child())
+				{
+				win=win->Child();
+				continue;
+				}
+			}
+		if (win==this)
+			return;
+		while(!win->NextSibling())
+			{
+			win=(CWsClientWindow *)win->BaseParent();
+			if (win==this)
+				return;
+			}
+		win=win->NextSibling();
+		} // for loop ends
+	}
+
+void CWsClientWindow::OffsetBaseArea(const TPoint &aOffset)
+	{
+	iBaseArea->Offset(aOffset);
+	//If the given window's position changes, then update.
+	if (aOffset.iX || aOffset.iY)
+		{
+		UpdateElementExtent(&aOffset);
+		}
+	}
+
+void CWsClientWindow::CalcBaseArea()
+//
+// The windows basic area before any clipping is done
+//
+	{
+	TInt cornerType=iCornerData&ECornerTypeMask;
+	if (cornerType==EWindowCornerRegion)
+		iBaseArea->ClipRect(FullRect());
+	else
+		{
+		TSize size=Size();
+		iBaseArea->Clear();
+		const TPoint *corners=NULL;
+		TInt count=0;
+		switch(cornerType)
+			{
+			case EWindowCorner1:
+				count=sizeof(corner1)/sizeof(TPoint);
+				corners=corner1;
+				break;
+			case EWindowCorner2:
+				count=sizeof(corner2)/sizeof(TPoint);
+				corners=corner2;
+				break;
+			case EWindowCorner3:
+				count=sizeof(corner3)/sizeof(TPoint);
+				corners=corner3;
+				break;
+			case EWindowCorner5:
+				count=sizeof(corner5)/sizeof(TPoint);
+				corners=corner5;
+				break;
+			default:
+				break;
+			}
+		TInt top=0;
+		TInt bot=size.iHeight;
+		for(TInt index=0;index<count;index++)
+			{
+			TInt xadjust=corners[index].iX;
+			TInt yadjust=corners[index].iY;
+			if ((iCornerData&(EWindowCornerNotTL|EWindowCornerNotTR))!=(EWindowCornerNotTL|EWindowCornerNotTR))
+				{
+				iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotTL?0:xadjust,top,
+										 size.iWidth-(iCornerData&EWindowCornerNotTR?0:xadjust),top+yadjust));
+				top+=yadjust;
+				}
+			if ((iCornerData&(EWindowCornerNotBL|EWindowCornerNotBR))!=(EWindowCornerNotBL|EWindowCornerNotBR))
+				{
+				iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotBL?0:xadjust,bot-yadjust,
+										 size.iWidth-(iCornerData&EWindowCornerNotBR?0:xadjust),bot));
+				bot-=yadjust;
+				}
+			}
+		iBaseArea->AddRect(TRect(0,top,size.iWidth,bot));
+		iBaseArea->Offset(Origin());
+		iBaseArea->ClipRect(FullRect());
+		iBaseArea->Sort();
+		}
+	}
+
+void CWsClientWindow::GenerateArea(RWsRegion &aArea, TBool aClipTranslucent) const
+//
+// Create the window area list.
+//
+	{
+	aArea.Clear();
+	if (IsVisible())
+		{
+		aArea.Copy(*iBaseArea);
+		aArea.ClipRect(iAbs);
+		const CWsClientWindow *win=this;
+		FOREVER
+			{
+			if (win->IsTopClientWindow())
+				break;
+			ClipWindows(aArea,(CWsClientWindow *)win->BaseParent()->BaseChild(),win,aClipTranslucent);
+			win=(CWsClientWindow *)win->iParent;
+			}
+		TInt tidyCount=0;
+		for(const CWsTopClientWindow *cwin=RootWindow()->FirstTopClientWindow();aArea.Count() && cwin!=win;cwin=cwin->NextSiblingMultiParent())
+			{
+			if (!tidyCount--)
+				{
+				aArea.Tidy();
+				tidyCount=ETidyCountSetting;	// Tidy every ETidyCountSetting times around
+				}
+			if (cwin->IsVisible())
+				{
+				if (cwin->IsTranslucent() && !aClipTranslucent)
+					{
+					if (cwin->iUserDefinedOpaqueRegion)
+						{
+						aArea.SubRegion(*cwin->iUserDefinedOpaqueRegion);
+						}
+					}
+				else
+					{
+					aArea.SubRegion(*cwin->iBaseArea);
+					}
+				}
+			}
+		aArea.Tidy();
+		}
+	}
+
+void CWsClientWindow::ClipWindows(TRegion &region,const CWsClientWindow *start, const CWsClientWindow *end, TBool aClipTranslucent)
+//
+// Remove out of the region the opaque part of the abs rect of all the windows starting from 'start'
+// along the sibling list to (and not including) the end window.
+//
+	{
+	for(const CWsClientWindow *win=start;region.Count() && win!=end;win=win->NextSibling())
+		{
+		if (win->IsVisible())
+			{
+			if (win->IsTranslucent() && !aClipTranslucent)
+				{
+				if (win->iUserDefinedOpaqueRegion)
+					{
+					region.SubRegion(*win->iUserDefinedOpaqueRegion);
+					}
+				}
+			else
+				{
+				region.SubRegion(*win->iBaseArea);
+				}
+			}
+		}
+	}
+
+void CWsClientWindow::GenerateTopRegion(RWsRegion& aRegion) const
+	{
+	GenerateArea(aRegion,ETrue);
+	if (iChild)
+		ClipWindows(aRegion,Child(),NULL,ETrue);
+	}
+
+void CWsClientWindow::GenerateWindowRegion(RWsRegion &aRegion) const
+//
+// Calculate the windows clipping region without using the usual stored iArea or iRegion fields
+// this function is used by the screen backup code to calculate "what if" regions to work out
+// whether something would be visible if the backed up window didn't exist, on this basis we
+// don't want to modify the existing copies of iArea & iRegion.
+//
+	{
+	GenerateArea(aRegion,EFalse);
+	if (iChild)
+		ClipWindows(aRegion,Child(),NULL,EFalse);
+	}
+
+const TRegion *CWsClientWindow::DrawingRegion()
+	{
+	return (&iRedraw->BaseDrawRegion());
+	}
+
+void CWsClientWindow::RecalcChildAbs(const TPoint *aOffset)
+	{
+	CWsClientWindow *win=this;
+	FOREVER
+		{
+		FOREVER
+			{
+			win->SetAbsFromRel();
+			if (aOffset)
+				win->OffsetBaseArea(*aOffset);
+			if (win->Child()==NULL)
+				break;
+			win=win->Child();
+			}
+		FOREVER
+			{
+			if (win==this)
+				return;
+			if (win->NextSibling()!=NULL)
+				{
+				win=win->NextSibling();
+				break;
+				}
+			win=(CWsClientWindow *)win->iParent;	// The cast is safe as the loop is aborted when win==this
+			}
+		}
+	}
+
+void CWsClientWindow::SetAbsFromRel()
+	{
+	iOrigin=iRel.iTl+iParent->Origin();
+	iAbs=iRel;
+	iAbs.Move(iParent->Origin());
+	iAbs.Intersection(iParent->AbsRect());
+	}
+
+void CWsClientWindow::SetExtentL(const TPoint *aPos,const TSize *aSize)
+	{
+	if (iParent==NULL)
+		OwnerPanic(EWservPanicParentDeleted);
+	TPoint offset = TPoint(0,0);
+	TSize oldSize;
+	TSize newSize;
+	TBool sizeChanged = EFalse;
+	TBool posChanged = EFalse;
+	
+	if (aPos)
+		{
+		offset = *aPos+iParent->Origin()-iOrigin;
+		if (offset.iX != 0 || offset.iY != 0)
+			{
+			posChanged = ETrue;
+			}
+		}
+		
+	if (posChanged)
+		{
+		TWalkWindowTreeScheduleRedraws wwt;
+		WalkWindowTree(wwt, EWalkChildren);
+		}
+	
+	if (aSize)
+		{
+		newSize=*aSize;
+		if (newSize.iWidth<0)
+			newSize.iWidth=0;
+		if (newSize.iHeight<0)
+			newSize.iHeight=0;
+		// This should be the only part of resizing that can fail
+		// and it can only fail for backedup windows.
+		iRedraw->PrepareForResizeL(newSize,oldSize);
+		sizeChanged = *aSize != iRel.Size();
+		}
+
+	if (posChanged)
+		{
+		iRel.Move(offset);
+		RecalcChildAbs(&offset);      // Also calls UpdateElementExtent(offset)
+		TWalkWindowTreeOffsetTransparentRegions offsetTransparent(offset);
+		WalkWindowTree(offsetTransparent, EWalkChildren);
+		}
+
+	if (sizeChanged)
+		{
+		iRel.SetSize(newSize);
+		RecalcChildAbs(NULL);
+		CalcBaseArea();
+		iRedraw->Resize(newSize,oldSize);
+		if (Redraw()->HasElement())
+		    UpdateElementExtent();
+		}
+	
+	if ((posChanged || sizeChanged) && Redraw()->HasElement())
+		{
+		TRect interSection(iParent->Origin(), iParent->Size());
+		interSection.Intersection(FullRect());
+		if (interSection == FullRect())
+			{
+			// There is no any clipping in this case
+			interSection = TRect();
+			}
+		// Get the corresponding source rectangle for the element
+		if (!iOriginalSrcElementRect.IsEmpty() && !iOriginalDestElementRect.IsEmpty() && !iAbs.IsEmpty())
+			{
+			MWsElement* element = Screen()->WindowElements().GetElementFromWindow(*this);
+			if (element)
+				{
+				element->SetDestinationClippingRect(interSection);
+				}
+			}
+		}	
+	
+	if (posChanged || sizeChanged)
+		{
+		iRedraw->ClipInvalidRegion(TRect(iRel.Size()));
+		iRedraw->Moved();
+		ScheduleRegionUpdate(NULL);
+		TWalkWindowTreeRecalcOpaque recalcOpaque;
+		WalkWindowTree(recalcOpaque, EWalkChildren);
+
+		MWsWindowTreeObserver* windowTreeObserver = Screen()->WindowTreeObserver();
+		if (windowTreeObserver)
+			{
+			windowTreeObserver->NodeExtentChanged(*this, FullRect());
+			}
+		}
+	}
+
+
+void CWsClientWindow::GetElementFlipAndRotation(TBool& aElemetFlip, MWsElement::TElementRotation& aElemenetRotation)
+    {
+    MWsElement* element = Screen()->WindowElements().GetElementFromWindow(*this);
+    if (element)
+        {
+        aElemetFlip = element->SourceFlipping();
+        aElemenetRotation = element->SourceRotation();
+        }
+    }
+
+void CWsClientWindow::Scroll(const TRect &aClipRect, const TPoint &aOffset, const TRect &aRect)
+	{
+	if (iParent==NULL)
+		OwnerPanic(EWservPanicParentDeleted);
+	
+//
+	iRedraw->Scroll(aClipRect, aOffset,aRect);
+//
+	CWsTop::TriggerRedraws(RootWindow());
+	}
+
+void CWsClientWindow::DeleteBaseArea()
+	{
+	WS_ASSERT_DEBUG(iBaseArea!=&nullRegion, EWsPanicRegionNull);
+ 	if ((iCornerData&ECornerTypeMask)==EWindowCornerRegion)
+		((RWsRegion *)iBaseArea)->Destroy();
+	else
+		{
+		delete iBaseArea;
+		}
+ 	iBaseArea=NULL;
+	}
+
+CWsClientWindow::~CWsClientWindow()
+	{
+	while(iVisibleRegionTrackingCounter>0)
+		{
+		SetupVisibleRegionTracking(EFalse);
+		}
+	if (iBaseWinFlags&EBaseWinNodeCreated)
+		{
+		MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+		if (windowTreeObserver)
+			{
+			windowTreeObserver->NodeReleased(*this);
+			iBaseWinFlags &= ~EBaseWinNodeCreated;
+			}
+		}
+	Shutdown();
+	SetUserTransparentRegion(0);
+	CWsPassword::WindowDestroyed(this);
+	}
+
+void CWsClientWindow::Shutdown()
+//
+// Destroy a window, disconnects from the window tree and destroys all it's child windows
+//
+	{
+	iFlags|=EFlagShutDownInProgress;
+	if (CClick::IsHandler())
+		{
+		TWindowCloseData params;
+		params.iClientHandle=iClientHandle;
+		//if parent already shutdown (or disconnected) send 0
+		params.iWindowGroupId = (iParent) ? WinGroup()->Identifier() : 0;
+		CClick::OtherEvent(EEventWindowClose,&params);
+		}
+
+	RemoveAllKeyRects();
+	while(iWinGcList)
+		iWinGcList->Deactivate();
+//
+	iFlags|=EFlagInvisible;		// First make it invisble
+	if (iParent)				// In case window wasn't fully constructed
+		ResetHiddenFlags();
+//
+	CWsWindow::Shutdown();
+	DeleteBaseArea();
+	CWsPointerBuffer::Disconnect(this);
+	iFlags&=~EFlagShutDownInProgress;
+	}
+
+void CWsClientWindow::Activate()
+	{
+	if (iFlags&EFlagActive)
+		OwnerPanic(EWservPanicWindowActive);
+	iFlags|=EFlagActive;
+
+	ResetHiddenFlags();
+
+	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+	if (windowTreeObserver)
+		{
+		windowTreeObserver->NodeExtentChanged(*this, FullRect());
+		windowTreeObserver->NodeActivated(*this);
+		}
+	}
+
+TBool CWsClientWindow::IsActivated() const
+	{
+	return (iFlags&EFlagActive)!=EFalse;
+	}
+
+void CWsClientWindow::SetCornerTypeL(TCornerType aCornerType, TInt aCornerFlags, TRegion *aNewBaseArea, TBool aNotifyShapeChanged)
+	{
+	TRegion *baseArea=NULL;
+	if (aCornerFlags&ECornerTypeMask)
+		OwnerPanic(EWservPanicCornerParams);
+	
+ 	switch (aCornerType)
+		{
+		case EWindowCornerSquare:
+			baseArea=new(ELeave) TRegionFix<1>();
+			break;
+		case EWindowCorner1:
+			baseArea=new(ELeave) TRegionFix<3>();
+			break;
+		case EWindowCorner2:
+		case EWindowCorner3:
+			baseArea=new(ELeave) TRegionFix<5>();
+			break;
+		case EWindowCorner5:
+			baseArea=new(ELeave) TRegionFix<9>();
+			break;
+		case EWindowCornerRegion:
+			User::LeaveIfNull(baseArea=aNewBaseArea);
+			baseArea->Offset(Origin());
+			break;
+		default:
+			OwnerPanic(EWservPanicCornerParams);
+		}
+	DeleteBaseArea();
+	iCornerData=aCornerType;
+	iCornerData|=aCornerFlags;
+	iBaseArea=baseArea;
+	CalcBaseArea();
+	ScheduleRegionUpdate(NULL);
+
+	if ( aNotifyShapeChanged )
+		{
+		MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+		if (windowTreeObserver)
+			{
+			windowTreeObserver->AttributeChanged(*this, MWsWindowTreeObserver::EWindowShape);
+			}
+		}
+	}
+
+void CWsClientWindow::SetVisible(TBool aState)
+	{
+	if (aState)
+		{
+		if (iParent==NULL)
+			OwnerPanic(EWservPanicParentDeleted);
+		if (!(iFlags&EFlagInvisible))	// Already visible
+			return;
+		iFlags&=~EFlagInvisible;
+		ResetHiddenFlags();
+		}
+	else
+		{
+		if (iFlags&EFlagInvisible || !iParent)	// Already invisible or parent has been deleted
+			return;
+		TWalkWindowTreePurgeEvents wwt;
+		WalkWindowTree(wwt,EWalkChildren);		// Destroy all events on this and all children
+		iFlags|=EFlagInvisible;
+		ResetHiddenFlags();
+		}
+	
+	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+	if (windowTreeObserver)
+		{
+		windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EVisible, aState);
+		}
+	}
+
+void CWsClientWindow::CommandL(TInt aOpcode, const TAny *aCmdData)
+	{
+#ifdef _DEBUG
+	// Save root window for performing CheckTree at the end of this func.
+	// When aOpcode is EWsWinOpFree, this object would've been destroyed
+	// and a call to RootWindow() in that case would be impossible
+	CWsRootWindow* rootWindow=RootWindow();
+#endif
+	TWsWinCmdUnion pData;
+	pData.any=aCmdData;
+	if (CWsWindowBase::CommandL(aOpcode,pData)==EFalse)
+		{
+		switch(aOpcode)
+			{
+			case EWsWinOpActivate:
+				Activate();
+				break;
+			case EWsWinOpSetPos:
+				SetExtentL(pData.pos,NULL);
+				break;
+			case EWsWinOpSetExtent:
+			case EWsWinOpSetExtentErr:
+				SetExtentL(&pData.SetEx->pos,&pData.SetEx->size);
+				break;
+			case EWsWinOpSetSize:
+			case EWsWinOpSetSizeErr:
+				SetExtentL(NULL,pData.size);
+				break;
+			case EWsWinOpInquireOffset:
+				CWsClient::ReplyPoint(InquireOffset(*pData.UInt));
+				break;
+			case EWsWinOpPosition:
+				CWsClient::ReplyPoint(iRel.iTl);
+				break; 
+			case EWsWinOpAbsPosition:
+				CWsClient::ReplyPoint(iOrigin);
+				break;
+			case EWsWinOpSize:
+				CWsClient::ReplySize(iRel.Size());
+				break;
+			case EWsWinOpTestInvariant:
+				SetReply(EFalse);
+				break;
+			case EWsWinOpPointerFilter:
+				{
+				TUint old=iPointerFilter;
+				iPointerFilter&=~pData.PointerFilter->mask;
+				iPointerFilter|=pData.PointerFilter->mask&pData.PointerFilter->flags;
+				if (old&EPointerFilterEnterExit)
+					TWsPointer::ReLogWindow(this);
+				}
+				break;
+			case EWsWinOpSetPointerGrab:
+				if (*pData.Bool==EFalse)
+					iFlags&=~EFlagPointerGrab;
+				else
+					iFlags|=EFlagPointerGrab;
+				break;
+			case EWsWinOpClaimPointerGrab:
+				{
+				if (!iParent)
+					OwnerPanic(EWservPanicParentDeleted);		
+				
+				TInt errNo = TWsPointer::ClaimGrab(this,*pData.GrabControl);
+				if(TWsWinCmdGrabControl::ESendReply & pData.GrabControl->flags)
+					{
+					// To avoid the reply-generated-flush, only do this for the new APIs, not the old ones.					
+					SetReply(errNo);
+					}
+				}
+				break;
+			case EWsWinOpSetPointerCapture:
+				iFlags&=~(EFlagPointerCaptured|EFlagPointerCaptureDragDrop|EFlagPointerCaptureAllGroups);
+				if ((*pData.UInt)&RWindowBase::TCaptureFlagEnabled)
+					{
+					iFlags|=EFlagPointerCaptured;
+					if ((*pData.UInt)&RWindowBase::TCaptureFlagDragDrop)
+						iFlags|=EFlagPointerCaptureDragDrop;
+					if ((*pData.UInt)&RWindowBase::TCaptureFlagAllGroups)
+						iFlags|=EFlagPointerCaptureAllGroups;
+					
+					}
+				TWsPointer::ReLogPointersCurrentWindows();
+				break;
+			case EWsWinOpSetPointerCapturePriority:
+				iPointerCapturePriority=*pData.Int;
+				break;
+			case EWsWinOpGetPointerCapturePriority:
+				SetReply(iPointerCapturePriority);
+				break;
+			case EWsWinOpSetVisible:
+				SetVisible(*pData.Bool);
+				break;
+			case EWsWinOpScroll:
+				{
+				TPoint origin(0,0);
+				TRect src(TRect(origin,iRel.Size()));
+				src.Move(-pData.ScrollRect->offset);
+				Scroll(TRect(origin,iRel.Size()),pData.ScrollRect->offset,src);
+				}
+				break;
+			case EWsWinOpScrollClip:
+				{
+				TPoint origin(0,0);
+				TRect src(TRect(origin,iRel.Size()));
+				src.Move(-pData.ScrollRect->offset);
+				TRect clip(pData.ScrollRect->clip);
+				Scroll(clip,pData.ScrollRect->offset,src);
+				}
+				break;
+			case EWsWinOpScrollRect:
+				{
+				TRect src(pData.ScrollRect->rect);
+				Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src);
+				}
+				break;
+			case EWsWinOpScrollClipRect:
+				{
+				TRect src(pData.ScrollRect->rect);
+				TRect clip(pData.ScrollRect->clip);
+				Scroll(clip, pData.ScrollRect->offset,src);
+				}
+				break;
+			case EWsWinOpSetOrdinalPositionPri:
+				iOrdinalPriority=pData.OrdinalPos->ordinalPriority;
+				SetOrdinalPosition(pData.OrdinalPos->pos);
+				break;
+			case EWsWinOpSetShadowHeight:
+				OwnerPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client
+				break;
+			case EWsWinOpShadowDisabled:
+				OwnerPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client
+				break;
+			case EWsWinOpRequiredDisplayMode:
+				if (Backup()!=NULL)
+					OwnerPanic(EWservPanicBackupDisplayMode);
+				SetReply(SetRequiredDisplayModeL(*pData.DisplayMode));
+				break;
+			case EWsWinOpGetDisplayMode:
+				SetReply(DisplayMode());
+				break;
+			case EWsWinOpRequestPointerRepeatEvent:
+				{
+				if (!iParent)
+					OwnerPanic(EWservPanicParentDeleted);
+				TInt errNo = TWsPointer::RequestPointerRepeatEvent(this,*pData.RequestPointerRepeatEvent);				
+				if(TWsWinCmdRequestPointerRepeatEvent::ERepeatFlagsSendReply & pData.RequestPointerRepeatEvent->repeatFlags)
+					{
+					SetReply(errNo);
+					}
+				}
+				break;
+			case EWsWinOpCancelPointerRepeatEventRequest:
+				{
+				TInt errNo = TWsPointer::CancelPointerRepeatEventRequest(*pData.CancelPointerRepeatEventRequest);				
+				if(TWsWinCmdCancelPointerRepeatEventRequest::ECancelRepeatFlagsSendReply & pData.RequestPointerRepeatEvent->repeatFlags)
+					{
+					SetReply(errNo);
+					}
+				}
+				break;
+			case EWsWinOpAllocPointerMoveBuffer:
+				CWsPointerBuffer::ConnectL(this,pData.AllocPointerMoveBuffer->maxNumPoints,pData.AllocPointerMoveBuffer->flags);
+				iFlags|=EFlagUsingPointerBuffer|EFlagHasPointerBuffer;
+				break;
+			case EWsWinOpFreePointerMoveBuffer:
+				CWsPointerBuffer::Disconnect(this);
+				iFlags&=~(EFlagUsingPointerBuffer|EFlagHasPointerBuffer);
+				break;
+			case EWsWinOpRetrievePointerMoveBuffer:
+				CWsPointerBuffer::RetrievePointerMoveBuffer(this,*pData.Int);
+				break;
+			case EWsWinOpEnablePointerMoveBuffer:
+				if (!(iFlags&EFlagHasPointerBuffer))
+					OwnerPanic(EWservPanicNoPointerBuffer);
+				iFlags|=EFlagUsingPointerBuffer;
+				break;
+			case EWsWinOpDisablePointerMoveBuffer: 
+				iFlags&=~EFlagUsingPointerBuffer; 
+				/*Fall Through*/
+			case EWsWinOpDiscardPointerMoveBuffer:	
+				CWsPointerBuffer::DiscardPointerMoveBuffer(this);
+				break;
+			case EWsWinOpAddKeyRect:
+				AddKeyRectL(pData.AddKeyRect->rect, pData.AddKeyRect->scanCode, pData.AddKeyRect->activatedByPointerSwitchOn);
+				break;
+			case EWsWinOpRemoveAllKeyRects:
+				RemoveAllKeyRects();
+				break;
+			case EWsWinOpPasswordWindow:
+				if (!iParent)
+					OwnerPanic(EWservPanicParentDeleted);
+				CWsPassword::SetPasswordWindowL(this, *pData.PasswordMode);
+				break;
+			case EWsWinOpEnableBackup:
+				if (!iParent)
+					OwnerPanic(EWservPanicParentDeleted);
+				if (*pData.UInt==0)
+					iBackupsRequested|=EWindowBackupAreaBehind;		//For backwards compatibility
+				else
+					iBackupsRequested|=*pData.UInt;
+				break;
+			case EWsWinOpFadeBehind:
+				{
+				if (!iParent)
+					OwnerPanic(EWservPanicParentDeleted);
+				
+				TUint8 blackMap;
+				TUint8 whiteMap;
+				iScreen->GetFadingParams(blackMap,whiteMap);
+				SetFadeBehind(*pData.Bool);
+				TWalkWindowTreeSetFaded wwt(*pData.Bool,this,blackMap,whiteMap);
+				WalkWindowTree(wwt,EWalkBehind);
+				}
+				break;
+			case EWsWinOpGetIsFaded:
+				SetReply(iFadeCount);
+				break;
+			case EWsWinOpGetIsNonFading:
+				SetReply(iFlags&EFlagNonFadingWindow);
+				break;
+			case EWsWinOpMoveToGroup:
+				if (!iParent)
+					OwnerPanic(EWservPanicParentDeleted);
+				if (iParent->WinType()!=EWinTypeGroup)
+					OwnerPanic(EWservPanicNotTopClient);
+				((CWsTopClientWindow*)this)->DoMoveWindowL(*pData.Int);
+				break;
+			case EWsWinOpTestLowPriorityRedraw:
+				{
+				// This is purely for testing purposes
+				// Returns the redraw priority
+				TUint priority=0;
+				TPckgBuf<TUint> priBuf;
+				priority=WsOwner()->RedrawQueue()->RedrawPriority((CWsWindowRedraw*)this->iRedraw);
+				priBuf()=priority;
+				CWsClient::ReplyBuf(priBuf);
+				}
+				break;
+			case EWsWinOpEnableVisibilityChangeEvents:
+				iFlags |= EFlagGeneratesVisibilityEvents;
+				SetupVisibleRegionTracking(ETrue);
+				if (iFlags&EFlagActive)
+					{
+					iScreen->DoRedrawNow();
+					PossibleVisibilityChangedEvent(ETrue);
+					}
+				break;
+			case EWsWinOpDisableVisibilityChangeEvents:
+				iFlags &= ~EFlagGeneratesVisibilityEvents;
+				SetupVisibleRegionTracking(EFalse);
+				break;
+			case EWsWinOpSetTransparentRegion:
+				{
+				if (IsTranslucent())
+					{
+					TInt recs=*pData.Int;
+	 				RWsRegion* reg=recs>0? GetRegionFromClientL(iWsOwner,recs) : new(ELeave) RWsRegion;
+	 				SetUserTransparentRegion(reg);
+					SetReply(KErrNone);
+					}
+				else
+					{
+					OwnerPanic(EWservPanicTransparencyObjNotCreated);	
+					}				
+				}
+				break;
+			case EWsWinOpSetTransparencyPolicy:
+				{
+				if (IsTranslucent())
+					SetReply(KErrNone);
+				else
+					OwnerPanic(EWservPanicTransparencyObjNotCreated);
+				}
+				break;
+			case EWsWinOpSetTransparencyAlphaChannel:
+				{
+				iFlags |= static_cast<TUint>(EFlagHasAlpha);
+				SetReply(KErrNone);
+				
+				MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+				if (windowTreeObserver)
+					{
+					windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EAlphaChannelTransparencyEnabled, ETrue);
+					}
+				break;
+				}			
+			default:
+				if (iRedraw->CommandL(aOpcode,pData)==EFalse)
+					{
+					OwnerPanic(EWservPanicOpcode);
+					}
+			}
+		}
+#if defined(_DEBUG)
+	rootWindow->CheckTree();
+#endif
+	}
+
+void CWsClientWindow::GcActivated(CWsGc *aGc)
+	{
+	aGc->SetNextWinGc(iWinGcList);
+	iWinGcList=aGc;
+	}
+
+void CWsClientWindow::GcDeactivated(CWsGc *aGc)
+	{
+	if (aGc==iWinGcList)
+		iWinGcList=aGc->NextWinGc();
+	else
+		{
+		CWsGc *gc=iWinGcList;
+		CWsGc *next;
+		FOREVER
+			{
+			next=gc->NextWinGc();
+			WS_ASSERT_DEBUG(next!=NULL, EWsPanicBadActiveGcList);
+			if (next==aGc)
+				{
+				gc->SetNextWinGc(next->NextWinGc());
+				break;
+				}
+			gc=next;
+			}
+		}
+	aGc->SetNextWinGc(NULL);
+	}
+
+void CWsClientWindow::ReactivateGcs()
+	{
+	for (CWsGc * gc = iWinGcList; gc; gc = gc->NextWinGc())
+		{
+		gc->Reactivate();
+		}
+	}
+
+void CWsClientWindow::OffsetUserTransparentRegion(const TPoint& aOffset)
+	{
+	if (iUserDefinedTransparentRegion)
+		{
+		iUserDefinedTransparentRegion->Offset(aOffset);
+		}	
+	}
+
+void CWsClientWindow::SetUserTransparentRegion(RWsRegion* aRegion)
+	{
+	if (iUserDefinedTransparentRegion)
+		{
+		iUserDefinedTransparentRegion->Close();
+		delete iUserDefinedTransparentRegion;
+		iUserDefinedTransparentRegion = 0;
+		}
+		
+	if (aRegion)
+		{		
+		aRegion->Offset(iOrigin);
+		iUserDefinedTransparentRegion=aRegion;
+		}
+		
+	SetUserOpaqueRegion();
+	}
+
+void CWsClientWindow::SetUserOpaqueRegion()
+	{
+	if (iUserDefinedOpaqueRegion)
+		{
+		iUserDefinedOpaqueRegion->Close();
+		delete iUserDefinedOpaqueRegion;
+		iUserDefinedOpaqueRegion = 0;
+		}
+	if (iUserDefinedTransparentRegion)
+		{
+		iUserDefinedOpaqueRegion=new RWsRegion;
+		if (iUserDefinedOpaqueRegion)
+			{
+			iUserDefinedOpaqueRegion->Copy(*iBaseArea);
+			iUserDefinedOpaqueRegion->SubRegion(*iUserDefinedTransparentRegion);
+			if (iUserDefinedOpaqueRegion->CheckError() || iUserDefinedOpaqueRegion->Count() == 0)
+				{
+				iUserDefinedOpaqueRegion->Close();
+				delete iUserDefinedOpaqueRegion;
+				iUserDefinedOpaqueRegion = 0;
+				}
+			}
+		// Intentionally not sending this notification during destruction (when SetUserTransparentRegion is called from d'tor)
+		MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+		if (windowTreeObserver)
+			{
+			windowTreeObserver->TransparentRegionChanged(*this, *iUserDefinedTransparentRegion, iUserDefinedOpaqueRegion);
+			}
+		}
+	}
+
+/** Checks whether this window is in front of aWin.
+
+@param aWin A window.
+@return EFalse if aWin is the same or is in front of this, ETrue otherwise.
+@internalComponent
+* released
+*/	
+TBool CWsClientWindow::IsInfrontOf(const CWsWindowBase* aWin) const
+	{
+	TInt thisDepth=Depth();
+	TInt otherDepth=aWin->Depth();
+	const CWsWindowBase *thisWin=this;
+	const CWsWindowBase *otherWin=aWin;
+	if (thisDepth>otherDepth)
+		{
+		for (TInt count=thisDepth-otherDepth;count>0;count--)
+			thisWin=thisWin->BaseParent();
+		}
+	else
+		{
+		for (TInt count=otherDepth-thisDepth;count>0;count--)
+			otherWin=otherWin->BaseParent();
+		}
+	if (thisWin==otherWin)
+		return thisDepth>otherDepth;
+	while(thisWin->BaseParent()!=otherWin->BaseParent())
+		{
+		thisWin=thisWin->BaseParent();
+		otherWin=otherWin->BaseParent();
+		}
+	const CWsWindowBase *win=thisWin->BaseParent()->BaseChild();
+	FOREVER
+		{
+		if (win==otherWin)
+			{
+			return EFalse;
+			}
+		if (win==thisWin)
+			return ETrue;
+		win=win->NextSibling();
+		}
+	}
+	
+CWsTopClientWindow* CWsClientWindow::TopClientWindow()
+	{
+	if (iParent==NULL)
+		OwnerPanic(EWservPanicParentDeleted);
+	CWsWindowBase* win=this;
+	while(win->BaseParent()->WinType()!=EWinTypeGroup)
+		win=win->BaseParent();
+	return static_cast<CWsTopClientWindow*>(win);
+	}
+
+const TRegion &CWsClientWindow::InvalidArea() const
+	{
+	return(iRedraw->InvalidArea());
+	}
+
+
+TUint CWsClientWindow::RedrawPriority(TInt *aShift) const
+	{
+	TUint ordinalPos=OrdinalPosition(EFalse)+1;
+	if (ordinalPos>15)	// Algorithm only works upto 15 , make all windows after 15 equal in priority
+		ordinalPos=15;
+	TInt shift;
+	TUint parent=((CWsClientWindow *)iParent)->RedrawPriority(&shift);
+	if (shift>0)
+		shift--;
+	if (aShift)
+		*aShift=shift;
+	return(parent+(ordinalPos<<(shift*KWinRedrawPriBitsPerLevel)));
+	}
+
+TDblQue<TPointerKeyList> *CWsClientWindow::PointerKeyList() const
+	{
+	return(iPointerKeyList);
+	}
+
+void CWsClientWindow::AddKeyRectL(const TRect &aRect, TInt aScanCode, TBool aActivatedByPointerSwitchOn)
+	{
+	if (!iPointerKeyList)
+		iPointerKeyList=new(ELeave) TDblQue<TPointerKeyList>(_FOFF(TPointerKeyList,iQue));
+	TPointerKeyList *pkl=new(ELeave) TPointerKeyList();
+	iPointerKeyList->AddLast(*pkl);
+	pkl->iRect=aRect;
+	pkl->iScanCode=aScanCode;
+	pkl->iActivatedByPointerSwitchOn=aActivatedByPointerSwitchOn;
+	}
+
+void CWsClientWindow::RemoveAllKeyRects()
+	{
+	if (iPointerKeyList)
+		{
+		TPointerKeyList *pkl=NULL;
+		for(TDblQueIter<TPointerKeyList> iter(*iPointerKeyList);(pkl=iter++)!=NULL;)
+			{
+			pkl->iQue.Deque();
+			delete pkl;
+			}
+		delete iPointerKeyList;
+		iPointerKeyList=NULL;
+		}
+	}
+
+TBool CWsClientWindow::IsHidden()
+	{
+	return (!IsVisible()) || VisibleRegion().IsEmpty();
+	}
+
+void CWsClientWindow::SetFaded(TBool aFade, TUint8 aBlackMap, TUint8 aWhiteMap, TBool aNotifyObserver)
+	{
+	TBool stateChanged;
+	SetFaded(aFade, aBlackMap, aWhiteMap, aNotifyObserver, stateChanged);
+	}
+
+void CWsClientWindow::SetFaded(TBool aFade, TUint8 aBlackMap, TUint8 aWhiteMap, TBool aNotifyObserver, TBool& aStateChanged)
+	{
+	iBlackMap=aBlackMap;
+	iWhiteMap=aWhiteMap;
+	const TBool mapAltered = (iBlackMap != aBlackMap) || (iWhiteMap != aWhiteMap); 
+	const TInt oldFadeCount = iFadeCount;
+
+	if (iAbsoluteFading) 
+		{ 
+		if (aFade) 
+			{ 
+			iFadeCount = 1; 
+			} 
+		else 
+			{ 
+			iFadeCount = 0; 
+			} 
+		} 
+	else 
+		{ 
+		if (aFade) 
+			{ 
+			++iFadeCount; 
+			} 
+		else if (iFadeCount > 0) 
+			{ 
+			--iFadeCount; 
+			} 
+		}
+	
+	//Fade state only changes when iFadeCount transitions from 0 to 1 or from 1 to 0.
+ 	aStateChanged = (iFadeCount==0 || oldFadeCount==0) && (oldFadeCount != iFadeCount);
+ 	if (!Screen()->ChangeTracking() && CWsTop::IsFadeEnabled() && (aStateChanged || mapAltered) ) 
+ 		{
+ 		Screen()->AcceptFadeRequest(this, (iFadeCount > 0));
+ 		}
+
+	const TBool doNotify = iAbsoluteFading ? aStateChanged : (oldFadeCount != iFadeCount);
+	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
+	if (windowTreeObserver && aNotifyObserver && doNotify)
+		{
+		windowTreeObserver->FadeCountChanged(*this, iFadeCount);
+		}	
+	}
+
+void CWsClientWindow::ResetHiddenFlagsInParentAndChildren()
+	{
+	ResetHiddenFlag();
+	SetElementOpacity(IsVisible() ? 0xFF : 0x00);	// Update element visibility
+	for(CWsClientWindow* child=Child();child;child=child->NextSibling())
+		{
+		child->ResetHiddenFlagsInParentAndChildren();
+		}
+	}
+
+const TRegion& CWsClientWindow::WindowArea() const
+	{
+	WS_ASSERT_DEBUG(iBaseArea, EWsPanicRegionNull);
+	return *iBaseArea;
+	}
+
+void CWsClientWindow::Invalidate(const TRect * aRect)
+	{
+	iRedraw->Invalidate(aRect);
+	}
+
+void CWsClientWindow::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty)
+	{
+	if (IsVisible())
+		{
+		iScreen->ScheduleRegionUpdate(aDefinitelyDirty);
+		}
+	}
+
+void CWsClientWindow::AddRedrawRegion(const TRegion& aRegion, TBool aSchedule, TRedrawDepth aDepth)
+	{
+	if (!IsHidden())
+		{
+		iScreen->AddRedrawRegion(aRegion, aSchedule, aDepth);
+		}
+	}
+
+void CWsClientWindow::SendState(MWsWindowTreeObserver& aWindowTreeObserver) const
+	{	
+	CWsWindow::SendState(aWindowTreeObserver);
+	
+	if(iFadeCount > 0)
+		{
+		aWindowTreeObserver.FadeCountChanged(*this, iFadeCount);
+		}
+	
+	if(iUserDefinedTransparentRegion)
+		{
+		aWindowTreeObserver.TransparentRegionChanged(*this, *iUserDefinedTransparentRegion, iUserDefinedOpaqueRegion);
+		}
+
+	if(HasElement())
+		{
+		CWindowElementSet& windowElementSet = Screen()->WindowElements();
+		const TBackgroundAttributes		*bElementAttr;
+		const RArray<TPlacedAttributes>	*pElementsAttr;
+		
+		TInt ret = windowElementSet.FindElements(*this, bElementAttr, pElementsAttr);
+		if(ret == KErrNone)
+			{
+			MWsElement* element = bElementAttr->iElement;
+			if (element)
+				aWindowTreeObserver.ElementAdded(*this, *element);
+			}
+		}
+	
+	}
+
+TBool CWsClientWindow::IsDSAHost() const
+	{
+	TBool res = CWsWindow::IsDSAHost();
+	if ( !res )
+		{ // check for grace period when DSA is being restarted (after aborting but before client started DSA again)
+		res = Screen()->IsDSAClientWindow( this );
+		}
+	return res;
+	}
+
+void CWsClientWindow::UpdateElementExtent(const TPoint* aOffset)
+	{
+	if (Redraw()->HasElement())
+		{
+		Screen()->WindowElements().UpdateElementExtent(*this, aOffset);
+		}
+	}
+
+void CWsClientWindow::SetElementOpacity(TInt aOpacity)
+	{
+	if (Redraw()->HasElement())
+		{
+		Screen()->WindowElements().SetElementOpacity(*this,aOpacity);
+
+		} 
+	}
+
+TRect CWsClientWindow::GetOriginalSrcElementRect() const
+    {
+    return iOriginalSrcElementRect;
+    }
+TRect CWsClientWindow::GetOriginalDestElementRect() const
+    {
+    return iOriginalDestElementRect;
+    }
+    
+//
+// Code for CWsTopClientWindow, a client window that connects to a group window //
+//
+
+CWsTopClientWindow::CWsTopClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsClientWindow(aOwner, aScreen)
+	{
+	}
+
+void CWsTopClientWindow::ConstructL(const TWsClCmdCreateWindow &cmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid)
+	{
+	iFlags|=EFlagIsTopClientWindow;
+	CWsClientWindow::ConstructL(cmd, aParent, aScreenDeviceIsInvalid);
+	}
+
+void CWsTopClientWindow::SetInactive()
+	{
+	iFlags&=~EFlagActive;
+	ResetHiddenFlags();
+	}
+
+void CWsTopClientWindow::SetScreenDeviceValidState(TBool aState)
+	{
+	if (SetScreenDeviceValidStateFlag(aState))
+		ResetHiddenFlags();
+	}
+
+TBool CWsTopClientWindow::SetScreenDeviceValidStateFlag(TBool aState)
+	{
+	TBool isSet=iFlags&EFlagScreenDeviceInvalid;
+	if (!isSet==!aState)
+		{
+		if (aState)
+			iFlags&=~EFlagScreenDeviceInvalid;
+		else
+			iFlags|=EFlagScreenDeviceInvalid;
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+void CWsTopClientWindow::SetOrdinalPosition(TInt aPos)
+	{
+	if (!iParent)
+		{
+		OwnerPanic(EWservPanicParentDeleted);
+		}
+	if (CheckOrdinalPositionChange(aPos))
+		{
+		CWsWindowBase::SetOrdinalPosition(aPos);
+		CWsTop::TriggerRedraws(RootWindow());
+		}
+	}
+
+void CWsTopClientWindow::DoMoveWindowL(TInt aIdentifier)
+	{
+	CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(aIdentifier);
+	if (group==iParent)
+		return;
+	if (group->WsOwner()!=WsOwner())
+		User::Leave(KErrNotFound);
+	ChangeWindowPosition(0, group);
+	CWsTop::TriggerRedraws(RootWindow());
+	}
+
+TUint CWsTopClientWindow::RedrawPriority(TInt *aShift) const
+	{
+	TUint ordinalPos=OrdinalPosition(EFalse);
+	if (ordinalPos>KWinRedrawPriMaxOrdinal)	// Algorithm only works for upto KWinRedrawPriMaxOrdinal windows,
+		ordinalPos=KWinRedrawPriMaxOrdinal;	// make all windows after this equal in priority
+	if (aShift)
+		*aShift=KWinRedrawPriMaxLevel;
+	return(ordinalPos<<(KWinRedrawPriMaxLevel*KWinRedrawPriBitsPerLevel));
+	}
+