windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp
changeset 0 5d03bc08d59c
child 84 de3e07519bb7
child 116 171fae344dd4
child 152 9f1c3fea0f87
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 // Client window functions
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "W32CLICK.H"
       
    19 #include <graphics/wselement.h>
       
    20 #include "server.h"
       
    21 #include "cliwin.h"
       
    22 #include "gc.h"
       
    23 #include "rootwin.h"
       
    24 #include "windowgroup.h"
       
    25 #include "walkwindowtree.h"
       
    26 #include "ScrDev.H"
       
    27 #include "wstop.h"
       
    28 #include "EVQUEUE.H"
       
    29 #include "KEYCLICK.H"
       
    30 #include "panics.h"
       
    31 #include "password.h"
       
    32 #include "pointer.h"
       
    33 #include "EVENT.H"
       
    34 #include "backedupwindow.h"
       
    35 #include "redrawmsgwindow.h"
       
    36 #include "windowelementset.h"
       
    37 
       
    38 
       
    39 
       
    40 
       
    41 TBool CWsClientWindow::iAbsoluteFading = EFalse;
       
    42 
       
    43 const TPoint corner1[1]={TPoint(1,1)};
       
    44 const TPoint corner2[2]={TPoint(2,1),TPoint(1,1)};
       
    45 const TPoint corner3[2]={TPoint(3,1),TPoint(1,2)};
       
    46 const TPoint corner5[4]={TPoint(5,1),TPoint(3,1),TPoint(2,1),TPoint(1,2)};
       
    47 
       
    48 /*CWsClientWindow*/
       
    49 
       
    50 CWsClientWindow::CWsClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsWindow(aOwner,WS_HANDLE_WINDOW,aScreen)
       
    51 	{
       
    52 	iWinType=EWinTypeClient;
       
    53 	}
       
    54 
       
    55 void CWsClientWindow::ConstructL(const TWsClCmdCreateWindow &aCmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid)
       
    56 	{
       
    57 	CWsWindow::Construct();
       
    58 	NewObjL();
       
    59 	if (aCmd.clientHandle==NULL)
       
    60 		OwnerPanic(EWservPanicNullHandle);
       
    61 #if defined(_DEBUG)
       
    62 	if (IsClientHandleInUse(aCmd.clientHandle))
       
    63 		OwnerPanic(EWservPanicDuplicateHandle);
       
    64 #endif
       
    65 	iPointerFilter=EPointerFilterEnterExit|EPointerFilterMove|EPointerFilterDrag;
       
    66 	iClientHandle=aCmd.clientHandle;
       
    67 	CWsWindow* inherit=static_cast<CWsWindow *>(aParent);
       
    68 	if (aParent->WinType()==EWinTypeGroup)
       
    69 		inherit=RootWindow();
       
    70 	SetPointerCursor(aParent->PointerCursor());
       
    71 	iAbs=inherit->Abs();
       
    72 	iOrigin=aParent->Origin();
       
    73 	iRel.iBr.iX=inherit->Rel().iBr.iX-inherit->Rel().iTl.iX;
       
    74 	iRel.iBr.iY=inherit->Rel().iBr.iY-inherit->Rel().iTl.iY;
       
    75 	switch(aCmd.type)
       
    76 		{
       
    77 		case EWinRedraw:
       
    78 			iRedraw=new(ELeave) CWsRedrawMsgWindow(this);
       
    79 			break;
       
    80 		case EWinBackedUp:
       
    81 			iRedraw=new(ELeave) CWsBackedUpWindow(this, aCmd.displayMode);
       
    82 			iAbs.iBr=iAbs.iTl;
       
    83 			iRel.iBr=iRel.iTl;
       
    84 			break;
       
    85 		case EWinBlank:
       
    86 			iRedraw=new(ELeave) CWsBlankWindow(this);
       
    87 			break;
       
    88 		default:
       
    89 			OwnerPanic(EWservPanicRedrawType);
       
    90 		}
       
    91 	ResetHiddenFlag();
       
    92 	SetCornerTypeL(EWindowCornerSquare,0,NULL,EFalse);
       
    93 	CWsWindowBase::ConstructL(aParent);
       
    94 	if (aScreenDeviceIsInvalid)
       
    95 		{
       
    96 		iFlags|=EFlagScreenDeviceInvalid;
       
    97 		ResetHiddenFlag();
       
    98 		}
       
    99 	iRedraw->ConstructL();
       
   100 	}
       
   101 
       
   102 void CWsClientWindow::GetBaseAreaOfNode(RWsRegion &aRegion) const
       
   103     {
       
   104     if (iBaseArea)
       
   105         {
       
   106         aRegion.Copy(*iBaseArea);
       
   107         }
       
   108     aRegion.ClipRect(iAbs);
       
   109     }
       
   110 
       
   111 void CWsClientWindow::ClipRegionToBaseArea(RWsRegion &aRegion) const
       
   112     {
       
   113     if (iBaseArea)
       
   114         {
       
   115         aRegion.Intersect(*iBaseArea);
       
   116         }
       
   117     aRegion.ClipRect(iAbs);
       
   118     }
       
   119 
       
   120 void CWsClientWindow::GetClippedBaseArea(RWsRegion &aRegion) const
       
   121 	{
       
   122 	const CWsWindowBase* ancestor = BaseParent();	    
       
   123 	GetBaseAreaOfNode(aRegion);	
       
   124 	while (ancestor && ancestor->WinType() == EWinTypeClient)
       
   125 	    {
       
   126 	    static_cast<const CWsClientWindow*>(ancestor)->ClipRegionToBaseArea(aRegion);       
       
   127 	    ancestor = ancestor->BaseParent();
       
   128 	    }
       
   129 	}
       
   130 
       
   131 void CWsClientWindow::GetOpaqueBaseAreaOfNode(RWsRegion &aRegion) const
       
   132     {
       
   133     if (IsTranslucent())
       
   134         {
       
   135         if (iUserDefinedOpaqueRegion)
       
   136             {
       
   137             aRegion.Copy(*iUserDefinedOpaqueRegion);
       
   138             aRegion.ClipRect(iAbs);
       
   139             }
       
   140         else
       
   141             {
       
   142             aRegion.Clear();
       
   143             }
       
   144         }
       
   145     else
       
   146         {
       
   147         GetBaseAreaOfNode(aRegion);
       
   148         }
       
   149     }
       
   150 
       
   151 void CWsClientWindow::ClipRegionToOpaqueBaseArea(RWsRegion& aRegion) const
       
   152     {
       
   153     if (IsTranslucent())
       
   154         {
       
   155         if (iUserDefinedOpaqueRegion)
       
   156             {
       
   157             aRegion.Intersect(*iUserDefinedOpaqueRegion);
       
   158             aRegion.ClipRect(iAbs);
       
   159             }
       
   160         else
       
   161             {
       
   162             aRegion.Clear();
       
   163             }
       
   164         }
       
   165     else
       
   166         {
       
   167         ClipRegionToBaseArea(aRegion);
       
   168         }
       
   169     }
       
   170 
       
   171 void CWsClientWindow::GetOpaqueClippedBaseArea(RWsRegion &aRegion) const
       
   172 	{
       
   173 	const CWsWindowBase* ancestor = BaseParent();
       
   174 	GetOpaqueBaseAreaOfNode(aRegion);
       
   175 	while (ancestor && ancestor->WinType() == EWinTypeClient)
       
   176 	    {
       
   177 	    static_cast<const CWsClientWindow*>(ancestor)->ClipRegionToOpaqueBaseArea(aRegion);
       
   178 	    ancestor = ancestor->BaseParent();
       
   179 	    }
       
   180 	}
       
   181 
       
   182 TInt CWsClientWindow::GetNonOpaqueBaseAreaOfNode(RWsRegion &aRegion) const
       
   183     {
       
   184     aRegion.Clear();
       
   185     if (IsTranslucent())
       
   186         {
       
   187         if(iUserDefinedTransparentRegion)
       
   188             {
       
   189             aRegion.Copy(*iUserDefinedTransparentRegion);
       
   190             aRegion.ClipRect(iAbs);
       
   191             return KErrNone;
       
   192             }
       
   193         }  
       
   194     return KErrNotFound;
       
   195     }
       
   196 
       
   197 void CWsClientWindow::ResetHiddenFlag()
       
   198 //
       
   199 // Reset the status of the hidden flag based on the current states of the active and invisible flags
       
   200 //
       
   201 	{
       
   202 	CWsClientWindow *parent=static_cast<CWsClientWindow*>(iParent);
       
   203 
       
   204 	TBool wasHidden = iFlags&EFlagHidden;
       
   205 	TBool nowHidden = (parent==NULL || 
       
   206 		              (parent->WinType()==EWinTypeClient && !parent->IsVisible()) ||
       
   207 	                  !(iFlags&EFlagActive) ||
       
   208 	                  (iFlags&EFlagInvisible) ||
       
   209 			          (iFlags&EFlagScreenDeviceInvalid));
       
   210 
       
   211 	if (nowHidden)
       
   212 		{
       
   213 		iFlags|=EFlagHidden;
       
   214 		iFlags&=~EFlagDrawnToScreen;
       
   215 		}
       
   216 	else
       
   217 		{
       
   218 		iFlags&=~EFlagHidden;
       
   219 		}
       
   220 	if ((!nowHidden) != (!wasHidden))
       
   221 		{
       
   222 		// intentionally call the screen directly
       
   223 		iScreen->ScheduleRegionUpdate(&iVisibleRegion);
       
   224 		
       
   225 		WS_ASSERT_DEBUG(!iDirtyWindowRegion.CheckError(),EWsPanicErrorInRegion);
       
   226 		WS_ASSERT_DEBUG(!iDirtySpriteRegion.CheckError(),EWsPanicErrorInRegion);
       
   227 	//	WS_ASSERT_DEBUG(!InvalidArea().CheckError(),EWsPanicErrorInRegion);		//error flag in invalid area may be set in OOM cases
       
   228 																				//thus the assert statement is caused to fail
       
   229 		if (wasHidden && iScreen->ChangeTracking() && 
       
   230 				(!iDirtyWindowRegion.IsEmpty() || !iDirtySpriteRegion.IsEmpty() || !InvalidArea().IsEmpty()))
       
   231 			{
       
   232 			// Window has just become visible, schedule it
       
   233 			iScreen->ScheduleWindow(this);
       
   234 			}
       
   235 		}
       
   236 	}
       
   237 	
       
   238 void CWsClientWindow::ResetHiddenFlags()
       
   239 	{
       
   240 	CWsClientWindow *win=this;
       
   241 	FOREVER
       
   242 		{
       
   243 		TUint oldHiddenFlag=win->iFlags&EFlagHidden;
       
   244 		win->ResetHiddenFlag();
       
   245 		if ((win->iFlags&EFlagHidden)!=oldHiddenFlag)	// If hidden status hasn't changed nothing to do
       
   246 			{
       
   247 			win->SetElementOpacity(IsVisible() ? 0xFF : 0x00);	// Update element visibility
       
   248 			if (win->Child())
       
   249 				{
       
   250 				win=win->Child();
       
   251 				continue;
       
   252 				}
       
   253 			}
       
   254 		if (win==this)
       
   255 			return;
       
   256 		while(!win->NextSibling())
       
   257 			{
       
   258 			win=(CWsClientWindow *)win->BaseParent();
       
   259 			if (win==this)
       
   260 				return;
       
   261 			}
       
   262 		win=win->NextSibling();
       
   263 		} // for loop ends
       
   264 	}
       
   265 
       
   266 void CWsClientWindow::OffsetBaseArea(const TPoint &aOffset)
       
   267 	{
       
   268 	iBaseArea->Offset(aOffset);
       
   269 	//If the given window's position changes, then update.
       
   270 	if (aOffset.iX || aOffset.iY)
       
   271 		{
       
   272 		UpdateElementExtent(&aOffset);
       
   273 		}
       
   274 	}
       
   275 
       
   276 void CWsClientWindow::CalcBaseArea()
       
   277 //
       
   278 // The windows basic area before any clipping is done
       
   279 //
       
   280 	{
       
   281 	TInt cornerType=iCornerData&ECornerTypeMask;
       
   282 	if (cornerType==EWindowCornerRegion)
       
   283 		iBaseArea->ClipRect(FullRect());
       
   284 	else
       
   285 		{
       
   286 		TSize size=Size();
       
   287 		iBaseArea->Clear();
       
   288 		const TPoint *corners=NULL;
       
   289 		TInt count=0;
       
   290 		switch(cornerType)
       
   291 			{
       
   292 			case EWindowCorner1:
       
   293 				count=sizeof(corner1)/sizeof(TPoint);
       
   294 				corners=corner1;
       
   295 				break;
       
   296 			case EWindowCorner2:
       
   297 				count=sizeof(corner2)/sizeof(TPoint);
       
   298 				corners=corner2;
       
   299 				break;
       
   300 			case EWindowCorner3:
       
   301 				count=sizeof(corner3)/sizeof(TPoint);
       
   302 				corners=corner3;
       
   303 				break;
       
   304 			case EWindowCorner5:
       
   305 				count=sizeof(corner5)/sizeof(TPoint);
       
   306 				corners=corner5;
       
   307 				break;
       
   308 			default:
       
   309 				break;
       
   310 			}
       
   311 		TInt top=0;
       
   312 		TInt bot=size.iHeight;
       
   313 		for(TInt index=0;index<count;index++)
       
   314 			{
       
   315 			TInt xadjust=corners[index].iX;
       
   316 			TInt yadjust=corners[index].iY;
       
   317 			if ((iCornerData&(EWindowCornerNotTL|EWindowCornerNotTR))!=(EWindowCornerNotTL|EWindowCornerNotTR))
       
   318 				{
       
   319 				iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotTL?0:xadjust,top,
       
   320 										 size.iWidth-(iCornerData&EWindowCornerNotTR?0:xadjust),top+yadjust));
       
   321 				top+=yadjust;
       
   322 				}
       
   323 			if ((iCornerData&(EWindowCornerNotBL|EWindowCornerNotBR))!=(EWindowCornerNotBL|EWindowCornerNotBR))
       
   324 				{
       
   325 				iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotBL?0:xadjust,bot-yadjust,
       
   326 										 size.iWidth-(iCornerData&EWindowCornerNotBR?0:xadjust),bot));
       
   327 				bot-=yadjust;
       
   328 				}
       
   329 			}
       
   330 		iBaseArea->AddRect(TRect(0,top,size.iWidth,bot));
       
   331 		iBaseArea->Offset(Origin());
       
   332 		iBaseArea->ClipRect(FullRect());
       
   333 		iBaseArea->Sort();
       
   334 		}
       
   335 	}
       
   336 
       
   337 void CWsClientWindow::GenerateArea(RWsRegion &aArea, TBool aClipTranslucent) const
       
   338 //
       
   339 // Create the window area list.
       
   340 //
       
   341 	{
       
   342 	aArea.Clear();
       
   343 	if (IsVisible())
       
   344 		{
       
   345 		aArea.Copy(*iBaseArea);
       
   346 		aArea.ClipRect(iAbs);
       
   347 		const CWsClientWindow *win=this;
       
   348 		FOREVER
       
   349 			{
       
   350 			if (win->IsTopClientWindow())
       
   351 				break;
       
   352 			ClipWindows(aArea,(CWsClientWindow *)win->BaseParent()->BaseChild(),win,aClipTranslucent);
       
   353 			win=(CWsClientWindow *)win->iParent;
       
   354 			}
       
   355 		TInt tidyCount=0;
       
   356 		for(const CWsTopClientWindow *cwin=RootWindow()->FirstTopClientWindow();aArea.Count() && cwin!=win;cwin=cwin->NextSiblingMultiParent())
       
   357 			{
       
   358 			if (!tidyCount--)
       
   359 				{
       
   360 				aArea.Tidy();
       
   361 				tidyCount=ETidyCountSetting;	// Tidy every ETidyCountSetting times around
       
   362 				}
       
   363 			if (cwin->IsVisible())
       
   364 				{
       
   365 				if (cwin->IsTranslucent() && !aClipTranslucent)
       
   366 					{
       
   367 					if (cwin->iUserDefinedOpaqueRegion)
       
   368 						{
       
   369 						aArea.SubRegion(*cwin->iUserDefinedOpaqueRegion);
       
   370 						}
       
   371 					}
       
   372 				else
       
   373 					{
       
   374 					aArea.SubRegion(*cwin->iBaseArea);
       
   375 					}
       
   376 				}
       
   377 			}
       
   378 		aArea.Tidy();
       
   379 		}
       
   380 	}
       
   381 
       
   382 void CWsClientWindow::ClipWindows(TRegion &region,const CWsClientWindow *start, const CWsClientWindow *end, TBool aClipTranslucent)
       
   383 //
       
   384 // Remove out of the region the opaque part of the abs rect of all the windows starting from 'start'
       
   385 // along the sibling list to (and not including) the end window.
       
   386 //
       
   387 	{
       
   388 	for(const CWsClientWindow *win=start;region.Count() && win!=end;win=win->NextSibling())
       
   389 		{
       
   390 		if (win->IsVisible())
       
   391 			{
       
   392 			if (win->IsTranslucent() && !aClipTranslucent)
       
   393 				{
       
   394 				if (win->iUserDefinedOpaqueRegion)
       
   395 					{
       
   396 					region.SubRegion(*win->iUserDefinedOpaqueRegion);
       
   397 					}
       
   398 				}
       
   399 			else
       
   400 				{
       
   401 				region.SubRegion(*win->iBaseArea);
       
   402 				}
       
   403 			}
       
   404 		}
       
   405 	}
       
   406 
       
   407 void CWsClientWindow::GenerateTopRegion(RWsRegion& aRegion) const
       
   408 	{
       
   409 	GenerateArea(aRegion,ETrue);
       
   410 	if (iChild)
       
   411 		ClipWindows(aRegion,Child(),NULL,ETrue);
       
   412 	}
       
   413 
       
   414 void CWsClientWindow::GenerateWindowRegion(RWsRegion &aRegion) const
       
   415 //
       
   416 // Calculate the windows clipping region without using the usual stored iArea or iRegion fields
       
   417 // this function is used by the screen backup code to calculate "what if" regions to work out
       
   418 // whether something would be visible if the backed up window didn't exist, on this basis we
       
   419 // don't want to modify the existing copies of iArea & iRegion.
       
   420 //
       
   421 	{
       
   422 	GenerateArea(aRegion,EFalse);
       
   423 	if (iChild)
       
   424 		ClipWindows(aRegion,Child(),NULL,EFalse);
       
   425 	}
       
   426 
       
   427 const TRegion *CWsClientWindow::DrawingRegion()
       
   428 	{
       
   429 	return (&iRedraw->BaseDrawRegion());
       
   430 	}
       
   431 
       
   432 void CWsClientWindow::RecalcChildAbs(const TPoint *aOffset)
       
   433 	{
       
   434 	CWsClientWindow *win=this;
       
   435 	FOREVER
       
   436 		{
       
   437 		FOREVER
       
   438 			{
       
   439 			win->SetAbsFromRel();
       
   440 			if (aOffset)
       
   441 				win->OffsetBaseArea(*aOffset);
       
   442 			if (win->Child()==NULL)
       
   443 				break;
       
   444 			win=win->Child();
       
   445 			}
       
   446 		FOREVER
       
   447 			{
       
   448 			if (win==this)
       
   449 				return;
       
   450 			if (win->NextSibling()!=NULL)
       
   451 				{
       
   452 				win=win->NextSibling();
       
   453 				break;
       
   454 				}
       
   455 			win=(CWsClientWindow *)win->iParent;	// The cast is safe as the loop is aborted when win==this
       
   456 			}
       
   457 		}
       
   458 	}
       
   459 
       
   460 void CWsClientWindow::SetAbsFromRel()
       
   461 	{
       
   462 	iOrigin=iRel.iTl+iParent->Origin();
       
   463 	iAbs=iRel;
       
   464 	iAbs.Move(iParent->Origin());
       
   465 	iAbs.Intersection(iParent->AbsRect());
       
   466 	}
       
   467 
       
   468 void CWsClientWindow::SetExtentL(const TPoint *aPos,const TSize *aSize)
       
   469 	{
       
   470 	if (iParent==NULL)
       
   471 		OwnerPanic(EWservPanicParentDeleted);
       
   472 	TPoint offset = TPoint(0,0);
       
   473 	TSize oldSize;
       
   474 	TSize newSize;
       
   475 	TBool sizeChanged = EFalse;
       
   476 	TBool posChanged = EFalse;
       
   477 	
       
   478 	if (aPos)
       
   479 		{
       
   480 		offset = *aPos+iParent->Origin()-iOrigin;
       
   481 		if (offset.iX != 0 || offset.iY != 0)
       
   482 			{
       
   483 			posChanged = ETrue;
       
   484 			}
       
   485 		}
       
   486 		
       
   487 	if (posChanged)
       
   488 		{
       
   489 		TWalkWindowTreeScheduleRedraws wwt;
       
   490 		WalkWindowTree(wwt, EWalkChildren);
       
   491 		}
       
   492 	
       
   493 	if (aSize)
       
   494 		{
       
   495 		newSize=*aSize;
       
   496 		if (newSize.iWidth<0)
       
   497 			newSize.iWidth=0;
       
   498 		if (newSize.iHeight<0)
       
   499 			newSize.iHeight=0;
       
   500 		// This should be the only part of resizing that can fail
       
   501 		// and it can only fail for backedup windows.
       
   502 		iRedraw->PrepareForResizeL(newSize,oldSize);
       
   503 		sizeChanged = *aSize != iRel.Size();
       
   504 		}
       
   505 
       
   506 	if (posChanged)
       
   507 		{
       
   508 		iRel.Move(offset);
       
   509 		RecalcChildAbs(&offset);      // Also calls UpdateElementExtent(offset)
       
   510 		TWalkWindowTreeOffsetTransparentRegions offsetTransparent(offset);
       
   511 		WalkWindowTree(offsetTransparent, EWalkChildren);
       
   512 		}
       
   513 
       
   514 	if (sizeChanged)
       
   515 		{
       
   516 		iRel.SetSize(newSize);
       
   517 		RecalcChildAbs(NULL);
       
   518 		CalcBaseArea();
       
   519 		iRedraw->Resize(newSize,oldSize);
       
   520 		if (Redraw()->HasElement())
       
   521 		    UpdateElementExtent();
       
   522 		}
       
   523 	
       
   524 	if ((posChanged || sizeChanged) && Redraw()->HasElement())
       
   525 		{
       
   526 		TRect interSection(iParent->Origin(), iParent->Size());
       
   527 		interSection.Intersection(FullRect());
       
   528 		if (interSection == FullRect())
       
   529 			{
       
   530 			// There is no any clipping in this case
       
   531 			interSection = TRect();
       
   532 			}
       
   533 		// Get the corresponding source rectangle for the element
       
   534 		if (!iOriginalSrcElementRect.IsEmpty() && !iOriginalDestElementRect.IsEmpty() && !iAbs.IsEmpty())
       
   535 			{
       
   536 			MWsElement* element = Screen()->WindowElements().GetElementFromWindow(*this);
       
   537 			if (element)
       
   538 				{
       
   539 				element->SetDestinationClippingRect(interSection);
       
   540 				}
       
   541 			}
       
   542 		}	
       
   543 	
       
   544 	if (posChanged || sizeChanged)
       
   545 		{
       
   546 		iRedraw->ClipInvalidRegion(TRect(iRel.Size()));
       
   547 		iRedraw->Moved();
       
   548 		ScheduleRegionUpdate(NULL);
       
   549 		TWalkWindowTreeRecalcOpaque recalcOpaque;
       
   550 		WalkWindowTree(recalcOpaque, EWalkChildren);
       
   551 
       
   552 		MWsWindowTreeObserver* windowTreeObserver = Screen()->WindowTreeObserver();
       
   553 		if (windowTreeObserver)
       
   554 			{
       
   555 			windowTreeObserver->NodeExtentChanged(*this, FullRect());
       
   556 			}
       
   557 		}
       
   558 	}
       
   559 
       
   560 
       
   561 void CWsClientWindow::GetElementFlipAndRotation(TBool& aElemetFlip, MWsElement::TElementRotation& aElemenetRotation)
       
   562     {
       
   563     MWsElement* element = Screen()->WindowElements().GetElementFromWindow(*this);
       
   564     if (element)
       
   565         {
       
   566         aElemetFlip = element->SourceFlipping();
       
   567         aElemenetRotation = element->SourceRotation();
       
   568         }
       
   569     }
       
   570 
       
   571 void CWsClientWindow::Scroll(const TRect &aClipRect, const TPoint &aOffset, const TRect &aRect)
       
   572 	{
       
   573 	if (iParent==NULL)
       
   574 		OwnerPanic(EWservPanicParentDeleted);
       
   575 	
       
   576 //
       
   577 	iRedraw->Scroll(aClipRect, aOffset,aRect);
       
   578 //
       
   579 	CWsTop::TriggerRedraws(RootWindow());
       
   580 	}
       
   581 
       
   582 void CWsClientWindow::DeleteBaseArea()
       
   583 	{
       
   584 	WS_ASSERT_DEBUG(iBaseArea!=&nullRegion, EWsPanicRegionNull);
       
   585  	if ((iCornerData&ECornerTypeMask)==EWindowCornerRegion)
       
   586 		((RWsRegion *)iBaseArea)->Destroy();
       
   587 	else
       
   588 		{
       
   589 		delete iBaseArea;
       
   590 		}
       
   591  	iBaseArea=NULL;
       
   592 	}
       
   593 
       
   594 CWsClientWindow::~CWsClientWindow()
       
   595 	{
       
   596 	while(iVisibleRegionTrackingCounter>0)
       
   597 		{
       
   598 		SetupVisibleRegionTracking(EFalse);
       
   599 		}
       
   600 	if (iBaseWinFlags&EBaseWinNodeCreated)
       
   601 		{
       
   602 		MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
   603 		if (windowTreeObserver)
       
   604 			{
       
   605 			windowTreeObserver->NodeReleased(*this);
       
   606 			iBaseWinFlags &= ~EBaseWinNodeCreated;
       
   607 			}
       
   608 		}
       
   609 	Shutdown();
       
   610 	SetUserTransparentRegion(0);
       
   611 	CWsPassword::WindowDestroyed(this);
       
   612 	}
       
   613 
       
   614 void CWsClientWindow::Shutdown()
       
   615 //
       
   616 // Destroy a window, disconnects from the window tree and destroys all it's child windows
       
   617 //
       
   618 	{
       
   619 	iFlags|=EFlagShutDownInProgress;
       
   620 	if (CClick::IsHandler())
       
   621 		{
       
   622 		TWindowCloseData params;
       
   623 		params.iClientHandle=iClientHandle;
       
   624 		//if parent already shutdown (or disconnected) send 0
       
   625 		params.iWindowGroupId = (iParent) ? WinGroup()->Identifier() : 0;
       
   626 		CClick::OtherEvent(EEventWindowClose,&params);
       
   627 		}
       
   628 
       
   629 	RemoveAllKeyRects();
       
   630 	while(iWinGcList)
       
   631 		iWinGcList->Deactivate();
       
   632 //
       
   633 	iFlags|=EFlagInvisible;		// First make it invisble
       
   634 	if (iParent)				// In case window wasn't fully constructed
       
   635 		ResetHiddenFlags();
       
   636 //
       
   637 	CWsWindow::Shutdown();
       
   638 	DeleteBaseArea();
       
   639 	CWsPointerBuffer::Disconnect(this);
       
   640 	iFlags&=~EFlagShutDownInProgress;
       
   641 	}
       
   642 
       
   643 void CWsClientWindow::Activate()
       
   644 	{
       
   645 	if (iFlags&EFlagActive)
       
   646 		OwnerPanic(EWservPanicWindowActive);
       
   647 	iFlags|=EFlagActive;
       
   648 
       
   649 	ResetHiddenFlags();
       
   650 
       
   651 	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
   652 	if (windowTreeObserver)
       
   653 		{
       
   654 		windowTreeObserver->NodeExtentChanged(*this, FullRect());
       
   655 		windowTreeObserver->NodeActivated(*this);
       
   656 		}
       
   657 	}
       
   658 
       
   659 TBool CWsClientWindow::IsActivated() const
       
   660 	{
       
   661 	return (iFlags&EFlagActive)!=EFalse;
       
   662 	}
       
   663 
       
   664 void CWsClientWindow::SetCornerTypeL(TCornerType aCornerType, TInt aCornerFlags, TRegion *aNewBaseArea, TBool aNotifyShapeChanged)
       
   665 	{
       
   666 	TRegion *baseArea=NULL;
       
   667 	if (aCornerFlags&ECornerTypeMask)
       
   668 		OwnerPanic(EWservPanicCornerParams);
       
   669 	
       
   670  	switch (aCornerType)
       
   671 		{
       
   672 		case EWindowCornerSquare:
       
   673 			baseArea=new(ELeave) TRegionFix<1>();
       
   674 			break;
       
   675 		case EWindowCorner1:
       
   676 			baseArea=new(ELeave) TRegionFix<3>();
       
   677 			break;
       
   678 		case EWindowCorner2:
       
   679 		case EWindowCorner3:
       
   680 			baseArea=new(ELeave) TRegionFix<5>();
       
   681 			break;
       
   682 		case EWindowCorner5:
       
   683 			baseArea=new(ELeave) TRegionFix<9>();
       
   684 			break;
       
   685 		case EWindowCornerRegion:
       
   686 			User::LeaveIfNull(baseArea=aNewBaseArea);
       
   687 			baseArea->Offset(Origin());
       
   688 			break;
       
   689 		default:
       
   690 			OwnerPanic(EWservPanicCornerParams);
       
   691 		}
       
   692 	DeleteBaseArea();
       
   693 	iCornerData=aCornerType;
       
   694 	iCornerData|=aCornerFlags;
       
   695 	iBaseArea=baseArea;
       
   696 	CalcBaseArea();
       
   697 	ScheduleRegionUpdate(NULL);
       
   698 
       
   699 	if ( aNotifyShapeChanged )
       
   700 		{
       
   701 		MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
   702 		if (windowTreeObserver)
       
   703 			{
       
   704 			windowTreeObserver->AttributeChanged(*this, MWsWindowTreeObserver::EWindowShape);
       
   705 			}
       
   706 		}
       
   707 	}
       
   708 
       
   709 void CWsClientWindow::SetVisible(TBool aState)
       
   710 	{
       
   711 	if (aState)
       
   712 		{
       
   713 		if (iParent==NULL)
       
   714 			OwnerPanic(EWservPanicParentDeleted);
       
   715 		if (!(iFlags&EFlagInvisible))	// Already visible
       
   716 			return;
       
   717 		iFlags&=~EFlagInvisible;
       
   718 		ResetHiddenFlags();
       
   719 		}
       
   720 	else
       
   721 		{
       
   722 		if (iFlags&EFlagInvisible || !iParent)	// Already invisible or parent has been deleted
       
   723 			return;
       
   724 		TWalkWindowTreePurgeEvents wwt;
       
   725 		WalkWindowTree(wwt,EWalkChildren);		// Destroy all events on this and all children
       
   726 		iFlags|=EFlagInvisible;
       
   727 		ResetHiddenFlags();
       
   728 		}
       
   729 	
       
   730 	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
   731 	if (windowTreeObserver)
       
   732 		{
       
   733 		windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EVisible, aState);
       
   734 		}
       
   735 	}
       
   736 
       
   737 void CWsClientWindow::CommandL(TInt aOpcode, const TAny *aCmdData)
       
   738 	{
       
   739 #ifdef _DEBUG
       
   740 	// Save root window for performing CheckTree at the end of this func.
       
   741 	// When aOpcode is EWsWinOpFree, this object would've been destroyed
       
   742 	// and a call to RootWindow() in that case would be impossible
       
   743 	CWsRootWindow* rootWindow=RootWindow();
       
   744 #endif
       
   745 	TWsWinCmdUnion pData;
       
   746 	pData.any=aCmdData;
       
   747 	if (CWsWindowBase::CommandL(aOpcode,pData)==EFalse)
       
   748 		{
       
   749 		switch(aOpcode)
       
   750 			{
       
   751 			case EWsWinOpActivate:
       
   752 				Activate();
       
   753 				break;
       
   754 			case EWsWinOpSetPos:
       
   755 				SetExtentL(pData.pos,NULL);
       
   756 				break;
       
   757 			case EWsWinOpSetExtent:
       
   758 			case EWsWinOpSetExtentErr:
       
   759 				SetExtentL(&pData.SetEx->pos,&pData.SetEx->size);
       
   760 				break;
       
   761 			case EWsWinOpSetSize:
       
   762 			case EWsWinOpSetSizeErr:
       
   763 				SetExtentL(NULL,pData.size);
       
   764 				break;
       
   765 			case EWsWinOpInquireOffset:
       
   766 				CWsClient::ReplyPoint(InquireOffset(*pData.UInt));
       
   767 				break;
       
   768 			case EWsWinOpPosition:
       
   769 				CWsClient::ReplyPoint(iRel.iTl);
       
   770 				break; 
       
   771 			case EWsWinOpAbsPosition:
       
   772 				CWsClient::ReplyPoint(iOrigin);
       
   773 				break;
       
   774 			case EWsWinOpSize:
       
   775 				CWsClient::ReplySize(iRel.Size());
       
   776 				break;
       
   777 			case EWsWinOpTestInvariant:
       
   778 				SetReply(EFalse);
       
   779 				break;
       
   780 			case EWsWinOpPointerFilter:
       
   781 				{
       
   782 				TUint old=iPointerFilter;
       
   783 				iPointerFilter&=~pData.PointerFilter->mask;
       
   784 				iPointerFilter|=pData.PointerFilter->mask&pData.PointerFilter->flags;
       
   785 				if (old&EPointerFilterEnterExit)
       
   786 					TWsPointer::ReLogWindow(this);
       
   787 				}
       
   788 				break;
       
   789 			case EWsWinOpSetPointerGrab:
       
   790 				if (*pData.Bool==EFalse)
       
   791 					iFlags&=~EFlagPointerGrab;
       
   792 				else
       
   793 					iFlags|=EFlagPointerGrab;
       
   794 				break;
       
   795 			case EWsWinOpClaimPointerGrab:
       
   796 				{
       
   797 				if (!iParent)
       
   798 					OwnerPanic(EWservPanicParentDeleted);		
       
   799 				
       
   800 				TInt errNo = TWsPointer::ClaimGrab(this,*pData.GrabControl);
       
   801 				if(TWsWinCmdGrabControl::ESendReply & pData.GrabControl->flags)
       
   802 					{
       
   803 					// To avoid the reply-generated-flush, only do this for the new APIs, not the old ones.					
       
   804 					SetReply(errNo);
       
   805 					}
       
   806 				}
       
   807 				break;
       
   808 			case EWsWinOpSetPointerCapture:
       
   809 				iFlags&=~(EFlagPointerCaptured|EFlagPointerCaptureDragDrop|EFlagPointerCaptureAllGroups);
       
   810 				if ((*pData.UInt)&RWindowBase::TCaptureFlagEnabled)
       
   811 					{
       
   812 					iFlags|=EFlagPointerCaptured;
       
   813 					if ((*pData.UInt)&RWindowBase::TCaptureFlagDragDrop)
       
   814 						iFlags|=EFlagPointerCaptureDragDrop;
       
   815 					if ((*pData.UInt)&RWindowBase::TCaptureFlagAllGroups)
       
   816 						iFlags|=EFlagPointerCaptureAllGroups;
       
   817 					
       
   818 					}
       
   819 				TWsPointer::ReLogPointersCurrentWindows();
       
   820 				break;
       
   821 			case EWsWinOpSetPointerCapturePriority:
       
   822 				iPointerCapturePriority=*pData.Int;
       
   823 				break;
       
   824 			case EWsWinOpGetPointerCapturePriority:
       
   825 				SetReply(iPointerCapturePriority);
       
   826 				break;
       
   827 			case EWsWinOpSetVisible:
       
   828 				SetVisible(*pData.Bool);
       
   829 				break;
       
   830 			case EWsWinOpScroll:
       
   831 				{
       
   832 				TPoint origin(0,0);
       
   833 				TRect src(TRect(origin,iRel.Size()));
       
   834 				src.Move(-pData.ScrollRect->offset);
       
   835 				Scroll(TRect(origin,iRel.Size()),pData.ScrollRect->offset,src);
       
   836 				}
       
   837 				break;
       
   838 			case EWsWinOpScrollClip:
       
   839 				{
       
   840 				TPoint origin(0,0);
       
   841 				TRect src(TRect(origin,iRel.Size()));
       
   842 				src.Move(-pData.ScrollRect->offset);
       
   843 				TRect clip(pData.ScrollRect->clip);
       
   844 				Scroll(clip,pData.ScrollRect->offset,src);
       
   845 				}
       
   846 				break;
       
   847 			case EWsWinOpScrollRect:
       
   848 				{
       
   849 				TRect src(pData.ScrollRect->rect);
       
   850 				Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src);
       
   851 				}
       
   852 				break;
       
   853 			case EWsWinOpScrollClipRect:
       
   854 				{
       
   855 				TRect src(pData.ScrollRect->rect);
       
   856 				TRect clip(pData.ScrollRect->clip);
       
   857 				Scroll(clip, pData.ScrollRect->offset,src);
       
   858 				}
       
   859 				break;
       
   860 			case EWsWinOpSetOrdinalPositionPri:
       
   861 				iOrdinalPriority=pData.OrdinalPos->ordinalPriority;
       
   862 				SetOrdinalPosition(pData.OrdinalPos->pos);
       
   863 				break;
       
   864 			case EWsWinOpSetShadowHeight:
       
   865 				OwnerPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client
       
   866 				break;
       
   867 			case EWsWinOpShadowDisabled:
       
   868 				OwnerPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client
       
   869 				break;
       
   870 			case EWsWinOpRequiredDisplayMode:
       
   871 				if (Backup()!=NULL)
       
   872 					OwnerPanic(EWservPanicBackupDisplayMode);
       
   873 				SetReply(SetRequiredDisplayModeL(*pData.DisplayMode));
       
   874 				break;
       
   875 			case EWsWinOpGetDisplayMode:
       
   876 				SetReply(DisplayMode());
       
   877 				break;
       
   878 			case EWsWinOpRequestPointerRepeatEvent:
       
   879 				{
       
   880 				if (!iParent)
       
   881 					OwnerPanic(EWservPanicParentDeleted);
       
   882 				TInt errNo = TWsPointer::RequestPointerRepeatEvent(this,*pData.RequestPointerRepeatEvent);				
       
   883 				if(TWsWinCmdRequestPointerRepeatEvent::ERepeatFlagsSendReply & pData.RequestPointerRepeatEvent->repeatFlags)
       
   884 					{
       
   885 					SetReply(errNo);
       
   886 					}
       
   887 				}
       
   888 				break;
       
   889 			case EWsWinOpCancelPointerRepeatEventRequest:
       
   890 				{
       
   891 				TInt errNo = TWsPointer::CancelPointerRepeatEventRequest(*pData.CancelPointerRepeatEventRequest);				
       
   892 				if(TWsWinCmdCancelPointerRepeatEventRequest::ECancelRepeatFlagsSendReply & pData.RequestPointerRepeatEvent->repeatFlags)
       
   893 					{
       
   894 					SetReply(errNo);
       
   895 					}
       
   896 				}
       
   897 				break;
       
   898 			case EWsWinOpAllocPointerMoveBuffer:
       
   899 				CWsPointerBuffer::ConnectL(this,pData.AllocPointerMoveBuffer->maxNumPoints,pData.AllocPointerMoveBuffer->flags);
       
   900 				iFlags|=EFlagUsingPointerBuffer|EFlagHasPointerBuffer;
       
   901 				break;
       
   902 			case EWsWinOpFreePointerMoveBuffer:
       
   903 				CWsPointerBuffer::Disconnect(this);
       
   904 				iFlags&=~(EFlagUsingPointerBuffer|EFlagHasPointerBuffer);
       
   905 				break;
       
   906 			case EWsWinOpRetrievePointerMoveBuffer:
       
   907 				CWsPointerBuffer::RetrievePointerMoveBuffer(this,*pData.Int);
       
   908 				break;
       
   909 			case EWsWinOpEnablePointerMoveBuffer:
       
   910 				if (!(iFlags&EFlagHasPointerBuffer))
       
   911 					OwnerPanic(EWservPanicNoPointerBuffer);
       
   912 				iFlags|=EFlagUsingPointerBuffer;
       
   913 				break;
       
   914 			case EWsWinOpDisablePointerMoveBuffer: 
       
   915 				iFlags&=~EFlagUsingPointerBuffer; 
       
   916 				/*Fall Through*/
       
   917 			case EWsWinOpDiscardPointerMoveBuffer:	
       
   918 				CWsPointerBuffer::DiscardPointerMoveBuffer(this);
       
   919 				break;
       
   920 			case EWsWinOpAddKeyRect:
       
   921 				AddKeyRectL(pData.AddKeyRect->rect, pData.AddKeyRect->scanCode, pData.AddKeyRect->activatedByPointerSwitchOn);
       
   922 				break;
       
   923 			case EWsWinOpRemoveAllKeyRects:
       
   924 				RemoveAllKeyRects();
       
   925 				break;
       
   926 			case EWsWinOpPasswordWindow:
       
   927 				if (!iParent)
       
   928 					OwnerPanic(EWservPanicParentDeleted);
       
   929 				CWsPassword::SetPasswordWindowL(this, *pData.PasswordMode);
       
   930 				break;
       
   931 			case EWsWinOpEnableBackup:
       
   932 				if (!iParent)
       
   933 					OwnerPanic(EWservPanicParentDeleted);
       
   934 				if (*pData.UInt==0)
       
   935 					iBackupsRequested|=EWindowBackupAreaBehind;		//For backwards compatibility
       
   936 				else
       
   937 					iBackupsRequested|=*pData.UInt;
       
   938 				break;
       
   939 			case EWsWinOpFadeBehind:
       
   940 				{
       
   941 				if (!iParent)
       
   942 					OwnerPanic(EWservPanicParentDeleted);
       
   943 				
       
   944 				TUint8 blackMap;
       
   945 				TUint8 whiteMap;
       
   946 				iScreen->GetFadingParams(blackMap,whiteMap);
       
   947 				SetFadeBehind(*pData.Bool);
       
   948 				TWalkWindowTreeSetFaded wwt(*pData.Bool,this,blackMap,whiteMap);
       
   949 				WalkWindowTree(wwt,EWalkBehind);
       
   950 				}
       
   951 				break;
       
   952 			case EWsWinOpGetIsFaded:
       
   953 				SetReply(iFadeCount);
       
   954 				break;
       
   955 			case EWsWinOpGetIsNonFading:
       
   956 				SetReply(iFlags&EFlagNonFadingWindow);
       
   957 				break;
       
   958 			case EWsWinOpMoveToGroup:
       
   959 				if (!iParent)
       
   960 					OwnerPanic(EWservPanicParentDeleted);
       
   961 				if (iParent->WinType()!=EWinTypeGroup)
       
   962 					OwnerPanic(EWservPanicNotTopClient);
       
   963 				((CWsTopClientWindow*)this)->DoMoveWindowL(*pData.Int);
       
   964 				break;
       
   965 			case EWsWinOpTestLowPriorityRedraw:
       
   966 				{
       
   967 				// This is purely for testing purposes
       
   968 				// Returns the redraw priority
       
   969 				TUint priority=0;
       
   970 				TPckgBuf<TUint> priBuf;
       
   971 				priority=WsOwner()->RedrawQueue()->RedrawPriority((CWsWindowRedraw*)this->iRedraw);
       
   972 				priBuf()=priority;
       
   973 				CWsClient::ReplyBuf(priBuf);
       
   974 				}
       
   975 				break;
       
   976 			case EWsWinOpEnableVisibilityChangeEvents:
       
   977 				iFlags |= EFlagGeneratesVisibilityEvents;
       
   978 				SetupVisibleRegionTracking(ETrue);
       
   979 				if (iFlags&EFlagActive)
       
   980 					{
       
   981 					iScreen->DoRedrawNow();
       
   982 					PossibleVisibilityChangedEvent(ETrue);
       
   983 					}
       
   984 				break;
       
   985 			case EWsWinOpDisableVisibilityChangeEvents:
       
   986 				iFlags &= ~EFlagGeneratesVisibilityEvents;
       
   987 				SetupVisibleRegionTracking(EFalse);
       
   988 				break;
       
   989 			case EWsWinOpSetTransparentRegion:
       
   990 				{
       
   991 				if (IsTranslucent())
       
   992 					{
       
   993 					TInt recs=*pData.Int;
       
   994 	 				RWsRegion* reg=recs>0? GetRegionFromClientL(iWsOwner,recs) : new(ELeave) RWsRegion;
       
   995 	 				SetUserTransparentRegion(reg);
       
   996 					SetReply(KErrNone);
       
   997 					}
       
   998 				else
       
   999 					{
       
  1000 					OwnerPanic(EWservPanicTransparencyObjNotCreated);	
       
  1001 					}				
       
  1002 				}
       
  1003 				break;
       
  1004 			case EWsWinOpSetTransparencyPolicy:
       
  1005 				{
       
  1006 				if (IsTranslucent())
       
  1007 					SetReply(KErrNone);
       
  1008 				else
       
  1009 					OwnerPanic(EWservPanicTransparencyObjNotCreated);
       
  1010 				}
       
  1011 				break;
       
  1012 			case EWsWinOpSetTransparencyAlphaChannel:
       
  1013 				{
       
  1014 				iFlags |= static_cast<TUint>(EFlagHasAlpha);
       
  1015 				SetReply(KErrNone);
       
  1016 				
       
  1017 				MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
  1018 				if (windowTreeObserver)
       
  1019 					{
       
  1020 					windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EAlphaChannelTransparencyEnabled, ETrue);
       
  1021 					}
       
  1022 				break;
       
  1023 				}			
       
  1024 			default:
       
  1025 				if (iRedraw->CommandL(aOpcode,pData)==EFalse)
       
  1026 					{
       
  1027 					OwnerPanic(EWservPanicOpcode);
       
  1028 					}
       
  1029 			}
       
  1030 		}
       
  1031 #if defined(_DEBUG)
       
  1032 	rootWindow->CheckTree();
       
  1033 #endif
       
  1034 	}
       
  1035 
       
  1036 void CWsClientWindow::GcActivated(CWsGc *aGc)
       
  1037 	{
       
  1038 	aGc->SetNextWinGc(iWinGcList);
       
  1039 	iWinGcList=aGc;
       
  1040 	}
       
  1041 
       
  1042 void CWsClientWindow::GcDeactivated(CWsGc *aGc)
       
  1043 	{
       
  1044 	if (aGc==iWinGcList)
       
  1045 		iWinGcList=aGc->NextWinGc();
       
  1046 	else
       
  1047 		{
       
  1048 		CWsGc *gc=iWinGcList;
       
  1049 		CWsGc *next;
       
  1050 		FOREVER
       
  1051 			{
       
  1052 			next=gc->NextWinGc();
       
  1053 			WS_ASSERT_DEBUG(next!=NULL, EWsPanicBadActiveGcList);
       
  1054 			if (next==aGc)
       
  1055 				{
       
  1056 				gc->SetNextWinGc(next->NextWinGc());
       
  1057 				break;
       
  1058 				}
       
  1059 			gc=next;
       
  1060 			}
       
  1061 		}
       
  1062 	aGc->SetNextWinGc(NULL);
       
  1063 	}
       
  1064 
       
  1065 void CWsClientWindow::ReactivateGcs()
       
  1066 	{
       
  1067 	for (CWsGc * gc = iWinGcList; gc; gc = gc->NextWinGc())
       
  1068 		{
       
  1069 		gc->Reactivate();
       
  1070 		}
       
  1071 	}
       
  1072 
       
  1073 void CWsClientWindow::OffsetUserTransparentRegion(const TPoint& aOffset)
       
  1074 	{
       
  1075 	if (iUserDefinedTransparentRegion)
       
  1076 		{
       
  1077 		iUserDefinedTransparentRegion->Offset(aOffset);
       
  1078 		}	
       
  1079 	}
       
  1080 
       
  1081 void CWsClientWindow::SetUserTransparentRegion(RWsRegion* aRegion)
       
  1082 	{
       
  1083 	if (iUserDefinedTransparentRegion)
       
  1084 		{
       
  1085 		iUserDefinedTransparentRegion->Close();
       
  1086 		delete iUserDefinedTransparentRegion;
       
  1087 		iUserDefinedTransparentRegion = 0;
       
  1088 		}
       
  1089 		
       
  1090 	if (aRegion)
       
  1091 		{		
       
  1092 		aRegion->Offset(iOrigin);
       
  1093 		iUserDefinedTransparentRegion=aRegion;
       
  1094 		}
       
  1095 		
       
  1096 	SetUserOpaqueRegion();
       
  1097 	}
       
  1098 
       
  1099 void CWsClientWindow::SetUserOpaqueRegion()
       
  1100 	{
       
  1101 	if (iUserDefinedOpaqueRegion)
       
  1102 		{
       
  1103 		iUserDefinedOpaqueRegion->Close();
       
  1104 		delete iUserDefinedOpaqueRegion;
       
  1105 		iUserDefinedOpaqueRegion = 0;
       
  1106 		}
       
  1107 	if (iUserDefinedTransparentRegion)
       
  1108 		{
       
  1109 		iUserDefinedOpaqueRegion=new RWsRegion;
       
  1110 		if (iUserDefinedOpaqueRegion)
       
  1111 			{
       
  1112 			iUserDefinedOpaqueRegion->Copy(*iBaseArea);
       
  1113 			iUserDefinedOpaqueRegion->SubRegion(*iUserDefinedTransparentRegion);
       
  1114 			if (iUserDefinedOpaqueRegion->CheckError() || iUserDefinedOpaqueRegion->Count() == 0)
       
  1115 				{
       
  1116 				iUserDefinedOpaqueRegion->Close();
       
  1117 				delete iUserDefinedOpaqueRegion;
       
  1118 				iUserDefinedOpaqueRegion = 0;
       
  1119 				}
       
  1120 			}
       
  1121 		// Intentionally not sending this notification during destruction (when SetUserTransparentRegion is called from d'tor)
       
  1122 		MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
  1123 		if (windowTreeObserver)
       
  1124 			{
       
  1125 			windowTreeObserver->TransparentRegionChanged(*this, *iUserDefinedTransparentRegion, iUserDefinedOpaqueRegion);
       
  1126 			}
       
  1127 		}
       
  1128 	}
       
  1129 
       
  1130 /** Checks whether this window is in front of aWin.
       
  1131 
       
  1132 @param aWin A window.
       
  1133 @return EFalse if aWin is the same or is in front of this, ETrue otherwise.
       
  1134 @internalComponent
       
  1135 * released
       
  1136 */	
       
  1137 TBool CWsClientWindow::IsInfrontOf(const CWsWindowBase* aWin) const
       
  1138 	{
       
  1139 	TInt thisDepth=Depth();
       
  1140 	TInt otherDepth=aWin->Depth();
       
  1141 	const CWsWindowBase *thisWin=this;
       
  1142 	const CWsWindowBase *otherWin=aWin;
       
  1143 	if (thisDepth>otherDepth)
       
  1144 		{
       
  1145 		for (TInt count=thisDepth-otherDepth;count>0;count--)
       
  1146 			thisWin=thisWin->BaseParent();
       
  1147 		}
       
  1148 	else
       
  1149 		{
       
  1150 		for (TInt count=otherDepth-thisDepth;count>0;count--)
       
  1151 			otherWin=otherWin->BaseParent();
       
  1152 		}
       
  1153 	if (thisWin==otherWin)
       
  1154 		return thisDepth>otherDepth;
       
  1155 	while(thisWin->BaseParent()!=otherWin->BaseParent())
       
  1156 		{
       
  1157 		thisWin=thisWin->BaseParent();
       
  1158 		otherWin=otherWin->BaseParent();
       
  1159 		}
       
  1160 	const CWsWindowBase *win=thisWin->BaseParent()->BaseChild();
       
  1161 	FOREVER
       
  1162 		{
       
  1163 		if (win==otherWin)
       
  1164 			{
       
  1165 			return EFalse;
       
  1166 			}
       
  1167 		if (win==thisWin)
       
  1168 			return ETrue;
       
  1169 		win=win->NextSibling();
       
  1170 		}
       
  1171 	}
       
  1172 	
       
  1173 CWsTopClientWindow* CWsClientWindow::TopClientWindow()
       
  1174 	{
       
  1175 	if (iParent==NULL)
       
  1176 		OwnerPanic(EWservPanicParentDeleted);
       
  1177 	CWsWindowBase* win=this;
       
  1178 	while(win->BaseParent()->WinType()!=EWinTypeGroup)
       
  1179 		win=win->BaseParent();
       
  1180 	return static_cast<CWsTopClientWindow*>(win);
       
  1181 	}
       
  1182 
       
  1183 const TRegion &CWsClientWindow::InvalidArea() const
       
  1184 	{
       
  1185 	return(iRedraw->InvalidArea());
       
  1186 	}
       
  1187 
       
  1188 
       
  1189 TUint CWsClientWindow::RedrawPriority(TInt *aShift) const
       
  1190 	{
       
  1191 	TUint ordinalPos=OrdinalPosition(EFalse)+1;
       
  1192 	if (ordinalPos>15)	// Algorithm only works upto 15 , make all windows after 15 equal in priority
       
  1193 		ordinalPos=15;
       
  1194 	TInt shift;
       
  1195 	TUint parent=((CWsClientWindow *)iParent)->RedrawPriority(&shift);
       
  1196 	if (shift>0)
       
  1197 		shift--;
       
  1198 	if (aShift)
       
  1199 		*aShift=shift;
       
  1200 	return(parent+(ordinalPos<<(shift*KWinRedrawPriBitsPerLevel)));
       
  1201 	}
       
  1202 
       
  1203 TDblQue<TPointerKeyList> *CWsClientWindow::PointerKeyList() const
       
  1204 	{
       
  1205 	return(iPointerKeyList);
       
  1206 	}
       
  1207 
       
  1208 void CWsClientWindow::AddKeyRectL(const TRect &aRect, TInt aScanCode, TBool aActivatedByPointerSwitchOn)
       
  1209 	{
       
  1210 	if (!iPointerKeyList)
       
  1211 		iPointerKeyList=new(ELeave) TDblQue<TPointerKeyList>(_FOFF(TPointerKeyList,iQue));
       
  1212 	TPointerKeyList *pkl=new(ELeave) TPointerKeyList();
       
  1213 	iPointerKeyList->AddLast(*pkl);
       
  1214 	pkl->iRect=aRect;
       
  1215 	pkl->iScanCode=aScanCode;
       
  1216 	pkl->iActivatedByPointerSwitchOn=aActivatedByPointerSwitchOn;
       
  1217 	}
       
  1218 
       
  1219 void CWsClientWindow::RemoveAllKeyRects()
       
  1220 	{
       
  1221 	if (iPointerKeyList)
       
  1222 		{
       
  1223 		TPointerKeyList *pkl=NULL;
       
  1224 		for(TDblQueIter<TPointerKeyList> iter(*iPointerKeyList);(pkl=iter++)!=NULL;)
       
  1225 			{
       
  1226 			pkl->iQue.Deque();
       
  1227 			delete pkl;
       
  1228 			}
       
  1229 		delete iPointerKeyList;
       
  1230 		iPointerKeyList=NULL;
       
  1231 		}
       
  1232 	}
       
  1233 
       
  1234 TBool CWsClientWindow::IsHidden()
       
  1235 	{
       
  1236 	return (!IsVisible()) || VisibleRegion().IsEmpty();
       
  1237 	}
       
  1238 
       
  1239 void CWsClientWindow::SetFaded(TBool aFade, TUint8 aBlackMap, TUint8 aWhiteMap, TBool aNotifyObserver)
       
  1240 	{
       
  1241 	TBool stateChanged;
       
  1242 	SetFaded(aFade, aBlackMap, aWhiteMap, aNotifyObserver, stateChanged);
       
  1243 	}
       
  1244 
       
  1245 void CWsClientWindow::SetFaded(TBool aFade, TUint8 aBlackMap, TUint8 aWhiteMap, TBool aNotifyObserver, TBool& aStateChanged)
       
  1246 	{
       
  1247 	iBlackMap=aBlackMap;
       
  1248 	iWhiteMap=aWhiteMap;
       
  1249 	const TBool mapAltered = (iBlackMap != aBlackMap) || (iWhiteMap != aWhiteMap); 
       
  1250 	const TInt oldFadeCount = iFadeCount;
       
  1251 
       
  1252 	if (iAbsoluteFading) 
       
  1253 		{ 
       
  1254 		if (aFade) 
       
  1255 			{ 
       
  1256 			iFadeCount = 1; 
       
  1257 			} 
       
  1258 		else 
       
  1259 			{ 
       
  1260 			iFadeCount = 0; 
       
  1261 			} 
       
  1262 		} 
       
  1263 	else 
       
  1264 		{ 
       
  1265 		if (aFade) 
       
  1266 			{ 
       
  1267 			++iFadeCount; 
       
  1268 			} 
       
  1269 		else if (iFadeCount > 0) 
       
  1270 			{ 
       
  1271 			--iFadeCount; 
       
  1272 			} 
       
  1273 		}
       
  1274 	
       
  1275 	//Fade state only changes when iFadeCount transitions from 0 to 1 or from 1 to 0.
       
  1276  	aStateChanged = (iFadeCount==0 || oldFadeCount==0) && (oldFadeCount != iFadeCount);
       
  1277  	if (!Screen()->ChangeTracking() && CWsTop::IsFadeEnabled() && (aStateChanged || mapAltered) ) 
       
  1278  		{
       
  1279  		Screen()->AcceptFadeRequest(this, (iFadeCount > 0));
       
  1280  		}
       
  1281 
       
  1282 	const TBool doNotify = iAbsoluteFading ? aStateChanged : (oldFadeCount != iFadeCount);
       
  1283 	MWsWindowTreeObserver* const windowTreeObserver = Screen()->WindowTreeObserver();
       
  1284 	if (windowTreeObserver && aNotifyObserver && doNotify)
       
  1285 		{
       
  1286 		windowTreeObserver->FadeCountChanged(*this, iFadeCount);
       
  1287 		}	
       
  1288 	}
       
  1289 
       
  1290 void CWsClientWindow::ResetHiddenFlagsInParentAndChildren()
       
  1291 	{
       
  1292 	ResetHiddenFlag();
       
  1293 	SetElementOpacity(IsVisible() ? 0xFF : 0x00);	// Update element visibility
       
  1294 	for(CWsClientWindow* child=Child();child;child=child->NextSibling())
       
  1295 		{
       
  1296 		child->ResetHiddenFlagsInParentAndChildren();
       
  1297 		}
       
  1298 	}
       
  1299 
       
  1300 const TRegion& CWsClientWindow::WindowArea() const
       
  1301 	{
       
  1302 	WS_ASSERT_DEBUG(iBaseArea, EWsPanicRegionNull);
       
  1303 	return *iBaseArea;
       
  1304 	}
       
  1305 
       
  1306 void CWsClientWindow::Invalidate(const TRect * aRect)
       
  1307 	{
       
  1308 	iRedraw->Invalidate(aRect);
       
  1309 	}
       
  1310 
       
  1311 void CWsClientWindow::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty)
       
  1312 	{
       
  1313 	if (IsVisible())
       
  1314 		{
       
  1315 		iScreen->ScheduleRegionUpdate(aDefinitelyDirty);
       
  1316 		}
       
  1317 	}
       
  1318 
       
  1319 void CWsClientWindow::AddRedrawRegion(const TRegion& aRegion, TBool aSchedule, TRedrawDepth aDepth)
       
  1320 	{
       
  1321 	if (!IsHidden())
       
  1322 		{
       
  1323 		iScreen->AddRedrawRegion(aRegion, aSchedule, aDepth);
       
  1324 		}
       
  1325 	}
       
  1326 
       
  1327 void CWsClientWindow::SendState(MWsWindowTreeObserver& aWindowTreeObserver) const
       
  1328 	{	
       
  1329 	CWsWindow::SendState(aWindowTreeObserver);
       
  1330 	
       
  1331 	if(iFadeCount > 0)
       
  1332 		{
       
  1333 		aWindowTreeObserver.FadeCountChanged(*this, iFadeCount);
       
  1334 		}
       
  1335 	
       
  1336 	if(iUserDefinedTransparentRegion)
       
  1337 		{
       
  1338 		aWindowTreeObserver.TransparentRegionChanged(*this, *iUserDefinedTransparentRegion, iUserDefinedOpaqueRegion);
       
  1339 		}
       
  1340 
       
  1341 	if(HasElement())
       
  1342 		{
       
  1343 		CWindowElementSet& windowElementSet = Screen()->WindowElements();
       
  1344 		const TBackgroundAttributes		*bElementAttr;
       
  1345 		const RArray<TPlacedAttributes>	*pElementsAttr;
       
  1346 		
       
  1347 		TInt ret = windowElementSet.FindElements(*this, bElementAttr, pElementsAttr);
       
  1348 		if(ret == KErrNone)
       
  1349 			{
       
  1350 			MWsElement* element = bElementAttr->iElement;
       
  1351 			if (element)
       
  1352 				aWindowTreeObserver.ElementAdded(*this, *element);
       
  1353 			}
       
  1354 		}
       
  1355 	
       
  1356 	}
       
  1357 
       
  1358 TBool CWsClientWindow::IsDSAHost() const
       
  1359 	{
       
  1360 	TBool res = CWsWindow::IsDSAHost();
       
  1361 	if ( !res )
       
  1362 		{ // check for grace period when DSA is being restarted (after aborting but before client started DSA again)
       
  1363 		res = Screen()->IsDSAClientWindow( this );
       
  1364 		}
       
  1365 	return res;
       
  1366 	}
       
  1367 
       
  1368 void CWsClientWindow::UpdateElementExtent(const TPoint* aOffset)
       
  1369 	{
       
  1370 	if (Redraw()->HasElement())
       
  1371 		{
       
  1372 		Screen()->WindowElements().UpdateElementExtent(*this, aOffset);
       
  1373 		}
       
  1374 	}
       
  1375 
       
  1376 void CWsClientWindow::SetElementOpacity(TInt aOpacity)
       
  1377 	{
       
  1378 	if (Redraw()->HasElement())
       
  1379 		{
       
  1380 		Screen()->WindowElements().SetElementOpacity(*this,aOpacity);
       
  1381 
       
  1382 		} 
       
  1383 	}
       
  1384 
       
  1385 TRect CWsClientWindow::GetOriginalSrcElementRect() const
       
  1386     {
       
  1387     return iOriginalSrcElementRect;
       
  1388     }
       
  1389 TRect CWsClientWindow::GetOriginalDestElementRect() const
       
  1390     {
       
  1391     return iOriginalDestElementRect;
       
  1392     }
       
  1393     
       
  1394 //
       
  1395 // Code for CWsTopClientWindow, a client window that connects to a group window //
       
  1396 //
       
  1397 
       
  1398 CWsTopClientWindow::CWsTopClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsClientWindow(aOwner, aScreen)
       
  1399 	{
       
  1400 	}
       
  1401 
       
  1402 void CWsTopClientWindow::ConstructL(const TWsClCmdCreateWindow &cmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid)
       
  1403 	{
       
  1404 	iFlags|=EFlagIsTopClientWindow;
       
  1405 	CWsClientWindow::ConstructL(cmd, aParent, aScreenDeviceIsInvalid);
       
  1406 	}
       
  1407 
       
  1408 void CWsTopClientWindow::SetInactive()
       
  1409 	{
       
  1410 	iFlags&=~EFlagActive;
       
  1411 	ResetHiddenFlags();
       
  1412 	}
       
  1413 
       
  1414 void CWsTopClientWindow::SetScreenDeviceValidState(TBool aState)
       
  1415 	{
       
  1416 	if (SetScreenDeviceValidStateFlag(aState))
       
  1417 		ResetHiddenFlags();
       
  1418 	}
       
  1419 
       
  1420 TBool CWsTopClientWindow::SetScreenDeviceValidStateFlag(TBool aState)
       
  1421 	{
       
  1422 	TBool isSet=iFlags&EFlagScreenDeviceInvalid;
       
  1423 	if (!isSet==!aState)
       
  1424 		{
       
  1425 		if (aState)
       
  1426 			iFlags&=~EFlagScreenDeviceInvalid;
       
  1427 		else
       
  1428 			iFlags|=EFlagScreenDeviceInvalid;
       
  1429 		return ETrue;
       
  1430 		}
       
  1431 	return EFalse;
       
  1432 	}
       
  1433 
       
  1434 void CWsTopClientWindow::SetOrdinalPosition(TInt aPos)
       
  1435 	{
       
  1436 	if (!iParent)
       
  1437 		{
       
  1438 		OwnerPanic(EWservPanicParentDeleted);
       
  1439 		}
       
  1440 	if (CheckOrdinalPositionChange(aPos))
       
  1441 		{
       
  1442 		CWsWindowBase::SetOrdinalPosition(aPos);
       
  1443 		CWsTop::TriggerRedraws(RootWindow());
       
  1444 		}
       
  1445 	}
       
  1446 
       
  1447 void CWsTopClientWindow::DoMoveWindowL(TInt aIdentifier)
       
  1448 	{
       
  1449 	CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(aIdentifier);
       
  1450 	if (group==iParent)
       
  1451 		return;
       
  1452 	if (group->WsOwner()!=WsOwner())
       
  1453 		User::Leave(KErrNotFound);
       
  1454 	ChangeWindowPosition(0, group);
       
  1455 	CWsTop::TriggerRedraws(RootWindow());
       
  1456 	}
       
  1457 
       
  1458 TUint CWsTopClientWindow::RedrawPriority(TInt *aShift) const
       
  1459 	{
       
  1460 	TUint ordinalPos=OrdinalPosition(EFalse);
       
  1461 	if (ordinalPos>KWinRedrawPriMaxOrdinal)	// Algorithm only works for upto KWinRedrawPriMaxOrdinal windows,
       
  1462 		ordinalPos=KWinRedrawPriMaxOrdinal;	// make all windows after this equal in priority
       
  1463 	if (aShift)
       
  1464 		*aShift=KWinRedrawPriMaxLevel;
       
  1465 	return(ordinalPos<<(KWinRedrawPriMaxLevel*KWinRedrawPriBitsPerLevel));
       
  1466 	}
       
  1467