windowing/windowserver/nonnga/SERVER/WINBASE.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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 
       
    30 CWsWindowBase::CWsWindowBase(CWsClient* aOwner,WH_HANDLES aType, CScreen* aScreen) : CWsScreenObject(aOwner,aType,aScreen)		
       
    31 	{
       
    32 	}
       
    33 
       
    34 void CWsWindowBase::ConstructL(CWsWindowBase *parent)
       
    35 	{
       
    36 	iParent=parent;
       
    37 	iSibling=parent->iChild;
       
    38 	parent->iChild=this;
       
    39 	SetOrdinalPosition(0);
       
    40 	iFadeCount = iParent->iFadeCount;
       
    41 	}
       
    42 
       
    43 CWsWindowBase *CWsWindowBase::GetPrevSibling() const
       
    44 	{
       
    45 	CWsWindowBase **prev= &iParent->iChild;
       
    46 	CWsWindowBase *ret=NULL;
       
    47 	while ((*prev)!=this)
       
    48 		{
       
    49 		ret=*prev;
       
    50 		prev= &(*prev)->iSibling;
       
    51 		}
       
    52 	return(ret);
       
    53 	}
       
    54 
       
    55 CWsWindowBase *CWsWindowBase::LastSibling() const
       
    56 	{
       
    57 	const CWsWindowBase *win;
       
    58 	for(win=this;win->iSibling;win=win->iSibling)
       
    59 		{}
       
    60 	return (CWsWindowBase*)win;
       
    61 	}
       
    62 
       
    63 CWsWindowBase *CWsWindowBase::PrevSiblingMultiParent() const
       
    64 	{
       
    65 	CWsWindowBase *win=GetPrevSibling();
       
    66 	if (win)
       
    67 		return(win);
       
    68 	for(CWsWindowBase *parent=iParent->GetPrevSibling();parent;parent=parent->GetPrevSibling())
       
    69 		if ((win=parent->iChild)!=NULL)
       
    70 			return(win->LastSibling());
       
    71 	return(NULL);
       
    72 	}
       
    73 
       
    74 // Andy - this is a kind of "next cousin" function
       
    75 CWsWindowBase *CWsWindowBase::NextSiblingMultiParent() const
       
    76 	{
       
    77 	if (iSibling)
       
    78 		return(iSibling);
       
    79 	for(CWsWindowBase *parent=iParent->iSibling;parent;parent=parent->iSibling)
       
    80 		{
       
    81 		if (parent->iChild!=NULL)
       
    82 			return(parent->iChild);
       
    83 		}
       
    84 	return(NULL);
       
    85 	}
       
    86 
       
    87 TInt CWsWindowBase::OrdinalPosition(TBool aFull) const
       
    88 	{
       
    89 	if (!iParent)
       
    90 		{
       
    91 		OwnerPanic(EWservPanicParentDeleted);
       
    92 		}
       
    93 	CWsWindowBase *win=iParent->iChild;
       
    94 	if (!aFull)
       
    95 		while(iOrdinalPriority<win->iOrdinalPriority)
       
    96 			win=win->iSibling;
       
    97 	TInt count;
       
    98 	for(count=0;win!=this;count++)
       
    99 		win=win->iSibling;
       
   100 	return(count);
       
   101 	}
       
   102 
       
   103 /** Removes a window from the list of siblings maintained by its parent window.
       
   104 
       
   105 The iSibling stored inside the window we remove is kept unchanged as it may be needed later.
       
   106 
       
   107 @internalComponent
       
   108 @released
       
   109 */
       
   110 void CWsWindowBase::RemoveFromSiblingList()
       
   111 	{
       
   112 	if (iParent!=NULL)
       
   113 		{
       
   114 		CWsWindowBase **prev= &iParent->iChild;
       
   115 		while ((*prev)!=this)
       
   116 			prev= &(*prev)->iSibling;
       
   117 		*prev=iSibling;
       
   118 		}
       
   119 	}
       
   120 
       
   121 /* This const casts in this function are horrible and need revisiting. */
       
   122 CWsWindowGroup *CWsWindowBase::WinGroup() const
       
   123 	{
       
   124 	switch (iWinType)
       
   125 		{
       
   126 		case EWinTypeClient:
       
   127 			{
       
   128 			if (iParent)
       
   129 				{
       
   130 				CWsWindowBase* win = const_cast<CWsWindowBase*>(this);
       
   131 				while(win->WinType()!=EWinTypeGroup)
       
   132 					win=win->BaseParent();
       
   133 				return static_cast<CWsWindowGroup*>(win);
       
   134 				}
       
   135 			return 0;
       
   136 			}
       
   137 		case EWinTypeGroup:
       
   138 			return const_cast<CWsWindowGroup*>(static_cast<const CWsWindowGroup*>(this));
       
   139 		default:
       
   140 			return 0;
       
   141 		}
       
   142 	}
       
   143 
       
   144 TBool CWsWindowBase::CheckOrdinalPositionChange(TInt aPos)
       
   145 //
       
   146 // This routine checks to see whether the specified new ordinal position
       
   147 // will causes a change, if so returns ETrue else EFalse.
       
   148 //
       
   149 	{
       
   150 	if (!iParent)
       
   151 		{
       
   152 		OwnerPanic(EWservPanicParentDeleted);
       
   153 		}
       
   154 	CWsWindowBase *win= iParent->iChild;
       
   155 	CWsWindowBase *prev= NULL;
       
   156 	while(win==this || (win!=NULL && iOrdinalPriority<win->iOrdinalPriority))
       
   157 		{
       
   158 		prev=win;
       
   159 		win=win->iSibling;
       
   160 		}
       
   161 	if (prev==this)
       
   162 		win=this;
       
   163 	else if (win==NULL || (win->iSibling==this && iOrdinalPriority>win->iOrdinalPriority))
       
   164 		return ETrue;
       
   165 	while(aPos--!=0 && win->iSibling!=NULL && iOrdinalPriority==win->iSibling->iOrdinalPriority)
       
   166 		win=win->iSibling;
       
   167 	return(win!=this);
       
   168 	}
       
   169 
       
   170 void CWsWindowBase::ChangeWindowPosition(TInt aPos,CWsWindowBase* aNewParent)
       
   171 	{
       
   172 	if (aNewParent != iParent)
       
   173 		{
       
   174 		iScreen->ScheduleRegionUpdate(NULL);		
       
   175 		TWalkWindowTreeScheduleRedraws wwt;
       
   176 		WalkWindowTree(wwt, EWalkChildren);
       
   177 		}
       
   178 	else if (WinType() == EWinTypeClient)
       
   179 		{
       
   180 		CWsClientWindow * cliwin = static_cast<CWsClientWindow*>(this);
       
   181 		if (cliwin->IsVisible())
       
   182 			{
       
   183 			iScreen->ScheduleRegionUpdate(NULL);
       
   184 			if (cliwin->IsTranslucent())
       
   185 				{
       
   186 				// There is still room for optimization here.  These redraws are only required if the window
       
   187 				// moved through another window and BOTH of them were transparent, otherwise the visible
       
   188 				// region change will sort out the redraws required.
       
   189 				TWalkWindowTreeScheduleRedraws wwt;
       
   190 				WalkWindowTree(wwt, EWalkChildren);
       
   191 				}
       
   192 			}
       
   193 		}
       
   194 	else if (WinType() == EWinTypeGroup)
       
   195 		{
       
   196 		iScreen->ScheduleRegionUpdate(NULL);
       
   197 		if (static_cast<CWsWindowGroup*>(this)->HasVisibleTranslucentChild())
       
   198 			{
       
   199 			TWalkWindowTreeScheduleRedraws wwt;
       
   200 			WalkWindowTree(wwt, EWalkChildren);				
       
   201 			}
       
   202 		}
       
   203 
       
   204 	RemoveFromSiblingList();
       
   205 	CWsWindowBase **prevWinPtr= &aNewParent->iChild;
       
   206 	while((*prevWinPtr)!=NULL && iOrdinalPriority<(*prevWinPtr)->iOrdinalPriority)
       
   207 		{
       
   208 		prevWinPtr= &(*prevWinPtr)->iSibling;
       
   209 		}
       
   210 	while(aPos--!=0 && *prevWinPtr!=NULL && iOrdinalPriority==(*prevWinPtr)->iOrdinalPriority)
       
   211 		{
       
   212 		prevWinPtr= &(*prevWinPtr)->iSibling;
       
   213 		}
       
   214 	iSibling=*prevWinPtr;
       
   215 	iParent=aNewParent;
       
   216 	*prevWinPtr=this;
       
   217 	}
       
   218 
       
   219 void CWsWindowBase::SetOrdinalPosition(TInt aPos)
       
   220 	{
       
   221 	if (CheckOrdinalPositionChange(aPos))
       
   222 		ChangeWindowPosition(aPos,iParent);
       
   223 	}
       
   224 
       
   225 TEventQueueWalkRet EventPurgeFunc(TAny *aPtr, TWsEvent *aEvent)
       
   226 //
       
   227 // Callback function for event queue walk
       
   228 //
       
   229 	{
       
   230 	return(((CWsWindowBase *)aPtr)->EventPurgeCheck(aEvent));
       
   231 	}
       
   232 
       
   233 TEventQueueWalkRet CWsWindowBase::EventPurgeCheck(TWsEvent *aEvent)
       
   234 	{
       
   235 	if (aEvent->Handle()==ClientHandle())
       
   236 		return(EEventQueueWalkDeleteEvent);
       
   237 	return(EEventQueueWalkOk);
       
   238 	}
       
   239 
       
   240 void CWsWindowBase::PurgeEvents()
       
   241 	{
       
   242 	iWsOwner->EventQueue()->WalkEventQueue(&EventPurgeFunc,this);
       
   243 	}
       
   244 
       
   245 void CWsWindowBase::Shutdown()
       
   246 //
       
   247 // Destroy a window, disconnects from the window tree and destroys all it's child windows
       
   248 //
       
   249 	{
       
   250 	if (iWsOwner!=NULL)
       
   251 		PurgeEvents();
       
   252 	if (iParent!=NULL)	// Check it's connected to something
       
   253 		{
       
   254 		CWsWindowBase *win;
       
   255 		for(win=this;win && win->iParent!=(CWsWindowBase *)RootWindow();win=win->iParent)
       
   256 			{}
       
   257 		RemoveFromSiblingList();
       
   258 		TWalkWindowTreeDisconnect wwt2(win ? ((CWsWindowGroup *)win)->TextCursor() : NULL);
       
   259 		WalkWindowTree(wwt2,EWalkChildren); // Disconnect all child windows
       
   260 		iChild=NULL;
       
   261 		}
       
   262 	TWindowServerEvent::RemoveFromSwitchOnEventList(*this);
       
   263 	TWindowServerEvent::RemoveFromErrorMessageList(*this);
       
   264 	TWindowServerEvent::RemoveFromGroupChangeEventEventList(*this);
       
   265 	TWindowServerEvent::RemoveFromFocusChangeEventEventList(*this);
       
   266 	TWindowServerEvent::RemoveFromGroupListChangeEventEventList(*this);
       
   267 	TWindowServerEvent::RemoveFromModifierChangedEventList(*this);
       
   268 	TWindowServerEvent::RemoveFromScreenDeviceChangeEventList(*this);
       
   269 	CWsTop::StopWindowGettingOffEvents(this);
       
   270 	}
       
   271 
       
   272 TBool CWsWindowBase::CommandL(TInt aOpcode, TWsWinCmdUnion &aCmd)
       
   273 //
       
   274 // If the command is supported by the window base class process it and return ETrue
       
   275 // if it is not supported return EFalse
       
   276 //
       
   277 	{
       
   278 	switch(aOpcode)
       
   279 		{
       
   280 		case EWsWinOpFree:
       
   281 			delete this;
       
   282 			break;
       
   283 		case EWsWinOpSetOrdinalPosition:
       
   284 			SetOrdinalPosition(*aCmd.Int);
       
   285 			break;
       
   286 		case EWsWinOpOrdinalPriority:
       
   287 			SetReply(iOrdinalPriority);
       
   288 			break;
       
   289 		case EWsWinOpOrdinalPosition:
       
   290 			SetReply(OrdinalPosition(EFalse));
       
   291 			break;
       
   292 		case EWsWinOpFullOrdinalPosition:
       
   293 			SetReply(OrdinalPosition(ETrue));
       
   294 			break;
       
   295 		case EWsWinOpClientHandle:
       
   296 			SetReply(iClientHandle);
       
   297 			break;
       
   298 		case EWsWinOpParent:
       
   299 			if (!iParent)
       
   300 				{
       
   301 				OwnerPanic(EWservPanicParentDeleted);
       
   302 				}
       
   303 			SetReply(iParent->iClientHandle);
       
   304 			break;
       
   305 		case EWsWinOpPrevSibling:
       
   306 			{
       
   307 			if (!iParent)
       
   308 				{
       
   309 				OwnerPanic(EWservPanicParentDeleted);
       
   310 				}
       
   311 			TUint32 reply=NULL;
       
   312 			for(CWsWindowBase *win=this->GetPrevSibling();win;win=win->GetPrevSibling())
       
   313 				{
       
   314 				if (win->iWsOwner==iWsOwner)
       
   315 					{
       
   316 					reply=win->iClientHandle;
       
   317 					break;
       
   318 					}
       
   319 				}
       
   320 			SetReply(reply);
       
   321 			}
       
   322 			break;
       
   323 		case EWsWinOpNextSibling:
       
   324 			{
       
   325 			TUint32 reply=NULL;
       
   326 			for(CWsWindowBase *win=this->iSibling;win;win=win->iSibling)
       
   327 				{
       
   328 				if (win->iWsOwner==iWsOwner)
       
   329 					{
       
   330 					reply=win->iClientHandle;
       
   331 					break;
       
   332 					}
       
   333 				}
       
   334 			SetReply(reply);
       
   335 			}
       
   336 			break;
       
   337 		case EWsWinOpChild:
       
   338 			SetReply(iChild==NULL ? NULL : iChild->iClientHandle);
       
   339 			break;
       
   340 		case EWsWinOpScreenNumber:
       
   341 			SetReply(Screen()->ScreenNumber());
       
   342 			break;
       
   343 		case EWsWinOpWindowGroupId:
       
   344 			if (!WinGroup())
       
   345 				{
       
   346 				OwnerPanic(EWservPanicParentDeleted);
       
   347 				}
       
   348 			SetReply(WinGroup()->Identifier());
       
   349 			break;
       
   350 		case EWsWinOpEnableOnEvents:
       
   351 			TWindowServerEvent::AddToSwitchOnEventListL(*this, *aCmd.EventControl);
       
   352 			break;
       
   353 		case EWsWinOpDisableOnEvents:
       
   354 			TWindowServerEvent::RemoveFromSwitchOnEventList(*this);
       
   355 			break;
       
   356 		case EWsWinOpEnableErrorMessages:
       
   357 			TWindowServerEvent::AddToErrorMessageListL(*this, *aCmd.EventControl);
       
   358 			break;
       
   359 		case EWsWinOpDisableErrorMessages:
       
   360 			TWindowServerEvent::RemoveFromErrorMessageList(*this);
       
   361 			break;
       
   362 		case EWsWinOpEnableModifierChangedEvents:
       
   363 			TWindowServerEvent::AddToModifierChangedEventListL(*this, aCmd.EnableModifierChangedEvents->modifierMask,
       
   364 														aCmd.EnableModifierChangedEvents->circumstances);
       
   365 			break;
       
   366 		case EWsWinOpDisableModifierChangedEvents:
       
   367 			TWindowServerEvent::RemoveFromModifierChangedEventList(*this);
       
   368 			break;
       
   369 		case EWsWinOpEnableGroupChangeEvents:
       
   370 			TWindowServerEvent::AddToGroupChangeEventListL(*this);
       
   371 			break;
       
   372 		case EWsWinOpDisableGroupChangeEvents:
       
   373 			TWindowServerEvent::RemoveFromGroupChangeEventEventList(*this);
       
   374 			break;
       
   375 		case EWsWinOpEnableFocusChangeEvents:
       
   376 			TWindowServerEvent::AddToFocusChangeEventListL(*this);
       
   377 			break;
       
   378 		case EWsWinOpDisableFocusChangeEvents:
       
   379 			TWindowServerEvent::RemoveFromFocusChangeEventEventList(*this);
       
   380 			break;
       
   381 		case EWsWinOpEnableGroupListChangeEvents:
       
   382 			TWindowServerEvent::AddToGroupListChangeEventListL(*this);
       
   383 			break;
       
   384 		case EWsWinOpDisableGroupListChangeEvents:
       
   385 			TWindowServerEvent::RemoveFromGroupListChangeEventEventList(*this);
       
   386 			break;
       
   387 		case EWsWinOpSetCustomPointerCursor:
       
   388 			CWsObject *pointercursor;
       
   389 			if ((pointercursor=iWsOwner->HandleToObj(*aCmd.Int, WS_HANDLE_POINTER_CURSOR))==NULL)
       
   390 				OwnerPanic(EWservPanicSprite);
       
   391 			SetPointerCursor((CWsPointerCursor *)pointercursor);
       
   392 			break;
       
   393 		case EWsWinOpSetPointerCursor:
       
   394 			SetPointerCursorByIndex(*aCmd.UInt);
       
   395 			break;
       
   396 		case EWsWinOpClearPointerCursor:
       
   397 			SetPointerCursor(NULL);
       
   398 			break;
       
   399 		case EWsWinOpSetNonFading:
       
   400 			{
       
   401 			WS_ASSERT_DEBUG(iScreen, EWsPanicNoScreen);
       
   402 			// No fading will occur from a graphical perspective, but the fade counts
       
   403 			// are maintained for BC reasons.
       
   404 			TWalkWindowTreeSetNonFading wwt(*aCmd.Bool);
       
   405 			WalkWindowTree(wwt,EWalkChildren);
       
   406 			Screen()->AcceptFadeRequest( reinterpret_cast<CWsWindow*>(this), 
       
   407 														 ETrue, 
       
   408 														 EFalse, 
       
   409 														 ETrue );
       
   410 			}
       
   411 			break;
       
   412 		case EWsWinOpSetFade:
       
   413 			{
       
   414 			if (!iParent)
       
   415 				{
       
   416 				OwnerPanic(EWservPanicParentDeleted);
       
   417 				}
       
   418 			WS_ASSERT_DEBUG(iScreen, EWsPanicNoScreen);
       
   419 			
       
   420 			TUint8 blackMap;
       
   421 			TUint8 whiteMap;
       
   422 			if (aCmd.SetFaded->UseDefaultMap())
       
   423 				{
       
   424 				iScreen->GetFadingParams(blackMap,whiteMap);
       
   425 				}
       
   426 			else
       
   427 				{
       
   428 				aCmd.SetFaded->GetFadingParams(blackMap,whiteMap);
       
   429 				}
       
   430 	
       
   431 			if (aCmd.SetFaded->IncludeChildren())
       
   432 				{
       
   433 				TWalkWindowTreeSetFaded wwt(aCmd.SetFaded->Faded(),this,blackMap,whiteMap);
       
   434 				WalkWindowTree(wwt,EWalkChildren);
       
   435 				}
       
   436 			else
       
   437 				{
       
   438 				if (iWinType==EWinTypeGroup)
       
   439 					OwnerPanic(EWservPanicOpcode);
       
   440 				static_cast<CWsClientWindow*>(this)->SetFaded(aCmd.SetFaded->Faded(),blackMap,whiteMap); 
       
   441 				}
       
   442 
       
   443 			if (CWsTop::IsFadeEnabled()) 
       
   444 				{
       
   445 				Screen()->AcceptFadeRequest( reinterpret_cast<CWsWindow *> (this), 
       
   446 											 aCmd.SetFaded->Faded(), 
       
   447 											 EFalse, 
       
   448 											 aCmd.SetFaded->IncludeChildren() );
       
   449 				}
       
   450 			}
       
   451 			break;
       
   452 		default:
       
   453 			return(EFalse);
       
   454 		}
       
   455 	return(ETrue);
       
   456 	}
       
   457 
       
   458 TBool CWsWindowBase::QueueEvent(TInt aEvent) const
       
   459 	{
       
   460 	if (WsOwner())
       
   461 		return(WsOwner()->EventQueue()->QueueEvent(iClientHandle, aEvent));
       
   462 	return(EFalse);
       
   463 	}
       
   464 
       
   465 void CWsWindowBase::SetPointerCursorByIndex(TInt aIndex)
       
   466 	{
       
   467 	SetPointerCursor(CWsClient::SystemPointerCursor(aIndex));
       
   468 	}
       
   469 
       
   470 void CWsWindowBase::SetPointerCursor(CWsPointerCursor *aCursor)
       
   471 	{
       
   472 	CWsPointerCursor *old=iPointerCursor;
       
   473 	iPointerCursor=aCursor;
       
   474 	if (iPointerCursor)
       
   475 		iPointerCursor->Open();
       
   476 	WsPointer::UpdatePointerCursor();
       
   477 	if (old)
       
   478 		old->Close();
       
   479 	}
       
   480 
       
   481 TBool CWsWindowBase::TreeIsObscured() const
       
   482 	{
       
   483 	TBool result;
       
   484 	TWalkWindowTreeIsObscured wwt(result);
       
   485 	CONST_CAST(CWsWindowBase *,this)->WalkWindowTree(wwt,EWalkChildren);
       
   486 	return(result);
       
   487 	}
       
   488 
       
   489 CEventQueue *CWsWindowBase::EventQueue() const
       
   490 	{
       
   491 	return(iWsOwner->EventQueue());
       
   492 	}
       
   493 
       
   494 void CWsWindowBase::WalkWindowTree(TWalkWindowTreeBase &aWalkClass,TWalkMode aMode)
       
   495 //
       
   496 // Walks windows in a front to back order
       
   497 //
       
   498 // If mode is EWalkBehind
       
   499 //	call DoIt for all windows that are behind 'this'
       
   500 // else if mode is EWalkChildren
       
   501 //  call DoIt for all descendents
       
   502 // else if mode is EWalkChildrenAndBehind
       
   503 //  call DoIt for for all descendents and windows behind
       
   504 //
       
   505 	{
       
   506 	if (this!=NULL)
       
   507 		{
       
   508 		CWsWindowBase *win=this;
       
   509 		CWsWindowBase *end=RootWindow();
       
   510 		CWsWindowBase *sibling=win->iSibling;
       
   511 		CWsWindowBase *parent=win->iParent;
       
   512 		if (aMode!=EWalkBehind)
       
   513 			{
       
   514 			if (aMode==EWalkChildren)
       
   515 				end=win;
       
   516 			goto start;
       
   517 			}
       
   518 		do
       
   519 			{
       
   520 			if (sibling!=NULL)
       
   521 				{
       
   522 				win=sibling;
       
   523 start:			while(win->iChild!=NULL)
       
   524 					win=win->iChild;
       
   525 				}
       
   526 			else
       
   527 				win=parent;
       
   528 			sibling=win->iSibling;	// De-reference win so it can be destroyed by 'DoIt'
       
   529 			parent=win->iParent;
       
   530 			if (win->iWinType!=EWinTypeGroup && aWalkClass.DoIt((CWsWindow *)win))
       
   531 				return;
       
   532 			} while(win!=end);
       
   533 		}
       
   534 	}
       
   535 
       
   536 /* Walks windows in a front to back order
       
   537 
       
   538  If aResume is EFalse the walk is identical to above.
       
   539  Otherwise iWin is taken as the restart point, (any child windows will have been
       
   540  walked previously).
       
   541  */
       
   542 void CWsWindowBase::WalkWindowTree(TResumableWalkWindowTreeBase& aWalkClass, TWalkMode aMode, TBool aResume)
       
   543 	{
       
   544 	if (this != NULL)
       
   545 		{ // init
       
   546 		if (!aResume)
       
   547 			{
       
   548 			aWalkClass.iWin = this;
       
   549 			aWalkClass.iEnd = (aMode == EWalkChildren) ? this : RootWindow();
       
   550 			aWalkClass.iParent = aWalkClass.iWin->iParent;
       
   551 			if (aMode == EWalkBehind)
       
   552 				{
       
   553 				aWalkClass.iNextChild = aWalkClass.iWin->iSibling;
       
   554 				}
       
   555 			else
       
   556 				{ // ensure walk includes this and its child windows
       
   557 				aWalkClass.iNextChild = this;
       
   558 				}
       
   559 			}
       
   560 		else if (aWalkClass.iWin == aWalkClass.iEnd)
       
   561 			{
       
   562 			return; // walk had already reached end
       
   563 			}
       
   564 
       
   565 		do
       
   566 			{
       
   567 			if (aWalkClass.iNextChild != NULL)
       
   568 				{ // walk down tree to a leaf window
       
   569 				aWalkClass.iWin = aWalkClass.iNextChild;
       
   570 				while (aWalkClass.iWin->iChild != NULL)
       
   571 					{
       
   572 					aWalkClass.iWin = aWalkClass.iWin->iChild;
       
   573 					}
       
   574 				}
       
   575 			else
       
   576 				{ // walk up tree
       
   577 				aWalkClass.iWin = aWalkClass.iParent;
       
   578 				}
       
   579 			// De-reference iWin so it can be destroyed by 'DoIt'
       
   580 			aWalkClass.iNextChild = aWalkClass.iWin->iSibling;
       
   581 			aWalkClass.iParent = aWalkClass.iWin->iParent;
       
   582 			if ( ( aWalkClass.iWin->iWinType != EWinTypeGroup ) && aWalkClass.DoIt(static_cast<CWsWindow *>(aWalkClass.iWin)) )
       
   583 				{
       
   584 				return;
       
   585 				}
       
   586 			}
       
   587 		while (aWalkClass.iWin != aWalkClass.iEnd);
       
   588 		}
       
   589 	}
       
   590 
       
   591 #if defined(_DEBUG)
       
   592 
       
   593 void CWsWindowBase::CheckTree()
       
   594 	{
       
   595 	TWalkWindowTreeCheck wwt1;
       
   596 	WalkWindowTree(wwt1,EWalkChildren);
       
   597 	}
       
   598 
       
   599 enum {ENullWsHandle=0xFFFFFFFF};	// Events delivered to this handle are thrown away
       
   600 TBool CWsWindowBase::IsClientHandleInUse(TUint32 aHandle)
       
   601 	{
       
   602 	if (aHandle==static_cast<TUint>(ENullWsHandle))		//This value has a special meaning in test code
       
   603 		return EFalse;
       
   604 	CWsObjectIx* index=iWsOwner->ObjectIndex();
       
   605 	const CWsObject* obj;
       
   606 	TInt length=index->Length();
       
   607 	TInt ii;
       
   608 	for (ii=0;ii<length;++ii)
       
   609 		{
       
   610 		obj=index->At(ii);
       
   611 		if (obj && (obj->Type()==WS_HANDLE_WINDOW || obj->Type()==WS_HANDLE_GROUP_WINDOW))
       
   612 			{
       
   613 			if (STATIC_CAST(const CWsWindowBase*,obj)->ClientHandle()==aHandle)
       
   614 				return ETrue;
       
   615 			}
       
   616 		}
       
   617 	return EFalse;
       
   618 	}
       
   619 
       
   620 #endif
       
   621 
       
   622 TBool CWsWindowBase::IsDSAHost() const
       
   623 	{
       
   624 	return EFalse;
       
   625 	}
       
   626