os/graphics/windowing/windowserver/nga/SERVER/openwfc/WINBASE.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Window virtual base class, windows and window groups are derived from this
    15 // 
    16 //
    17 
    18 #include <e32std.h>
    19 #include "server.h"
    20 #include "winbase.h"
    21 #include "rootwin.h"
    22 #include "windowgroup.h"
    23 #include "walkwindowtree.h"
    24 #include "wstop.h"
    25 #include "EVQUEUE.H"
    26 #include "EVENT.H"
    27 #include "panics.h"
    28 #include "pointer.h"
    29 #include "windowelementset.h"
    30 
    31 CWsWindowBase::CWsWindowBase(CWsClient* aOwner,WH_HANDLES aType, CScreen* aScreen) : CWsScreenObject(aOwner,aType,aScreen)		
    32 	{
    33 	}
    34 
    35 void CWsWindowBase::ConstructL(CWsWindowBase *aParent)
    36 	{
    37 	iParent=aParent;
    38 	iSibling=aParent->iChild;
    39 	aParent->iChild=this;
    40 	CScreen* screen = aParent->Screen();
    41 	WS_ASSERT_DEBUG(screen,EWsPanicNoScreen);
    42 	MWsWindowTreeObserver* const windowTreeObserver = screen->WindowTreeObserver();
    43 	if (windowTreeObserver)
    44 		{
    45 		windowTreeObserver->NodeCreated(*this, ParentNode());
    46 		iBaseWinFlags |= EBaseWinNodeCreated;
    47 		}
    48 	SetOrdinalPosition(0);
    49 	iFadeCount = iParent->iFadeCount;
    50 	}
    51 
    52 CWsWindowBase *CWsWindowBase::GetPrevSibling() const
    53 	{
    54 	if(iParent == NULL) //RootWindow
    55 		return(NULL);
    56 	
    57 	CWsWindowBase* prev=iParent->iChild;
    58 	CWsWindowBase *ret=NULL;
    59 	while (prev!=this)
    60 		{
    61 		ret=prev;
    62 		prev=prev->iSibling;
    63 		}
    64 	return(ret);
    65 	}
    66 
    67 CWsWindowBase *CWsWindowBase::LastSibling() const
    68 	{
    69 	const CWsWindowBase *win;
    70 	for(win=this;win->iSibling;win=win->iSibling)
    71 		{}
    72 	return (CWsWindowBase*)win;
    73 	}
    74 
    75 CWsWindowBase *CWsWindowBase::PrevSiblingMultiParent() const
    76 	{
    77 	CWsWindowBase *win=GetPrevSibling();
    78 	if (win)
    79 		return(win);
    80 	for(CWsWindowBase *parent=iParent->GetPrevSibling();parent;parent=parent->GetPrevSibling())
    81 		if ((win=parent->iChild)!=NULL)
    82 			return(win->LastSibling());
    83 	return(NULL);
    84 	}
    85 
    86 CWsWindowBase *CWsWindowBase::NextSiblingMultiParent() const
    87 	{
    88 	if (iSibling)
    89 		return(iSibling);
    90 	for(CWsWindowBase *parent=iParent->iSibling;parent;parent=parent->iSibling)
    91 		{
    92 		if (parent->iChild!=NULL)
    93 			return(parent->iChild);
    94 		}
    95 	return(NULL);
    96 	}
    97 
    98 TInt CWsWindowBase::OrdinalPosition(TBool aFull) const
    99 	{
   100 	if (!iParent)
   101 		{
   102 		OwnerPanic(EWservPanicParentDeleted);
   103 		}
   104 	CWsWindowBase *win=iParent->iChild;
   105 	if (!aFull)
   106 		while(iOrdinalPriority<win->iOrdinalPriority)
   107 			win=win->iSibling;
   108 	TInt count;
   109 	for(count=0;win!=this;count++)
   110 		win=win->iSibling;
   111 	return(count);
   112 	}
   113 
   114 /** Removes a window from the list of siblings maintained by its parent window.
   115 
   116 The iSibling stored inside the window we remove is kept unchanged as it may be needed later.
   117 
   118 @internalComponent
   119 @released
   120 */
   121 void CWsWindowBase::RemoveFromSiblingList()
   122 	{
   123 	if (iParent!=NULL)
   124 		{
   125 		CWsWindowBase **prev= &iParent->iChild;
   126 		while ((*prev)!=this)
   127 			prev= &(*prev)->iSibling;
   128 		*prev=iSibling;
   129 		}
   130 	}
   131 
   132 CWsWindowGroup *CWsWindowBase::WinGroup() const
   133 	{
   134 	if (iWinType==EWinTypeClient)
   135 		return(((CWsClientWindow *)this)->TopClientWindow()->Parent());
   136 	if (iWinType==EWinTypeGroup)
   137 		return((CWsWindowGroup *)this);
   138 	return(NULL);
   139 	}
   140 
   141 TBool CWsWindowBase::CheckOrdinalPositionChange(TInt aPos)
   142 //
   143 // This routine checks to see whether the specified new ordinal position
   144 // will causes a change, if so returns ETrue else EFalse.
   145 //
   146 	{
   147 	CWsWindowBase *win= iParent->iChild;
   148 	CWsWindowBase *prev= NULL;
   149 	while(win==this || (win!=NULL && iOrdinalPriority<win->iOrdinalPriority))
   150 		{
   151 		prev=win;
   152 		win=win->iSibling;
   153 		}
   154 	if (prev==this)
   155 		win=this;
   156 	else if (win==NULL || (win->iSibling==this && iOrdinalPriority>win->iOrdinalPriority))
   157 		return ETrue;
   158 	while(aPos--!=0 && win->iSibling!=NULL && iOrdinalPriority==win->iSibling->iOrdinalPriority)
   159 		win=win->iSibling;
   160 	return(win!=this);
   161 	}
   162 
   163 void CWsWindowBase::ChangeWindowPosition(TInt aPos,CWsWindowBase* aNewParent)
   164 	{
   165 	TBool changedWindowGroup = EFalse;
   166 	WS_ASSERT_DEBUG(aNewParent,EWsPanicWindowNull);
   167 	if (aNewParent != iParent)
   168 		{
   169 		iScreen->ScheduleRegionUpdate(NULL);		
   170 		TWalkWindowTreeScheduleRedraws wwt;
   171 		WalkWindowTree(wwt, EWalkChildren);
   172 		changedWindowGroup = ETrue;
   173 		}
   174 	else if (WinType() == EWinTypeClient)
   175 		{
   176 		CWsClientWindow * cliwin = static_cast<CWsClientWindow*>(this);
   177 		if (cliwin->IsVisible())
   178 			{
   179 			iScreen->ScheduleRegionUpdate(NULL);
   180 			if (cliwin->IsTranslucent())
   181 				{
   182 				// There is still room for optimization here.  These redraws are only required if the window
   183 				// moved through another window and BOTH of them were transparent, otherwise the visible
   184 				// region change will sort out the redraws required.
   185 				TWalkWindowTreeScheduleRedraws wwt;
   186 				WalkWindowTree(wwt, EWalkChildren);
   187 				}
   188 			}
   189 		}
   190 	else if (WinType() == EWinTypeGroup)
   191 		{
   192 		iScreen->ScheduleRegionUpdate(NULL);
   193 		if (static_cast<CWsWindowGroup*>(this)->HasVisibleTranslucentChild())
   194 			{
   195 			TWalkWindowTreeScheduleRedraws wwt;
   196 			WalkWindowTree(wwt, EWalkChildren);				
   197 			}
   198 		}
   199 
   200 	RemoveFromSiblingList();
   201 	CWsWindowBase **prevWinPtr= &aNewParent->iChild;
   202 	while((*prevWinPtr)!=NULL && iOrdinalPriority<(*prevWinPtr)->iOrdinalPriority)
   203 		{
   204 		prevWinPtr= &(*prevWinPtr)->iSibling;
   205 		}
   206 	while(aPos--!=0 && *prevWinPtr!=NULL && iOrdinalPriority==(*prevWinPtr)->iOrdinalPriority)
   207 		{
   208 		prevWinPtr= &(*prevWinPtr)->iSibling;
   209 		}
   210 	iSibling=*prevWinPtr;
   211 	iParent=aNewParent;
   212 	*prevWinPtr=this;
   213 
   214 	Screen()->WindowElements().SortByZOrder();
   215 
   216 	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
   217 	if (windowTreeObserver)
   218 		{
   219 		if(changedWindowGroup && (WinType() == EWinTypeClient))
   220 			{
   221 			windowTreeObserver->MovedToWindowGroup(*this, *(this->WinGroup()));
   222 			}
   223 		else if(!changedWindowGroup)
   224 			{
   225 			windowTreeObserver->SiblingOrderChanged(*this, OrdinalPosition(ETrue));
   226 			}
   227 		else if(changedWindowGroup)
   228 			{
   229 			OwnerPanic(EWservPanicInvalidParameter); //Should be impossible to end up here as only WinType() EWinTypeClient 
   230 			}										 //and EWinTypeGroup can be moved to another windowgroup.
   231 		}											 //@see RWindowBase::MoveToGroup
   232 	}
   233 
   234 void CWsWindowBase::SetOrdinalPosition(TInt aPos)
   235 	{
   236 	if (CheckOrdinalPositionChange(aPos))
   237 		ChangeWindowPosition(aPos,iParent);
   238 	}
   239 
   240 TEventQueueWalkRet EventPurgeFunc(TAny *aPtr, TWsEvent *aEvent)
   241 //
   242 // Callback function for event queue walk
   243 //
   244 	{
   245 	return(((CWsWindowBase *)aPtr)->EventPurgeCheck(aEvent));
   246 	}
   247 
   248 TEventQueueWalkRet CWsWindowBase::EventPurgeCheck(TWsEvent *aEvent)
   249 	{
   250 	if (aEvent->Handle()==ClientHandle())
   251 		return(EEventQueueWalkDeleteEvent);
   252 	return(EEventQueueWalkOk);
   253 	}
   254 
   255 void CWsWindowBase::PurgeEvents()
   256 	{
   257 	iWsOwner->EventQueue()->WalkEventQueue(&EventPurgeFunc,this);
   258 	}
   259 
   260 void CWsWindowBase::Shutdown()
   261 //
   262 // Destroy a window, disconnects from the window tree and destroys all it's child windows
   263 //
   264 	{
   265 	if (iWsOwner!=NULL)
   266 		PurgeEvents();
   267 	if (iParent!=NULL)	// Check it's connected to something
   268 		{
   269 		CWsWindowBase *win;
   270 		for(win=this;win && win->iParent!=(CWsWindowBase *)RootWindow();win=win->iParent)
   271 			{}
   272 		RemoveFromSiblingList();
   273 		TWalkWindowTreeDisconnect wwt2(win ? ((CWsWindowGroup *)win)->TextCursor() : NULL);
   274 		WalkWindowTree(wwt2,EWalkChildren); // Disconnect all child windows
   275 		iChild=NULL;
   276 		}
   277 	TWindowServerEvent::RemoveFromSwitchOnEventList(*this);
   278 	TWindowServerEvent::RemoveFromErrorMessageList(*this);
   279 	TWindowServerEvent::RemoveFromGroupChangeEventEventList(*this);
   280 	TWindowServerEvent::RemoveFromFocusChangeEventEventList(*this);
   281 	TWindowServerEvent::RemoveFromGroupListChangeEventEventList(*this);
   282 	TWindowServerEvent::RemoveFromModifierChangedEventList(*this);
   283 	TWindowServerEvent::RemoveFromScreenDeviceChangeEventList(*this);
   284 	CWsTop::StopWindowGettingOffEvents(this);
   285 	}
   286 
   287 TBool CWsWindowBase::CommandL(TInt aOpcode, TWsWinCmdUnion &aCmd)
   288 //
   289 // If the command is supported by the window base class process it and return ETrue
   290 // if it is not supported return EFalse
   291 //
   292 	{
   293 	switch(aOpcode)
   294 		{
   295 		case EWsWinOpFree:
   296 			{
   297 			delete this;
   298 			break;
   299 			}
   300 		case EWsWinOpSetOrdinalPosition:
   301 			SetOrdinalPosition(*aCmd.Int);
   302 			break;
   303 		case EWsWinOpOrdinalPriority:
   304 			SetReply(iOrdinalPriority);
   305 			break;
   306 		case EWsWinOpOrdinalPosition:
   307 			SetReply(OrdinalPosition(EFalse));
   308 			break;
   309 		case EWsWinOpFullOrdinalPosition:
   310 			SetReply(OrdinalPosition(ETrue));
   311 			break;
   312 		case EWsWinOpClientHandle:
   313 			SetReply(iClientHandle);
   314 			break;
   315 		case EWsWinOpParent:
   316 			if (!iParent)
   317 				{
   318 				OwnerPanic(EWservPanicParentDeleted);
   319 				}
   320 			SetReply(iParent->iClientHandle);
   321 			break;
   322 		case EWsWinOpPrevSibling:
   323 			{
   324 			if (!iParent)
   325 				{
   326 				OwnerPanic(EWservPanicParentDeleted);
   327 				}
   328 			TUint32 reply=NULL;
   329 			for(CWsWindowBase *win=this->GetPrevSibling();win;win=win->GetPrevSibling())
   330 				{
   331 				if (win->iWsOwner==iWsOwner)
   332 					{
   333 					reply=win->iClientHandle;
   334 					break;
   335 					}
   336 				}
   337 			SetReply(reply);
   338 			}
   339 			break;
   340 		case EWsWinOpNextSibling:
   341 			{
   342 			TUint32 reply=NULL;
   343 			for(CWsWindowBase *win=this->iSibling;win;win=win->iSibling)
   344 				{
   345 				if (win->iWsOwner==iWsOwner)
   346 					{
   347 					reply=win->iClientHandle;
   348 					break;
   349 					}
   350 				}
   351 			SetReply(reply);
   352 			}
   353 			break;
   354 		case EWsWinOpChild:
   355 			SetReply(iChild==NULL ? NULL : iChild->iClientHandle);
   356 			break;
   357 		case EWsWinOpScreenNumber:
   358 			SetReply(Screen()->ScreenNumber());
   359 			break;
   360 		case EWsWinOpWindowGroupId:
   361 			{
   362 			TUint32 reply=NULL;
   363 			CWsWindowGroup *wg=WinGroup();
   364 			if (wg)
   365 				{
   366 				reply=wg->Identifier();
   367 				}
   368 			SetReply(reply);
   369 			}
   370 			break;
   371 		case EWsWinOpEnableOnEvents:
   372 			{
   373 			const TEventControl circumstances = *aCmd.EventControl;
   374 			TWindowServerEvent::AddToSwitchOnEventListL(*this, circumstances);
   375 			if (iScreen->ChangeTracking())
   376 				{
   377 				if(circumstances & EEventControlOnlyWhenVisible)
   378 					{
   379 					TWalkWindowTreeSetupVisibleRegionTracking wwt(ETrue);
   380 					WalkWindowTree(wwt, EWalkChildren);
   381 					}
   382 				}
   383 			break;
   384 			}
   385 		case EWsWinOpDisableOnEvents:
   386 			{
   387 			TWindowServerEvent::RemoveFromSwitchOnEventList(*this);
   388 			if (iScreen->ChangeTracking())
   389 				{
   390 				TWalkWindowTreeSetupVisibleRegionTracking wwt(EFalse);
   391 				WalkWindowTree(wwt, EWalkChildren);
   392 				}
   393 			break;
   394 			}
   395 		case EWsWinOpEnableErrorMessages:
   396 			{
   397 			const TEventControl circumstances = *aCmd.EventControl;
   398 			TWindowServerEvent::AddToErrorMessageListL(*this, circumstances);
   399 			if (iScreen->ChangeTracking())
   400 				{
   401 				if(circumstances & EEventControlOnlyWhenVisible)
   402 					{
   403 					TWalkWindowTreeSetupVisibleRegionTracking wwt(ETrue);
   404 					WalkWindowTree(wwt, EWalkChildren);
   405 					}
   406 				}
   407 			break;
   408 			}
   409 		case EWsWinOpDisableErrorMessages:
   410 			{
   411 			TWindowServerEvent::RemoveFromErrorMessageList(*this);
   412 			if (iScreen->ChangeTracking())
   413 				{
   414 				TWalkWindowTreeSetupVisibleRegionTracking wwt(EFalse);
   415 				WalkWindowTree(wwt, EWalkChildren);
   416 				}
   417 			break;
   418 			}
   419 		case EWsWinOpEnableModifierChangedEvents:
   420 			{
   421 			const TInt modifierMask = aCmd.EnableModifierChangedEvents->modifierMask;
   422 			const TEventControl circumstances = aCmd.EnableModifierChangedEvents->circumstances;
   423 			TWindowServerEvent::AddToModifierChangedEventListL(*this, modifierMask, circumstances);
   424 			if (iScreen->ChangeTracking())
   425 				{
   426 				if(circumstances & EEventControlOnlyWhenVisible)
   427 					{
   428 					TWalkWindowTreeSetupVisibleRegionTracking wwt(ETrue);
   429 					WalkWindowTree(wwt, EWalkChildren);
   430 					}
   431 				}
   432 			break;
   433 			}
   434 		case EWsWinOpDisableModifierChangedEvents:
   435 			{
   436 			TWindowServerEvent::RemoveFromModifierChangedEventList(*this);
   437 			if (iScreen->ChangeTracking())
   438 				{
   439 				TWalkWindowTreeSetupVisibleRegionTracking wwt(EFalse);
   440 				WalkWindowTree(wwt, EWalkChildren);
   441 				}
   442 			break;
   443 			}
   444 		case EWsWinOpEnableGroupChangeEvents:
   445 			TWindowServerEvent::AddToGroupChangeEventListL(*this);
   446 			break;
   447 		case EWsWinOpDisableGroupChangeEvents:
   448 			TWindowServerEvent::RemoveFromGroupChangeEventEventList(*this);
   449 			break;
   450 		case EWsWinOpEnableFocusChangeEvents:
   451 			TWindowServerEvent::AddToFocusChangeEventListL(*this);
   452 			break;
   453 		case EWsWinOpDisableFocusChangeEvents:
   454 			TWindowServerEvent::RemoveFromFocusChangeEventEventList(*this);
   455 			break;
   456 		case EWsWinOpEnableGroupListChangeEvents:
   457 			TWindowServerEvent::AddToGroupListChangeEventListL(*this);
   458 			break;
   459 		case EWsWinOpDisableGroupListChangeEvents:
   460 			TWindowServerEvent::RemoveFromGroupListChangeEventEventList(*this);
   461 			break;
   462 		case EWsWinOpSetCustomPointerCursor:
   463 			CWsObject *pointercursor;
   464 			if ((pointercursor=iWsOwner->HandleToObj(*aCmd.Int, WS_HANDLE_POINTER_CURSOR))==NULL)
   465 				OwnerPanic(EWservPanicSprite);
   466 			SetPointerCursor((CWsPointerCursor *)pointercursor);
   467 			break;
   468 		case EWsWinOpSetPointerCursor:
   469 			SetPointerCursorByIndex(*aCmd.UInt);
   470 			break;
   471 		case EWsWinOpClearPointerCursor:
   472 			SetPointerCursor(NULL);
   473 			break;
   474 		case EWsWinOpSetNonFading:
   475 			{
   476 			WS_ASSERT_DEBUG(iScreen, EWsPanicNoScreen);
   477 			// No fading will occur from a graphical perspective, but the fade counts
   478 			// are maintained for BC reasons.
   479 			TWalkWindowTreeSetNonFading wwt(*aCmd.Bool);
   480 			WalkWindowTree(wwt,EWalkChildren);
   481 			}
   482 			break;
   483 		case EWsWinOpSetFade:
   484 			{
   485 			WS_ASSERT_DEBUG(iScreen, EWsPanicNoScreen);
   486 			
   487 			TUint8 blackMap;
   488 			TUint8 whiteMap;
   489 			if (aCmd.SetFaded->UseDefaultMap())
   490 				{
   491 				iScreen->GetFadingParams(blackMap,whiteMap);
   492 				}
   493 			else
   494 				{
   495 				aCmd.SetFaded->GetFadingParams(blackMap,whiteMap);
   496 				}
   497 			
   498 			if (aCmd.SetFaded->IncludeChildren())
   499 				{
   500 				TWalkWindowTreeSetFaded wwt(aCmd.SetFaded->Faded(),this,blackMap,whiteMap);
   501 				WalkWindowTree(wwt,EWalkChildren);
   502 				}
   503 			else
   504 				{
   505 				if (iWinType==EWinTypeGroup)
   506 					OwnerPanic(EWservPanicOpcode);
   507 				
   508 				const TBool KNotifyObserver = ETrue; //yes please
   509 				const TBool KFaded = aCmd.SetFaded->Faded();
   510 				static_cast<CWsClientWindow*>(this)->SetFaded(KFaded, blackMap, whiteMap, KNotifyObserver); 
   511 				}
   512 			}
   513 			break;
   514 		case EWsWinOpEnableAdvancedPointers:
   515       if(!IsActivated())
   516           {
   517           // Must call this BEFORE activating the window.
   518           iBaseWinFlags |= EBaseWinAdvancedPointersEnabled;
   519           }
   520       else
   521           {                    
   522           // Called after activation, so panic the client.                
   523           OwnerPanic(EWservPanicUnableToEnableAdvPointer);
   524           }
   525 			break;
   526 		case EWsWinOpSetSurfaceTransparency:
   527 			RDebug::Printf("[Bug 3343] OpCode EWsWinOpSetSurfaceTransparency not supported.");
   528 			break;
   529 		default:
   530 			return(EFalse);
   531 		}
   532 	return(ETrue);
   533 	}
   534 
   535 /** @see MWsWindowTreeNode */
   536 MWsWindowTreeNode::TType CWsWindowBase::NodeType() const
   537 	{
   538 	return static_cast<MWsWindowTreeNode::TType>(iWinType); //TWinType is a subset of MWsWindowTreeNode::TType
   539 	}
   540 
   541 /** @see MWsWindowTreeNode */
   542 const MWsWindow* CWsWindowBase::Window() const
   543 	{
   544 	return (iWinType!=EWinTypeGroup) ? (static_cast<const CWsWindow*>(this)) : NULL;
   545 	}
   546 
   547 /** @see MWsWindowTreeNode */
   548 const MWsSprite* CWsWindowBase::Sprite() const
   549 	{
   550 	return NULL;
   551 	}
   552 
   553 /** @see MWsWindowTreeNode */
   554 const MWsStandardTextCursor* CWsWindowBase::StandardTextCursor() const
   555 	{
   556 	return NULL;
   557 	}
   558 
   559 /** @see MWsWindowTreeNode */
   560 const MWsWindowGroup* CWsWindowBase::WindowGroup() const
   561 	{
   562 	return static_cast<MWsWindowGroup*>(WinGroup()); 
   563 	}
   564 
   565 /** @see MWsWindowTreeNode */
   566 const MWsWindowTreeNode* CWsWindowBase::ParentNode() const
   567 	{
   568 	return iParent;
   569 	}
   570 
   571 TBool CWsWindowBase::QueueEvent(TInt aEvent, TInt aIntVal) const
   572 	{
   573 	if (WsOwner())
   574 		return(WsOwner()->EventQueue()->QueueEvent(iClientHandle, aEvent, aIntVal));
   575 	return(EFalse);
   576 	}
   577 
   578 void CWsWindowBase::SetPointerCursorByIndex(TInt aIndex)
   579 	{
   580 	SetPointerCursor(CWsClient::SystemPointerCursor(aIndex));
   581 	}
   582 
   583 void CWsWindowBase::SetPointerCursor(CWsPointerCursor *aCursor)
   584 	{
   585 	CWsPointerCursor *old=iPointerCursor;
   586 	iPointerCursor=aCursor;
   587 	if (iPointerCursor)
   588 		iPointerCursor->Open();
   589 	TWsPointer::UpdatePointerCursor();
   590 	if (old)
   591 		old->Close();
   592 	}
   593 
   594 TBool CWsWindowBase::TreeIsObscured() const
   595 	{
   596 	TBool result;
   597 	TWalkWindowTreeIsObscured wwt(result);
   598 	CONST_CAST(CWsWindowBase *,this)->WalkWindowTree(wwt,EWalkChildren);
   599 	return(result);
   600 	}
   601 
   602 CEventQueue *CWsWindowBase::EventQueue() const
   603 	{
   604 	CEventQueue* eventQueue = NULL;
   605 	if (iWsOwner)
   606 		eventQueue = iWsOwner->EventQueue();
   607 	return eventQueue;
   608 	}
   609 
   610 TInt CWsWindowBase::Depth() const
   611 	{
   612 	TInt count=0;
   613 	const CWsWindowBase *win=this;
   614 	while (win->WinType()!=EWinTypeRoot)
   615 		{
   616 		++count;
   617 		win=win->iParent;
   618 		}
   619 	return(count);
   620 	}
   621 
   622 void CWsWindowBase::WalkWindowTree(TWalkWindowTreeBase &aWalkClass,TWalkMode aMode)
   623 //
   624 // Walks windows in a front to back order
   625 //
   626 // If mode is EWalkBehind
   627 //	call DoIt for all windows that are behind 'this'
   628 // else if mode is EWalkChildren
   629 //  call DoIt for all descendents
   630 // else if mode is EWalkChildrenAndBehind
   631 //  call DoIt for for all descendents and windows behind
   632 //
   633 	{
   634 	if (this!=NULL)
   635 		{
   636 		CWsWindowBase *win=this;
   637 		CWsWindowBase *end=RootWindow();
   638 		CWsWindowBase *sibling=win->iSibling;
   639 		CWsWindowBase *parent=win->iParent;
   640 		if (aMode!=EWalkBehind)
   641 			{
   642 			if (aMode==EWalkChildren)
   643 				end=win;
   644 			goto start;
   645 			}
   646 		do
   647 			{
   648 			if (sibling!=NULL)
   649 				{
   650 				win=sibling;
   651 start:			while(win->iChild!=NULL)
   652 					win=win->iChild;
   653 				}
   654 			else
   655 				win=parent;
   656 			sibling=win->iSibling;	// De-reference win so it can be destroyed by 'DoIt'
   657 			parent=win->iParent;
   658 			if (win->iWinType!=EWinTypeGroup && aWalkClass.DoIt((CWsWindow *)win))
   659 				return;
   660 			} while(win!=end);
   661 		}
   662 	}
   663 
   664 /* Walks windows in a front to back order
   665 
   666  If aResume is EFalse the walk is identical to above.
   667  Otherwise iWin is taken as the restart point, (any child windows will have been
   668  walked previously).
   669  */
   670 void CWsWindowBase::WalkWindowTree(TResumableWalkWindowTreeBase& aWalkClass, TWalkMode aMode, TBool aResume)
   671 	{
   672 	if (this != NULL)
   673 		{ // init
   674 		if (!aResume)
   675 			{
   676 			aWalkClass.iWin = this;
   677 			aWalkClass.iEnd = (aMode == EWalkChildren) ? this : RootWindow();
   678 			aWalkClass.iParent = aWalkClass.iWin->iParent;
   679 			if (aMode == EWalkBehind)
   680 				{
   681 				aWalkClass.iNextChild = aWalkClass.iWin->iSibling;
   682 				}
   683 			else
   684 				{ // ensure walk includes this and its child windows
   685 				aWalkClass.iNextChild = this;
   686 				}
   687 			}
   688 		else if (aWalkClass.iWin == aWalkClass.iEnd)
   689 			{
   690 			return; // walk had already reached end
   691 			}
   692 
   693 		do
   694 			{
   695 			if (aWalkClass.iNextChild != NULL)
   696 				{ // walk down tree to a leaf window
   697 				aWalkClass.iWin = aWalkClass.iNextChild;
   698 				while (aWalkClass.iWin->iChild != NULL)
   699 					{
   700 					aWalkClass.iWin = aWalkClass.iWin->iChild;
   701 					}
   702 				}
   703 			else
   704 				{ // walk up tree
   705 				aWalkClass.iWin = aWalkClass.iParent;
   706 				}
   707 			// De-reference iWin so it can be destroyed by 'DoIt'
   708 			aWalkClass.iNextChild = aWalkClass.iWin->iSibling;
   709 			aWalkClass.iParent = aWalkClass.iWin->iParent;
   710 			if ( ( aWalkClass.iWin->iWinType != EWinTypeGroup ) && aWalkClass.DoIt(static_cast<CWsWindow *>(aWalkClass.iWin)) )
   711 				{
   712 				return;
   713 				}
   714 			}
   715 		while (aWalkClass.iWin != aWalkClass.iEnd);
   716 		}
   717 	}
   718 
   719 void CWsWindowBase::WalkWindowTreeBackToFront(TWalkWindowTreeBase &aWalkClass, TWalkModeBackToFront aMode)
   720 	{
   721 	// Walks windows in a back to front order
   722 	//
   723 	// If mode is EVisitParentNodesFirst
   724 	// call DoIt() on each node before walking their child windows.	
   725 	
   726 	if(iSibling)
   727 		iSibling->WalkWindowTreeBackToFront(aWalkClass,aMode);
   728 	
   729 	if(aMode == EVisitParentNodesFirst)
   730 		aWalkClass.DoIt(static_cast<CWsWindow *>(this));
   731 	
   732 	if(iChild)
   733 		iChild->WalkWindowTreeBackToFront(aWalkClass,aMode);
   734 	
   735 	}
   736 
   737 TBool CWsWindowBase::IsDSAHost() const
   738 	{
   739 	return EFalse;
   740 	}
   741 
   742 TBool CWsWindowBase::IsActivated() const
   743 	{
   744 	return EFalse;
   745 	}
   746 
   747 void CWsWindowBase::AddSprite(CWsSpriteBase * aSprite)
   748 	{
   749 	aSprite->SetNext(iSpriteList);
   750 	iSpriteList = aSprite;
   751 	}
   752 	
   753 void CWsWindowBase::RemoveSprite(CWsSpriteBase * aSprite)
   754 	{
   755 	if (aSprite == iSpriteList)
   756 		{
   757 		iSpriteList = aSprite->Next();
   758 		}
   759 	else
   760 		{
   761 		for (CWsSpriteBase * sprite = iSpriteList; sprite; sprite = sprite->Next())
   762 			{
   763 			if (sprite->Next() == aSprite)
   764 				{
   765 				sprite->SetNext(aSprite->Next());
   766 				}
   767 			}
   768 		}
   769 	aSprite->SetNext(0);
   770 	}
   771 
   772 void CWsWindowBase::SendState(MWsWindowTreeObserver& aWindowTreeObserver) const
   773 	{
   774 	//Sprites
   775 	if(iSpriteList)
   776 		iSpriteList->SendState(aWindowTreeObserver);
   777 	}
   778 
   779 #if defined(_DEBUG)
   780 
   781 void CWsWindowBase::CheckTree()
   782 	{
   783 	TWalkWindowTreeCheck wwt1;
   784 	WalkWindowTree(wwt1,EWalkChildren);
   785 	}
   786 
   787 enum {ENullWsHandle=0xFFFFFFFF};	// Events delivered to this handle are thrown away
   788 TBool CWsWindowBase::IsClientHandleInUse(TUint32 aHandle)
   789 	{
   790 	if (aHandle==static_cast<TUint>(ENullWsHandle))		//This value has a special meaning in test code
   791 		return EFalse;
   792 	CWsObjectIx* index=iWsOwner->ObjectIndex();
   793 	const CWsObject* obj;
   794 	TInt length=index->Length();
   795 	TInt ii;
   796 	for (ii=0;ii<length;++ii)
   797 		{
   798 		obj=index->At(ii);
   799 		if (obj && (obj->Type()==WS_HANDLE_WINDOW || obj->Type()==WS_HANDLE_GROUP_WINDOW))
   800 			{
   801 			if (STATIC_CAST(const CWsWindowBase*,obj)->ClientHandle()==aHandle)
   802 				return ETrue;
   803 			}
   804 		}
   805 	return EFalse;
   806 	}
   807 
   808 #endif