windowing/windowserver/nga/SERVER/openwfc/WINBASE.CPP
changeset 0 5d03bc08d59c
child 122 5fabdb30d001
child 136 62bb7c97884c
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 #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 				User::LeaveIfError(IsActivated()?KErrInUse:KErrNone);
       
   516 				iBaseWinFlags |= EBaseWinAdvancedPointersEnabled;
       
   517 				break;
       
   518 		default:
       
   519 			return(EFalse);
       
   520 		}
       
   521 	return(ETrue);
       
   522 	}
       
   523 
       
   524 /** @see MWsWindowTreeNode */
       
   525 MWsWindowTreeNode::TType CWsWindowBase::NodeType() const
       
   526 	{
       
   527 	return static_cast<MWsWindowTreeNode::TType>(iWinType); //TWinType is a subset of MWsWindowTreeNode::TType
       
   528 	}
       
   529 
       
   530 /** @see MWsWindowTreeNode */
       
   531 const MWsWindow* CWsWindowBase::Window() const
       
   532 	{
       
   533 	return (iWinType!=EWinTypeGroup) ? (static_cast<const CWsWindow*>(this)) : NULL;
       
   534 	}
       
   535 
       
   536 /** @see MWsWindowTreeNode */
       
   537 const MWsSprite* CWsWindowBase::Sprite() const
       
   538 	{
       
   539 	return NULL;
       
   540 	}
       
   541 
       
   542 /** @see MWsWindowTreeNode */
       
   543 const MWsStandardTextCursor* CWsWindowBase::StandardTextCursor() const
       
   544 	{
       
   545 	return NULL;
       
   546 	}
       
   547 
       
   548 /** @see MWsWindowTreeNode */
       
   549 const MWsWindowGroup* CWsWindowBase::WindowGroup() const
       
   550 	{
       
   551 	return static_cast<MWsWindowGroup*>(WinGroup()); 
       
   552 	}
       
   553 
       
   554 /** @see MWsWindowTreeNode */
       
   555 const MWsWindowTreeNode* CWsWindowBase::ParentNode() const
       
   556 	{
       
   557 	return iParent;
       
   558 	}
       
   559 
       
   560 TBool CWsWindowBase::QueueEvent(TInt aEvent, TInt aIntVal) const
       
   561 	{
       
   562 	if (WsOwner())
       
   563 		return(WsOwner()->EventQueue()->QueueEvent(iClientHandle, aEvent, aIntVal));
       
   564 	return(EFalse);
       
   565 	}
       
   566 
       
   567 void CWsWindowBase::SetPointerCursorByIndex(TInt aIndex)
       
   568 	{
       
   569 	SetPointerCursor(CWsClient::SystemPointerCursor(aIndex));
       
   570 	}
       
   571 
       
   572 void CWsWindowBase::SetPointerCursor(CWsPointerCursor *aCursor)
       
   573 	{
       
   574 	CWsPointerCursor *old=iPointerCursor;
       
   575 	iPointerCursor=aCursor;
       
   576 	if (iPointerCursor)
       
   577 		iPointerCursor->Open();
       
   578 	TWsPointer::UpdatePointerCursor();
       
   579 	if (old)
       
   580 		old->Close();
       
   581 	}
       
   582 
       
   583 TBool CWsWindowBase::TreeIsObscured() const
       
   584 	{
       
   585 	TBool result;
       
   586 	TWalkWindowTreeIsObscured wwt(result);
       
   587 	CONST_CAST(CWsWindowBase *,this)->WalkWindowTree(wwt,EWalkChildren);
       
   588 	return(result);
       
   589 	}
       
   590 
       
   591 CEventQueue *CWsWindowBase::EventQueue() const
       
   592 	{
       
   593 	CEventQueue* eventQueue = NULL;
       
   594 	if (iWsOwner)
       
   595 		eventQueue = iWsOwner->EventQueue();
       
   596 	return eventQueue;
       
   597 	}
       
   598 
       
   599 TInt CWsWindowBase::Depth() const
       
   600 	{
       
   601 	TInt count=0;
       
   602 	const CWsWindowBase *win=this;
       
   603 	while (win->WinType()!=EWinTypeRoot)
       
   604 		{
       
   605 		++count;
       
   606 		win=win->iParent;
       
   607 		}
       
   608 	return(count);
       
   609 	}
       
   610 
       
   611 void CWsWindowBase::WalkWindowTree(TWalkWindowTreeBase &aWalkClass,TWalkMode aMode)
       
   612 //
       
   613 // Walks windows in a front to back order
       
   614 //
       
   615 // If mode is EWalkBehind
       
   616 //	call DoIt for all windows that are behind 'this'
       
   617 // else if mode is EWalkChildren
       
   618 //  call DoIt for all descendents
       
   619 // else if mode is EWalkChildrenAndBehind
       
   620 //  call DoIt for for all descendents and windows behind
       
   621 //
       
   622 	{
       
   623 	if (this!=NULL)
       
   624 		{
       
   625 		CWsWindowBase *win=this;
       
   626 		CWsWindowBase *end=RootWindow();
       
   627 		CWsWindowBase *sibling=win->iSibling;
       
   628 		CWsWindowBase *parent=win->iParent;
       
   629 		if (aMode!=EWalkBehind)
       
   630 			{
       
   631 			if (aMode==EWalkChildren)
       
   632 				end=win;
       
   633 			goto start;
       
   634 			}
       
   635 		do
       
   636 			{
       
   637 			if (sibling!=NULL)
       
   638 				{
       
   639 				win=sibling;
       
   640 start:			while(win->iChild!=NULL)
       
   641 					win=win->iChild;
       
   642 				}
       
   643 			else
       
   644 				win=parent;
       
   645 			sibling=win->iSibling;	// De-reference win so it can be destroyed by 'DoIt'
       
   646 			parent=win->iParent;
       
   647 			if (win->iWinType!=EWinTypeGroup && aWalkClass.DoIt((CWsWindow *)win))
       
   648 				return;
       
   649 			} while(win!=end);
       
   650 		}
       
   651 	}
       
   652 
       
   653 /* Walks windows in a front to back order
       
   654 
       
   655  If aResume is EFalse the walk is identical to above.
       
   656  Otherwise iWin is taken as the restart point, (any child windows will have been
       
   657  walked previously).
       
   658  */
       
   659 void CWsWindowBase::WalkWindowTree(TResumableWalkWindowTreeBase& aWalkClass, TWalkMode aMode, TBool aResume)
       
   660 	{
       
   661 	if (this != NULL)
       
   662 		{ // init
       
   663 		if (!aResume)
       
   664 			{
       
   665 			aWalkClass.iWin = this;
       
   666 			aWalkClass.iEnd = (aMode == EWalkChildren) ? this : RootWindow();
       
   667 			aWalkClass.iParent = aWalkClass.iWin->iParent;
       
   668 			if (aMode == EWalkBehind)
       
   669 				{
       
   670 				aWalkClass.iNextChild = aWalkClass.iWin->iSibling;
       
   671 				}
       
   672 			else
       
   673 				{ // ensure walk includes this and its child windows
       
   674 				aWalkClass.iNextChild = this;
       
   675 				}
       
   676 			}
       
   677 		else if (aWalkClass.iWin == aWalkClass.iEnd)
       
   678 			{
       
   679 			return; // walk had already reached end
       
   680 			}
       
   681 
       
   682 		do
       
   683 			{
       
   684 			if (aWalkClass.iNextChild != NULL)
       
   685 				{ // walk down tree to a leaf window
       
   686 				aWalkClass.iWin = aWalkClass.iNextChild;
       
   687 				while (aWalkClass.iWin->iChild != NULL)
       
   688 					{
       
   689 					aWalkClass.iWin = aWalkClass.iWin->iChild;
       
   690 					}
       
   691 				}
       
   692 			else
       
   693 				{ // walk up tree
       
   694 				aWalkClass.iWin = aWalkClass.iParent;
       
   695 				}
       
   696 			// De-reference iWin so it can be destroyed by 'DoIt'
       
   697 			aWalkClass.iNextChild = aWalkClass.iWin->iSibling;
       
   698 			aWalkClass.iParent = aWalkClass.iWin->iParent;
       
   699 			if ( ( aWalkClass.iWin->iWinType != EWinTypeGroup ) && aWalkClass.DoIt(static_cast<CWsWindow *>(aWalkClass.iWin)) )
       
   700 				{
       
   701 				return;
       
   702 				}
       
   703 			}
       
   704 		while (aWalkClass.iWin != aWalkClass.iEnd);
       
   705 		}
       
   706 	}
       
   707 
       
   708 void CWsWindowBase::WalkWindowTreeBackToFront(TWalkWindowTreeBase &aWalkClass, TWalkModeBackToFront aMode)
       
   709 	{
       
   710 	// Walks windows in a back to front order
       
   711 	//
       
   712 	// If mode is EVisitParentNodesFirst
       
   713 	// call DoIt() on each node before walking their child windows.	
       
   714 	
       
   715 	if(iSibling)
       
   716 		iSibling->WalkWindowTreeBackToFront(aWalkClass,aMode);
       
   717 	
       
   718 	if(aMode == EVisitParentNodesFirst)
       
   719 		aWalkClass.DoIt(static_cast<CWsWindow *>(this));
       
   720 	
       
   721 	if(iChild)
       
   722 		iChild->WalkWindowTreeBackToFront(aWalkClass,aMode);
       
   723 	
       
   724 	}
       
   725 
       
   726 TBool CWsWindowBase::IsDSAHost() const
       
   727 	{
       
   728 	return EFalse;
       
   729 	}
       
   730 
       
   731 TBool CWsWindowBase::IsActivated() const
       
   732 	{
       
   733 	return EFalse;
       
   734 	}
       
   735 
       
   736 void CWsWindowBase::AddSprite(CWsSpriteBase * aSprite)
       
   737 	{
       
   738 	aSprite->SetNext(iSpriteList);
       
   739 	iSpriteList = aSprite;
       
   740 	}
       
   741 	
       
   742 void CWsWindowBase::RemoveSprite(CWsSpriteBase * aSprite)
       
   743 	{
       
   744 	if (aSprite == iSpriteList)
       
   745 		{
       
   746 		iSpriteList = aSprite->Next();
       
   747 		}
       
   748 	else
       
   749 		{
       
   750 		for (CWsSpriteBase * sprite = iSpriteList; sprite; sprite = sprite->Next())
       
   751 			{
       
   752 			if (sprite->Next() == aSprite)
       
   753 				{
       
   754 				sprite->SetNext(aSprite->Next());
       
   755 				}
       
   756 			}
       
   757 		}
       
   758 	aSprite->SetNext(0);
       
   759 	}
       
   760 
       
   761 void CWsWindowBase::SendState(MWsWindowTreeObserver& aWindowTreeObserver) const
       
   762 	{
       
   763 	//Sprites
       
   764 	if(iSpriteList)
       
   765 		iSpriteList->SendState(aWindowTreeObserver);
       
   766 	}
       
   767 
       
   768 #if defined(_DEBUG)
       
   769 
       
   770 void CWsWindowBase::CheckTree()
       
   771 	{
       
   772 	TWalkWindowTreeCheck wwt1;
       
   773 	WalkWindowTree(wwt1,EWalkChildren);
       
   774 	}
       
   775 
       
   776 enum {ENullWsHandle=0xFFFFFFFF};	// Events delivered to this handle are thrown away
       
   777 TBool CWsWindowBase::IsClientHandleInUse(TUint32 aHandle)
       
   778 	{
       
   779 	if (aHandle==static_cast<TUint>(ENullWsHandle))		//This value has a special meaning in test code
       
   780 		return EFalse;
       
   781 	CWsObjectIx* index=iWsOwner->ObjectIndex();
       
   782 	const CWsObject* obj;
       
   783 	TInt length=index->Length();
       
   784 	TInt ii;
       
   785 	for (ii=0;ii<length;++ii)
       
   786 		{
       
   787 		obj=index->At(ii);
       
   788 		if (obj && (obj->Type()==WS_HANDLE_WINDOW || obj->Type()==WS_HANDLE_GROUP_WINDOW))
       
   789 			{
       
   790 			if (STATIC_CAST(const CWsWindowBase*,obj)->ClientHandle()==aHandle)
       
   791 				return ETrue;
       
   792 			}
       
   793 		}
       
   794 	return EFalse;
       
   795 	}
       
   796 
       
   797 #endif