os/graphics/windowing/windowserver/nonnga/SERVER/GROUPWIN.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Group window sub-class of CWsWindow
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <e32std.h>
sl@0
    19
#include "W32STD.H"
sl@0
    20
#include "W32CLICK.H"
sl@0
    21
#include "server.h"
sl@0
    22
#include "rootwin.h"
sl@0
    23
#include "windowgroup.h"
sl@0
    24
#include "walkwindowtree.h"
sl@0
    25
#include "wstop.h"
sl@0
    26
#include "EVENT.H"
sl@0
    27
#include "KEYCLICK.H"
sl@0
    28
#include "PRIKEY.H"
sl@0
    29
#include "panics.h"
sl@0
    30
sl@0
    31
GLREF_D TPtr nullDescriptor;
sl@0
    32
GLREF_D CDebugLogBase* wsDebugLog;
sl@0
    33
sl@0
    34
#if defined(_DEBUG)
sl@0
    35
TInt CWsWindowGroup::iSkipCount=0;
sl@0
    36
#endif
sl@0
    37
sl@0
    38
TInt CWsWindowGroup::iIdentifierCount=1;
sl@0
    39
TBool CWsWindowGroup::iFocusGainPreProcess=EFalse;		//'REMOVEFADINGONFOCUSGAIN' flag in INI file
sl@0
    40
RPointerArray< TDblQue<CWsWindowGroup> > CWsWindowGroup::iChains(3);
sl@0
    41
static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_SwEvent,ECapabilitySwEvent);
sl@0
    42
static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_WriteDeviceData,ECapabilityWriteDeviceData);
sl@0
    43
const TInt KArrayMaxGranularity=0x10000000;
sl@0
    44
sl@0
    45
CWsWindowGroup* CWsWindowGroup::NewL(CWsClient* aOwner, CScreen* aScreen, 
sl@0
    46
	const TWsClCmdCreateWindowGroup& aCmd)
sl@0
    47
	{
sl@0
    48
	CWsWindowGroup* self = new(ELeave) CWsWindowGroup(aOwner, aScreen);
sl@0
    49
	CleanupStack::PushL(self);
sl@0
    50
	self->ConstructL(aCmd);
sl@0
    51
	CleanupStack::Pop(self);
sl@0
    52
	return self;
sl@0
    53
	}
sl@0
    54
sl@0
    55
CWsWindowGroup::CWsWindowGroup(CWsClient* aOwner, CScreen* aScreen) : CWsWindowBase(aOwner,WS_HANDLE_GROUP_WINDOW,aScreen)
sl@0
    56
	{
sl@0
    57
	__DECLARE_NAME(_S("CWsWindowGroup"));
sl@0
    58
	iWinType=EWinTypeGroup;
sl@0
    59
	}
sl@0
    60
sl@0
    61
void CWsWindowGroup::PurgeCapturedKeys()
sl@0
    62
	{
sl@0
    63
	CWsObjectIx& objix=*WsOwner()->ObjectIndex();
sl@0
    64
	const TWsObject* ptr=objix.FirstObject();
sl@0
    65
	const TWsObject* end=ptr+objix.Length();
sl@0
    66
	while(++ptr<end)		//Fisrt one should always have a NULL object
sl@0
    67
		{
sl@0
    68
		const CWsObject* obj=ptr->iObject;
sl@0
    69
		if (obj 
sl@0
    70
			&& ((obj->Type()==WS_HANDLE_CAPTURE_KEY && STATIC_CAST(const CWsCaptureKey*,obj)->WindowGroup()==this)
sl@0
    71
				|| (obj->Type()==WS_HANDLE_CAPTURE_KEY_UPDOWNS && STATIC_CAST(const CWsCaptureKeyUpsAndDowns*,obj)->WindowGroup()==this)
sl@0
    72
				|| (obj->Type()==WS_HANDLE_CAPTURE_LONG_KEY && STATIC_CAST(const CWsCaptureLongKey*,obj)->WindowGroup()==this)))
sl@0
    73
			{
sl@0
    74
			objix.Remove(ptr);
sl@0
    75
			delete obj;
sl@0
    76
			}
sl@0
    77
		}
sl@0
    78
	objix.Tidy();
sl@0
    79
	CKeyboardRepeat::CancelRepeat(this);
sl@0
    80
	}
sl@0
    81
sl@0
    82
void CWsWindowGroup::SwitchToOwningWindow(CWsWindowGroup *aClosingWindow)
sl@0
    83
	{
sl@0
    84
	if (this==CWsTop::FocusWindowGroup())
sl@0
    85
		{
sl@0
    86
		CWsWindowGroup *winGroup=NULL;
sl@0
    87
//
sl@0
    88
// First try for an 'owning' window
sl@0
    89
//
sl@0
    90
		if (iOwningWindowGroup)
sl@0
    91
			{
sl@0
    92
			for(winGroup=RootWindow()->Child();winGroup;winGroup=winGroup->NextSibling())
sl@0
    93
				if (winGroup->Identifier()==iOwningWindowGroup && winGroup->iOrdinalPriority==iOrdinalPriority)
sl@0
    94
					goto gotIt;
sl@0
    95
			}
sl@0
    96
//
sl@0
    97
// If that failed look for the frontmost window belonging to the owner of dying window
sl@0
    98
//
sl@0
    99
		for(winGroup=RootWindow()->Child();winGroup;winGroup=winGroup->NextSibling())
sl@0
   100
			if (winGroup!=this && winGroup->WsOwner()==WsOwner() && winGroup->iOrdinalPriority==iOrdinalPriority)
sl@0
   101
				goto gotIt;
sl@0
   102
//
sl@0
   103
// Next try for the nominated default owning window group
sl@0
   104
//
sl@0
   105
		winGroup=iScreen->DefaultOwningWindowGroup();
sl@0
   106
		if (winGroup && winGroup->iOrdinalPriority==iOrdinalPriority)
sl@0
   107
			{
sl@0
   108
gotIt:		winGroup->SetOrdinalPosition(0,this);
sl@0
   109
			return;
sl@0
   110
			}
sl@0
   111
		}
sl@0
   112
	ResetFocus(aClosingWindow);
sl@0
   113
	}
sl@0
   114
sl@0
   115
CWsWindowGroup::~CWsWindowGroup()
sl@0
   116
	{
sl@0
   117
	if (wsDebugLog)
sl@0
   118
		{
sl@0
   119
		TLogMessageText buf;
sl@0
   120
		_LIT(KWSERVDebugLogGroupWindowId,"Destroying: RWindowGroup[0x%x,%d],Id=%d");
sl@0
   121
		buf.Format(KWSERVDebugLogGroupWindowId,iClientHandle,LogHandle(),iIdentifier);
sl@0
   122
		wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything, buf);
sl@0
   123
		}
sl@0
   124
	if (CClick::IsHandler())
sl@0
   125
		{
sl@0
   126
		CClick::OtherEvent(EEventGroupWindowClose,reinterpret_cast<TAny*>(iIdentifier));
sl@0
   127
		}
sl@0
   128
	if (iQueue)
sl@0
   129
		{
sl@0
   130
		if (iQueue->Last()!=this)
sl@0
   131
			{		//Unlink all the children of the window that is being deleted
sl@0
   132
			TDblQueIter<CWsWindowGroup> iter(*iQueue);
sl@0
   133
			CWsWindowGroup* groupWin;
sl@0
   134
			iter.SetToLast();
sl@0
   135
			while ((groupWin=iter--)!=this)
sl@0
   136
				{
sl@0
   137
				WS_ASSERT_DEBUG(groupWin!=NULL && groupWin->iQueue==iQueue,EWsPanicGroupWindowChainError);
sl@0
   138
				groupWin->iChainLink.Deque();
sl@0
   139
				groupWin->iQueue=NULL;
sl@0
   140
				}
sl@0
   141
			}
sl@0
   142
		WS_ASSERT_DEBUG(iQueue->Last()==this,EWsPanicGroupWindowChainError);
sl@0
   143
		TDblQueLinkBase* parentLink=iChainLink.iPrev;
sl@0
   144
		iChainLink.Deque();
sl@0
   145
		if (parentLink->iNext==parentLink->iPrev)		//Check to see chain no longer required
sl@0
   146
			{
sl@0
   147
			if (!iQueue->IsEmpty())
sl@0
   148
				{				//Only the parent is left in queue
sl@0
   149
				CWsWindowGroup* parent=iQueue->First();
sl@0
   150
				static_cast<TDblQueLink*>(parentLink)->Deque();
sl@0
   151
				WS_ASSERT_DEBUG(parent->iQueue==iQueue,EWsPanicGroupWindowChainError);
sl@0
   152
				parent->iQueue=NULL;
sl@0
   153
				}
sl@0
   154
			DeleteQueue(iQueue);
sl@0
   155
			}
sl@0
   156
		iQueue=NULL;
sl@0
   157
		}
sl@0
   158
	RemoveAllPriorityKeys();
sl@0
   159
	PurgeCapturedKeys();
sl@0
   160
	iTextCursor.Close();
sl@0
   161
	SetPointerCursor(NULL);
sl@0
   162
	for(CWsClientWindow *win=Child();win;win=win->NextSibling())
sl@0
   163
		win->SetInactive();
sl@0
   164
	if (iScreen)
sl@0
   165
		{
sl@0
   166
		iScreen->RemoveFromDefaultOwningList(this);
sl@0
   167
		}
sl@0
   168
	CWsWindowBase::Shutdown();
sl@0
   169
	TWindowServerEvent::SendGroupChangedEvents();
sl@0
   170
	iClientHandle=0;	// To block focus lost events being sent
sl@0
   171
// Decide which window to give focus to if WServ isn't shutting down
sl@0
   172
	if (iScreen && !CWsTop::ShuttingDown())
sl@0
   173
		SwitchToOwningWindow(this);
sl@0
   174
	delete iGroupName;
sl@0
   175
	delete iMessageArray;
sl@0
   176
	}
sl@0
   177
sl@0
   178
void CWsWindowGroup::DeleteQueue(TDblQue<CWsWindowGroup>* aQueue)
sl@0
   179
	{
sl@0
   180
	iChains.Remove(iChains.Find(aQueue));
sl@0
   181
	delete aQueue;
sl@0
   182
	if (iChains.Count()==0)
sl@0
   183
		{
sl@0
   184
		iChains.Compress();
sl@0
   185
		}
sl@0
   186
	}
sl@0
   187
sl@0
   188
void CWsWindowGroup::AdvanceIdentifierCount()
sl@0
   189
	{
sl@0
   190
	if (++iIdentifierCount>EMaxIdentifierCount)
sl@0
   191
		iIdentifierCount=1;		// so limit it to low value
sl@0
   192
	}
sl@0
   193
sl@0
   194
void CWsWindowGroup::ConstructL(const TWsClCmdCreateWindowGroup &aCmd)
sl@0
   195
	{
sl@0
   196
#if defined(_DEBUG)
sl@0
   197
	if (IsClientHandleInUse(aCmd.clientHandle))
sl@0
   198
		{
sl@0
   199
		OwnerPanic(EWservPanicDuplicateHandle);
sl@0
   200
		}
sl@0
   201
#endif
sl@0
   202
	NewObjL();
sl@0
   203
	iFlags=EGroupFlagAutoForeground|EGroupFlagMsgQueueNew;
sl@0
   204
	if (aCmd.focus)
sl@0
   205
		{
sl@0
   206
		iFlags|=EGroupFlagReceivesFocus;
sl@0
   207
		}
sl@0
   208
	iTextCursor.ConstructL(this);
sl@0
   209
	iClientHandle=aCmd.clientHandle;
sl@0
   210
	
sl@0
   211
	if(aCmd.screenDeviceHandle <= 0)
sl@0
   212
		{
sl@0
   213
		//Use primary screen. Client should make sure PrimaryScreenDevice is correct set up immediately after establishing session.
sl@0
   214
		iScreenDevice=iWsOwner->PrimaryScreenDevice();
sl@0
   215
		}
sl@0
   216
	else
sl@0
   217
		{
sl@0
   218
		//Use the specified screen
sl@0
   219
		iScreenDevice=STATIC_CAST(DWsScreenDevice*,iWsOwner->HandleToObj(aCmd.screenDeviceHandle,WS_HANDLE_SCREEN_DEVICE));
sl@0
   220
		}
sl@0
   221
sl@0
   222
	iScreen = (iScreenDevice) ? iScreenDevice->Screen() : CWsTop::Screen(); //if no screen device use screen 0
sl@0
   223
	
sl@0
   224
	CWsWindowGroup* parent=NULL;
sl@0
   225
	if (aCmd.parentId>0)
sl@0
   226
		{
sl@0
   227
		parent=CWsWindowGroup::WindowGroupFromIdentifier(aCmd.parentId);
sl@0
   228
		if (!parent)
sl@0
   229
			{
sl@0
   230
			OwnerPanic(EWservPanicWindow);
sl@0
   231
			}
sl@0
   232
		
sl@0
   233
		if(parent->Screen() != iScreen)
sl@0
   234
			{
sl@0
   235
			OwnerPanic(EWservPanicWrongScreen);
sl@0
   236
			}
sl@0
   237
		
sl@0
   238
		if (parent->iOrdinalPriorityAdjust>0)
sl@0
   239
			{
sl@0
   240
			WS_ASSERT_DEBUG(parent->iQueue==NULL,EWsPanicGroupWindowChainError);
sl@0
   241
			parent->iOrdinalPriorityAdjust=0;
sl@0
   242
			parent->UpdateOrdinalPriority(ETrue);
sl@0
   243
			}
sl@0
   244
		iOrdinalPriorityBase=parent->iOrdinalPriorityBase;
sl@0
   245
		iOrdinalPriority=iOrdinalPriorityBase;
sl@0
   246
		}
sl@0
   247
	
sl@0
   248
	CWsWindowBase::ConstructL(RootWindow());
sl@0
   249
	
sl@0
   250
	if (parent)
sl@0
   251
		{
sl@0
   252
		TDblQue<CWsWindowGroup>* queue=parent->iQueue;
sl@0
   253
		if (queue && queue->Last()!=parent)
sl@0
   254
			User::Leave(KErrInUse);
sl@0
   255
		if (parent->iWsOwner!=iWsOwner)
sl@0
   256
			{
sl@0
   257
			_LIT_SECURITY_POLICY_S0(securityPolicy,parent->iChildSID);
sl@0
   258
			if (!securityPolicy().CheckPolicy(iWsOwner->ClientMessage()))
sl@0
   259
				User::Leave(KErrPermissionDenied);
sl@0
   260
			}
sl@0
   261
		if (!queue)
sl@0
   262
			{
sl@0
   263
			queue=new(ELeave) TDblQue<CWsWindowGroup>(_FOFF(CWsWindowGroup,iChainLink));
sl@0
   264
			CleanupStack::PushL(queue);
sl@0
   265
			User::LeaveIfError(iChains.Append(queue));
sl@0
   266
			CleanupStack::Pop(queue);
sl@0
   267
			queue->AddFirst(*parent);
sl@0
   268
			parent->iQueue=queue;
sl@0
   269
			}
sl@0
   270
		iQueue=queue;		//Shouldn't set the queue until after it can leave
sl@0
   271
		iChainLink.Enque(&parent->iChainLink);
sl@0
   272
		}
sl@0
   273
	do
sl@0
   274
		{
sl@0
   275
		AdvanceIdentifierCount();	// Always advance by at least one to stop re-using last id
sl@0
   276
		} while (WindowGroupFromIdentifier(iIdentifierCount)); // If current count is in use try again
sl@0
   277
	
sl@0
   278
	iIdentifier=iIdentifierCount;
sl@0
   279
	iMessageArray=new(ELeave) CArrayVarSeg<TWsMessage>(1);
sl@0
   280
	if (CClick::IsHandler())
sl@0
   281
		{
sl@0
   282
		TGroupWindowOpenData params;
sl@0
   283
		params.iIdentifier=iIdentifier;
sl@0
   284
		params.iClient=iWsOwner->ConnectionHandle();
sl@0
   285
		params.iNumClientWindowGroups=NumClientWindowGroups()-1;	//Don't include this one
sl@0
   286
		CClick::OtherEvent(EEventGroupWindowOpen,&params);
sl@0
   287
		}
sl@0
   288
	if (wsDebugLog)
sl@0
   289
		{
sl@0
   290
		TLogMessageText buf;
sl@0
   291
		_LIT(KWSERVDebugLogGroupWindowId,"Creating: RWindowGroup[0x%x,%d],Id=%d");
sl@0
   292
		buf.Format(KWSERVDebugLogGroupWindowId,iClientHandle,LogHandle(),iIdentifier);
sl@0
   293
		wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything, buf);
sl@0
   294
		}
sl@0
   295
	}
sl@0
   296
sl@0
   297
void CWsWindowGroup::UpdateOrdinalPriority(TBool aDoAdjust)
sl@0
   298
	{
sl@0
   299
	TInt newPri;
sl@0
   300
	newPri=iOrdinalPriorityBase;
sl@0
   301
	if (iWsOwner==CWsTop::FocusWindowGroupOwner())
sl@0
   302
		newPri+=iOrdinalPriorityAdjust;
sl@0
   303
	CheckCapability(newPri);
sl@0
   304
	if (newPri!=iOrdinalPriority)
sl@0
   305
		{
sl@0
   306
		iOrdinalPriority=newPri;
sl@0
   307
		if (aDoAdjust)
sl@0
   308
			SetOrdinalPosition(0);
sl@0
   309
		}
sl@0
   310
	}
sl@0
   311
sl@0
   312
void CWsWindowGroup::SetOrdinalPriority(TInt aPos,TInt aPriority)
sl@0
   313
	{
sl@0
   314
	if (!iQueue)
sl@0
   315
		{
sl@0
   316
		iOrdinalPriorityBase=aPriority;
sl@0
   317
		UpdateOrdinalPriority(EFalse);
sl@0
   318
		}
sl@0
   319
	else
sl@0
   320
		{
sl@0
   321
		TDblQueIter<CWsWindowGroup> iter(*iQueue);
sl@0
   322
		CWsWindowGroup* group;
sl@0
   323
		while ((group=iter++)!=NULL)
sl@0
   324
			{
sl@0
   325
			group->iOrdinalPriorityBase=aPriority;
sl@0
   326
			group->iOrdinalPriority=aPriority;
sl@0
   327
			}
sl@0
   328
		}
sl@0
   329
	SetOrdinalPosition(aPos);
sl@0
   330
	}
sl@0
   331
sl@0
   332
void CWsWindowGroup::CommandL(TInt aOpcode, const TAny *aCmdData)
sl@0
   333
	{
sl@0
   334
#ifdef _DEBUG
sl@0
   335
	// Save root window for performing CheckTree at the end of this func.
sl@0
   336
	// When aOpcode is EWsWinOpFree, this object would've been destroyed
sl@0
   337
	// and a call to RootWindow() in that case would be impossible
sl@0
   338
	CWsRootWindow* rootWindow=RootWindow();
sl@0
   339
sl@0
   340
	// For certain opcodes, check for the 'screen device deleted' condition. If it
sl@0
   341
	// has occured for the screen device associated with this group window then
sl@0
   342
	// those op-codes are not valid, and the client is panicked.
sl@0
   343
	switch (aOpcode)
sl@0
   344
		{
sl@0
   345
		case EWsWinOpEnableScreenChangeEvents:
sl@0
   346
		case EWsWinOpAllowChildWindowGroup:
sl@0
   347
		case EWsWinOpReceiveFocus:
sl@0
   348
		case EWsWinOpAutoForeground:
sl@0
   349
		case EWsWinOpSetOrdinalPositionPri:
sl@0
   350
		case EWsWinOpSetOrdinalPriorityAdjust:
sl@0
   351
		case EWsWinOpCaptureKey:
sl@0
   352
		case EWsWinOpCaptureKeyUpsAndDowns:
sl@0
   353
		case EWsWinOpCaptureLongKey:
sl@0
   354
		case EWsWinOpAddPriorityKey:
sl@0
   355
		case EWsWinOpSetTextCursor:
sl@0
   356
		case EWsWinOpSetTextCursorClipped:
sl@0
   357
		case EWsWinOpSetOwningWindowGroup:
sl@0
   358
		case EWsWinOpDefaultOwningWindow:
sl@0
   359
		case EWsWinOpSetName:
sl@0
   360
		case EWsWinOpDisableKeyClick:
sl@0
   361
		case EWsWinOpSendPointerEvent:
sl@0
   362
			{
sl@0
   363
			if (ScreenDeviceDeleted())
sl@0
   364
				OwnerPanic(EWservPanicGroupWinScreenDeviceDeleted);
sl@0
   365
			break;				
sl@0
   366
			};
sl@0
   367
		}
sl@0
   368
#endif
sl@0
   369
sl@0
   370
	TWsWinCmdUnion pData;
sl@0
   371
	pData.any=aCmdData;
sl@0
   372
	if (CWsWindowBase::CommandL(aOpcode,pData)==EFalse)
sl@0
   373
		{
sl@0
   374
		switch(aOpcode)
sl@0
   375
			{
sl@0
   376
			case EWsWinOpAllowChildWindowGroup:
sl@0
   377
				iChildSID=*pData.UInt;
sl@0
   378
				break;
sl@0
   379
			case EWsWinOpEnableScreenChangeEvents:
sl@0
   380
				SetScreenChangeEventStateL(ETrue);
sl@0
   381
				break;
sl@0
   382
			case EWsWinOpDisableScreenChangeEvents:
sl@0
   383
				SetScreenChangeEventStateL(EFalse);
sl@0
   384
				break;
sl@0
   385
			case EWsWinOpReceiveFocus:
sl@0
   386
				iFlags&=~EGroupFlagReceivesFocus;
sl@0
   387
				if (*pData.Bool)
sl@0
   388
					iFlags|=EGroupFlagReceivesFocus;
sl@0
   389
				iScreen->ResetFocus(NULL);
sl@0
   390
				break;
sl@0
   391
			case EWsWinOpAutoForeground:
sl@0
   392
				iFlags&=~EGroupFlagAutoForeground;
sl@0
   393
				if (*pData.Bool)
sl@0
   394
					iFlags|=EGroupFlagAutoForeground;
sl@0
   395
				break;
sl@0
   396
			case EWsWinOpSetOrdinalPositionPri:
sl@0
   397
			case EWsWinOpSetOrdinalPositionErr:
sl@0
   398
				{
sl@0
   399
				TInt priority=pData.OrdinalPos->ordinalPriority;
sl@0
   400
				TBool hascap = CheckCapability(priority);
sl@0
   401
				SetOrdinalPriority(pData.OrdinalPos->pos, priority);
sl@0
   402
				if (aOpcode == EWsWinOpSetOrdinalPositionErr)
sl@0
   403
					{
sl@0
   404
					SetReply(hascap?KErrNone:KErrPermissionDenied);
sl@0
   405
					}
sl@0
   406
				}
sl@0
   407
				break;
sl@0
   408
			case EWsWinOpSetOrdinalPriorityAdjust:
sl@0
   409
				if (!iQueue)
sl@0
   410
					{
sl@0
   411
					iOrdinalPriorityAdjust=*pData.Int;
sl@0
   412
					UpdateOrdinalPriority(ETrue);
sl@0
   413
					}
sl@0
   414
				break;
sl@0
   415
			case EWsWinOpCaptureKey:
sl@0
   416
				{
sl@0
   417
				if(!KSecurityPolicy_SwEvent().CheckPolicy(iWsOwner->ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWindowGroup::CaptureKey API")))
sl@0
   418
					{
sl@0
   419
					User::Leave(KErrPermissionDenied);
sl@0
   420
					}
sl@0
   421
				CWsCaptureKey *cKey=new(ELeave) CWsCaptureKey(this);
sl@0
   422
				CleanupStack::PushL(cKey);
sl@0
   423
				cKey->ConstructL(*pData.CaptureKey);
sl@0
   424
				CleanupStack::Pop();
sl@0
   425
				}
sl@0
   426
				break;
sl@0
   427
			case EWsWinOpCaptureKeyUpsAndDowns:
sl@0
   428
				{
sl@0
   429
				if(!KSecurityPolicy_SwEvent().CheckPolicy(iWsOwner->ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWindowGroup::CaptureKeyUpsAndDowns API")))
sl@0
   430
					{
sl@0
   431
					User::Leave(KErrPermissionDenied);
sl@0
   432
					}
sl@0
   433
				CWsCaptureKeyUpsAndDowns *cKey=new(ELeave) CWsCaptureKeyUpsAndDowns(this);
sl@0
   434
				CleanupStack::PushL(cKey);
sl@0
   435
				cKey->ConstructL(*pData.CaptureKey);
sl@0
   436
				CleanupStack::Pop();
sl@0
   437
				}
sl@0
   438
				break;
sl@0
   439
			case EWsWinOpCaptureLongKey:
sl@0
   440
				{
sl@0
   441
				if(!KSecurityPolicy_SwEvent().CheckPolicy(iWsOwner->ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWindowGroup::CaptureLongKey API")))
sl@0
   442
					{
sl@0
   443
					User::Leave(KErrPermissionDenied);
sl@0
   444
					}
sl@0
   445
				CWsCaptureLongKey *cKey=new(ELeave) CWsCaptureLongKey(this);
sl@0
   446
				CleanupStack::PushL(cKey);
sl@0
   447
				cKey->ConstructL(*pData.CaptureLongKey);
sl@0
   448
				CleanupStack::Pop();
sl@0
   449
				}
sl@0
   450
				break;
sl@0
   451
			case EWsWinOpCancelCaptureKey:
sl@0
   452
				if (*pData.UInt!=0)	// Ignore null handle
sl@0
   453
					{
sl@0
   454
					CWsObject *destroyObj = iWsOwner->HandleToObj(*pData.UInt,WS_HANDLE_CAPTURE_KEY);
sl@0
   455
					if (destroyObj)
sl@0
   456
						{
sl@0
   457
						//Cancel any repeat that is underway for this key
sl@0
   458
						const TWsWinCmdCaptureKey& capKey(*pData.CaptureKey);
sl@0
   459
						CKeyboardRepeat::CancelRepeat(this,capKey.key,EFalse,capKey.modifierMask);
sl@0
   460
						delete destroyObj;
sl@0
   461
						}
sl@0
   462
					else
sl@0
   463
						{
sl@0
   464
#ifdef _DEBUG
sl@0
   465
						// Attempt to cancel key capture with an incorrect handle
sl@0
   466
						OwnerPanic(EWservPanicDestroy);  
sl@0
   467
#endif // _DEBUG
sl@0
   468
						}					
sl@0
   469
					}
sl@0
   470
				break;
sl@0
   471
			case EWsWinOpCancelCaptureKeyUpsAndDowns:
sl@0
   472
				if (*pData.UInt!=0)	// Ignore null handle
sl@0
   473
					{
sl@0
   474
					CWsObject *destroyObj = iWsOwner->HandleToObj(*pData.UInt,WS_HANDLE_CAPTURE_KEY_UPDOWNS);
sl@0
   475
					if (destroyObj)					
sl@0
   476
						{
sl@0
   477
						//Cancel any repeat that is underway for this key
sl@0
   478
						const TWsWinCmdCaptureKey& capKey(*pData.CaptureKey);
sl@0
   479
						CKeyboardRepeat::CancelRepeat(this,capKey.key,EFalse,capKey.modifierMask);
sl@0
   480
						delete destroyObj;
sl@0
   481
						}
sl@0
   482
					else
sl@0
   483
						{
sl@0
   484
#ifdef _DEBUG						
sl@0
   485
						// Attempt to cancel ups and downs key capture with an incorrect handle
sl@0
   486
						OwnerPanic(EWservPanicDestroy);
sl@0
   487
#endif // _DEBUG
sl@0
   488
						}					
sl@0
   489
					}
sl@0
   490
				break;
sl@0
   491
			case EWsWinOpCancelCaptureLongKey:
sl@0
   492
				if (*pData.UInt!=0)	// Ignore null handle
sl@0
   493
					{
sl@0
   494
					CWsObject *destroyObj = iWsOwner->HandleToObj(*pData.UInt,WS_HANDLE_CAPTURE_LONG_KEY);
sl@0
   495
					if (destroyObj)					
sl@0
   496
						{
sl@0
   497
						//Cancel any repeat that is underway for this key
sl@0
   498
						const TWsWinCmdCaptureLongKey& capKey(*pData.CaptureLongKey);
sl@0
   499
						CKeyboardRepeat::CancelRepeat(this,capKey.inputKey,ETrue,capKey.modifierMask);
sl@0
   500
						delete destroyObj;
sl@0
   501
						} 
sl@0
   502
					else
sl@0
   503
						{
sl@0
   504
#ifdef _DEBUG						
sl@0
   505
						// Attempt to cancel long key capture with an incorrect handle
sl@0
   506
						OwnerPanic(EWservPanicDestroy);
sl@0
   507
#endif // _DEBUG
sl@0
   508
						}					
sl@0
   509
					}
sl@0
   510
				break;
sl@0
   511
			case EWsWinOpAddPriorityKey:
sl@0
   512
				AddPriorityKeyL(pData.PriorityKey->keycode, pData.PriorityKey->modifierMask, pData.PriorityKey->modifiers);
sl@0
   513
				break;
sl@0
   514
			case EWsWinOpRemovePriorityKey:
sl@0
   515
				RemovePriorityKey(pData.PriorityKey->keycode, pData.PriorityKey->modifierMask, pData.PriorityKey->modifiers);
sl@0
   516
				break;
sl@0
   517
			case EWsWinOpSetTextCursor:
sl@0
   518
				iTextCursor.SetL(*pData.SetTextCursor, EFalse);
sl@0
   519
				break;
sl@0
   520
			case EWsWinOpSetTextCursorClipped:
sl@0
   521
				iTextCursor.SetL(*pData.SetTextCursor, ETrue);
sl@0
   522
				break;
sl@0
   523
			case EWsWinOpCancelTextCursor:
sl@0
   524
				iTextCursor.Cancel();
sl@0
   525
				break;
sl@0
   526
			case EWsWinOpSetOwningWindowGroup:
sl@0
   527
				iOwningWindowGroup=*pData.Int;
sl@0
   528
				break;
sl@0
   529
			case EWsWinOpDefaultOwningWindow:
sl@0
   530
				{
sl@0
   531
				if(KSecurityPolicy_WriteDeviceData().CheckPolicy(iWsOwner->ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWindowGroup::DefaultOwningWindow API")))
sl@0
   532
					{
sl@0
   533
					iScreen->SetDefaultOwningWindow(this);
sl@0
   534
					}
sl@0
   535
				}
sl@0
   536
				break;
sl@0
   537
			case EWsWinOpName:
sl@0
   538
				iWsOwner->ReplyGroupName(iGroupName,*pData.Int);
sl@0
   539
				break;
sl@0
   540
			case EWsWinOpSetName:
sl@0
   541
				{
sl@0
   542
				HBufC *newName=NULL;
sl@0
   543
				const TInt size=*pData.Int;
sl@0
   544
				if (size>0)
sl@0
   545
					{
sl@0
   546
					newName=HBufC::NewLC(size);
sl@0
   547
					TPtr ptr(newName->Des());
sl@0
   548
					iWsOwner->RemoteReadL(ptr,0);
sl@0
   549
					CleanupStack::Pop(newName);
sl@0
   550
					}
sl@0
   551
				//Window Group Name is unchanged
sl@0
   552
				if (iGroupName && newName && *iGroupName == *newName)
sl@0
   553
					{
sl@0
   554
					delete newName;
sl@0
   555
					} 
sl@0
   556
				else  //Window Group Name is changed
sl@0
   557
					{  
sl@0
   558
					delete iGroupName;
sl@0
   559
					iGroupName=newName;
sl@0
   560
					TWindowServerEvent::SendGroupChangedEvents();
sl@0
   561
					}
sl@0
   562
				}
sl@0
   563
				break;
sl@0
   564
			case EWsWinOpIdentifier:
sl@0
   565
				SetReply(Identifier());
sl@0
   566
				break;
sl@0
   567
			case EWsWinOpDisableKeyClick:
sl@0
   568
				if (*pData.Bool)
sl@0
   569
					iFlags|=EGroupFlagDisableKeyClick;
sl@0
   570
				else
sl@0
   571
					iFlags&=~EGroupFlagDisableKeyClick;
sl@0
   572
				if (this==CWsTop::FocusWindowGroup())
sl@0
   573
					UpdateKeyClickState();
sl@0
   574
				break;
sl@0
   575
			case EWsWinOpSendPointerEvent:
sl@0
   576
				if (!TWindowServerEvent::MousePress(*pData.RawEvent,this))
sl@0
   577
					OwnerPanic(EWservPanicEventType);
sl@0
   578
				break;
sl@0
   579
			case EWsWinOpClearChildGroup:
sl@0
   580
				if(iQueue)
sl@0
   581
					{				
sl@0
   582
					TBool fBefore=EFalse; 
sl@0
   583
					TBool fAfter=EFalse; 
sl@0
   584
					// If there is nothing to clear, return KErrArgument
sl@0
   585
					if(iQueue->Last()==this)
sl@0
   586
						{
sl@0
   587
						SetReply(KErrArgument);
sl@0
   588
						break;
sl@0
   589
						}
sl@0
   590
					// fBefore is True if there is AT LEAST one window group queued before the current one
sl@0
   591
					else if(iQueue->First()!=this)
sl@0
   592
						{
sl@0
   593
						fBefore=ETrue;
sl@0
   594
						}
sl@0
   595
					// fAfter is True if there is MORE THAN one window group queued after the current one
sl@0
   596
					TDblQueIter<CWsWindowGroup> iter(*iQueue);
sl@0
   597
					iter.SetToLast();
sl@0
   598
					if(iter--!=this && iter!=this)
sl@0
   599
						{
sl@0
   600
						fAfter=ETrue;
sl@0
   601
						}
sl@0
   602
					TDblQue<CWsWindowGroup>* queue=NULL;
sl@0
   603
					// if fBefore and fAfter are True, create a new queue and copy all window groups after the current one into that queue
sl@0
   604
					if(fBefore && fAfter)
sl@0
   605
						{
sl@0
   606
						TInt ret=KErrNoMemory;
sl@0
   607
						queue=new TDblQue<CWsWindowGroup>(_FOFF(CWsWindowGroup,iChainLink));
sl@0
   608
						if(queue)
sl@0
   609
							{
sl@0
   610
							ret=iChains.Append(queue);	
sl@0
   611
							if(ret!=KErrNone)
sl@0
   612
								{
sl@0
   613
								delete queue;
sl@0
   614
								queue = NULL;
sl@0
   615
								}
sl@0
   616
							}
sl@0
   617
						// Check that the queue creation and appending worked (we deque all the child groups even if it didn't) 
sl@0
   618
						if(ret!=KErrNone)
sl@0
   619
							{
sl@0
   620
							SetReply(ret);
sl@0
   621
							}
sl@0
   622
						}
sl@0
   623
					// If we've got zero or one window groups after, don't need to queue them
sl@0
   624
					if(!fAfter || fBefore)
sl@0
   625
						{
sl@0
   626
						iter.SetToLast();
sl@0
   627
						CWsWindowGroup* groupWin;
sl@0
   628
						while((groupWin=iter--)!=this)
sl@0
   629
							{
sl@0
   630
							groupWin->iChainLink.Deque();
sl@0
   631
							groupWin->iQueue=queue;
sl@0
   632
							if(queue)
sl@0
   633
								queue->AddFirst(*groupWin);
sl@0
   634
							}
sl@0
   635
						}
sl@0
   636
					// if we've got no window groups before, don't need to have a queue for this anymore
sl@0
   637
					if(!fBefore)
sl@0
   638
						{
sl@0
   639
						iChainLink.Deque();
sl@0
   640
						if (!fAfter)
sl@0
   641
							{
sl@0
   642
							DeleteQueue(iQueue);
sl@0
   643
							}
sl@0
   644
						iQueue=NULL;
sl@0
   645
						}
sl@0
   646
					}
sl@0
   647
				else // if this window group isn't queued, we can't clear any children
sl@0
   648
					{
sl@0
   649
					SetReply(KErrArgument);
sl@0
   650
					}
sl@0
   651
				break;
sl@0
   652
			case EWsWinOpSetChildGroup:
sl@0
   653
				{
sl@0
   654
				CWsWindowGroup* childWinGroup = CWsWindowGroup::WindowGroupFromIdentifier(*pData.Int);
sl@0
   655
				if(!childWinGroup																	//(no child to append)
sl@0
   656
					|| (iQueue && (!iQueue->IsLast(this) || (childWinGroup->iQueue==iQueue)))		//(GpWin has a child) || (GpWin and childGpWin in the same queue)
sl@0
   657
					|| (childWinGroup->iQueue && !childWinGroup->iQueue->IsFirst(childWinGroup))	//(childGpWin has a parent)
sl@0
   658
					|| (childWinGroup == this))														//(childGpWin == GpWin)
sl@0
   659
					{
sl@0
   660
					SetReply(KErrArgument);
sl@0
   661
					break;
sl@0
   662
					}
sl@0
   663
				if(iQueue)
sl@0
   664
				// If we have a chain, we're prepending ourselves to the child window group
sl@0
   665
				// So we take the childs chain and prepend each of the window groups in our own chain
sl@0
   666
				// beginning with the current window group and working backward
sl@0
   667
					{
sl@0
   668
					TDblQueIter<CWsWindowGroup> iter(*iQueue);
sl@0
   669
					iter.SetToLast();
sl@0
   670
					CWsWindowGroup* groupWin;
sl@0
   671
					if(childWinGroup->iQueue)
sl@0
   672
						{
sl@0
   673
						TDblQue<CWsWindowGroup>* oldQueue=iQueue;
sl@0
   674
						while((groupWin=iter--)!=NULL)
sl@0
   675
							{
sl@0
   676
							groupWin->iChainLink.Deque();
sl@0
   677
							childWinGroup->iQueue->AddFirst(*groupWin);
sl@0
   678
							groupWin->iQueue=childWinGroup->iQueue;
sl@0
   679
							}
sl@0
   680
						DeleteQueue(oldQueue);
sl@0
   681
						}
sl@0
   682
					else
sl@0
   683
						{
sl@0
   684
						iQueue->AddLast(*childWinGroup);
sl@0
   685
						childWinGroup->iQueue=iQueue;
sl@0
   686
						}
sl@0
   687
					}
sl@0
   688
				else
sl@0
   689
				// 1. If we don't have a chain, and if the child has a chain, we can simply prepend this wg to the child
sl@0
   690
				// wg chain
sl@0
   691
				// 2. If we don't have a chain, and if the child does not have a chain, need to create a chain with the child
sl@0
   692
				//    as the owning member, and prepend our window group
sl@0
   693
					{
sl@0
   694
					if(childWinGroup->iQueue)
sl@0
   695
						{
sl@0
   696
						childWinGroup->iQueue->AddFirst(*this);
sl@0
   697
						iQueue=childWinGroup->iQueue;
sl@0
   698
						}
sl@0
   699
					else
sl@0
   700
						{
sl@0
   701
						TDblQue<CWsWindowGroup>* queue=new TDblQue<CWsWindowGroup>(_FOFF(CWsWindowGroup,iChainLink));
sl@0
   702
						TInt ret=KErrNoMemory;
sl@0
   703
						if (queue)
sl@0
   704
							{
sl@0
   705
							ret=iChains.Append(queue);
sl@0
   706
							if(ret!=KErrNone)
sl@0
   707
								{
sl@0
   708
								delete queue;
sl@0
   709
								}
sl@0
   710
							}
sl@0
   711
						if(ret!=KErrNone)
sl@0
   712
							{
sl@0
   713
							SetReply(ret);
sl@0
   714
							break;
sl@0
   715
							}
sl@0
   716
						queue->AddFirst(*childWinGroup);
sl@0
   717
						childWinGroup->iQueue=queue;
sl@0
   718
						queue->AddFirst(*this);
sl@0
   719
						iQueue=queue;
sl@0
   720
						}						
sl@0
   721
					}
sl@0
   722
				}
sl@0
   723
				break;
sl@0
   724
			default:						// All other window commands disallowed
sl@0
   725
				OwnerPanic(EWservPanicOpcode);
sl@0
   726
			}
sl@0
   727
		}
sl@0
   728
#if defined(_DEBUG)
sl@0
   729
	rootWindow->CheckTree();
sl@0
   730
#endif
sl@0
   731
	}
sl@0
   732
	
sl@0
   733
TPoint CWsWindowGroup::Origin() const
sl@0
   734
	{
sl@0
   735
	return TPoint(0,0);
sl@0
   736
	}
sl@0
   737
	
sl@0
   738
TRect CWsWindowGroup::AbsRect() const
sl@0
   739
	{
sl@0
   740
	return (TRect(RootWindow()->Abs().iTl,RootWindow()->Size()));
sl@0
   741
	}
sl@0
   742
sl@0
   743
TSize CWsWindowGroup::Size() const
sl@0
   744
	{
sl@0
   745
	return RootWindow()->Size();
sl@0
   746
	}
sl@0
   747
	
sl@0
   748
void CWsWindowGroup::UpdateKeyClickState()
sl@0
   749
	{
sl@0
   750
	CClick::SetKeyClickOveride(iFlags&EGroupFlagDisableKeyClick);
sl@0
   751
	}
sl@0
   752
sl@0
   753
void CWsWindowGroup::SetOrdinalPosition(TInt aPos)
sl@0
   754
	{
sl@0
   755
	if (aPos==(TInt)KOrdinalPositionSwitchToOwningWindow)
sl@0
   756
		SwitchToOwningWindow(NULL);
sl@0
   757
	else
sl@0
   758
		SetOrdinalPosition(aPos,NULL);
sl@0
   759
	}
sl@0
   760
sl@0
   761
TBool CWsWindowGroup::SetOrdinalPosition(TInt aPos,CWsWindowGroup* aClosingWindow)
sl@0
   762
	{
sl@0
   763
	TBool ret=ETrue;
sl@0
   764
	if (!iQueue)
sl@0
   765
		ret=DoSetOrdinalPosition1(aPos,aClosingWindow);
sl@0
   766
	else
sl@0
   767
		{
sl@0
   768
		TDblQueIter<CWsWindowGroup> iter(*iQueue);
sl@0
   769
		CWsWindowGroup* group;
sl@0
   770
		iter.SetToLast();
sl@0
   771
		TInt after=0;
sl@0
   772
		TInt before=0;
sl@0
   773
		TInt* inc=&before;
sl@0
   774
		while ((group=iter--)!=NULL)
sl@0
   775
			{
sl@0
   776
			if (group==this)
sl@0
   777
				inc=&after;
sl@0
   778
			++(*inc);
sl@0
   779
			}
sl@0
   780
		TInt lastWinGpPos=NumWindowGroupsOnMyScreen(OrdinalPriority())-after;
sl@0
   781
		if (aPos<0)
sl@0
   782
			aPos=lastWinGpPos;
sl@0
   783
		else
sl@0
   784
			aPos=Min(aPos,lastWinGpPos);
sl@0
   785
		aPos-=before;
sl@0
   786
		aPos=Max(aPos,0);
sl@0
   787
		iter.SetToLast();
sl@0
   788
		CWsWindowGroup* firstForward=iter--;
sl@0
   789
		while (firstForward && firstForward->OrdinalPosition(EFalse)<aPos)
sl@0
   790
			{
sl@0
   791
			firstForward=iter--;
sl@0
   792
			++aPos;
sl@0
   793
			}
sl@0
   794
		if (!firstForward)
sl@0
   795
			iter.SetToFirst();
sl@0
   796
		else
sl@0
   797
			{
sl@0
   798
			iter.Set(*firstForward);
sl@0
   799
			MoveChainedWindows(iter,ETrue,aPos,aClosingWindow);
sl@0
   800
			iter.Set(*firstForward);
sl@0
   801
			iter++;
sl@0
   802
			}
sl@0
   803
		MoveChainedWindows(iter,EFalse,--aPos,aClosingWindow);
sl@0
   804
#if defined(_DEBUG)
sl@0
   805
		iter.SetToLast();
sl@0
   806
		TInt pos1=-1;
sl@0
   807
		TInt pos2;
sl@0
   808
		TBool ok=ETrue;
sl@0
   809
		while ((group=iter--)!=this)
sl@0
   810
			{
sl@0
   811
			pos2=group->OrdinalPosition(EFalse);
sl@0
   812
			if (pos2<=pos1)
sl@0
   813
				ok=EFalse;
sl@0
   814
			pos1=pos2;
sl@0
   815
			}
sl@0
   816
		WS_ASSERT_DEBUG(ok, EWsPanicGroupWindowChainError);
sl@0
   817
#endif
sl@0
   818
		}
sl@0
   819
sl@0
   820
	return ret;
sl@0
   821
	}
sl@0
   822
sl@0
   823
sl@0
   824
void CWsWindowGroup::MoveChainedWindows(TDblQueIter<CWsWindowGroup>& aIter,TBool aForward,TInt aPos,CWsWindowGroup* aClosingWindow)
sl@0
   825
	{
sl@0
   826
	CWsWindowGroup* groupWindow;
sl@0
   827
	while ((groupWindow=(aForward ? aIter-- : aIter++))!=NULL)
sl@0
   828
		{
sl@0
   829
		groupWindow->DoSetOrdinalPosition1(aPos,aClosingWindow);
sl@0
   830
		(aForward ? ++aPos : --aPos);
sl@0
   831
		}
sl@0
   832
	}
sl@0
   833
sl@0
   834
TBool CWsWindowGroup::DoSetOrdinalPosition1(TInt aPos,CWsWindowGroup* aClosingWindow)
sl@0
   835
	{
sl@0
   836
	TBool ret=EFalse;
sl@0
   837
	if (CheckOrdinalPositionChange(aPos))
sl@0
   838
		{
sl@0
   839
		if (Child())	// A group window with no children can not affect shadows
sl@0
   840
			{
sl@0
   841
			ret=ETrue;
sl@0
   842
			}
sl@0
   843
		DoSetOrdinalPosition2(aPos,aClosingWindow);
sl@0
   844
		}
sl@0
   845
	else
sl@0
   846
		iScreen->ResetFocus(aClosingWindow);
sl@0
   847
	return ret;
sl@0
   848
	}
sl@0
   849
sl@0
   850
void CWsWindowGroup::DoSetOrdinalPosition2(TInt aPos, CWsWindowGroup *aClosingWindow)
sl@0
   851
	{
sl@0
   852
	ChangeWindowPosition(aPos,iParent);
sl@0
   853
	ResetFocus(aClosingWindow);
sl@0
   854
	}
sl@0
   855
sl@0
   856
void CWsWindowGroup::LostFocus()
sl@0
   857
	{
sl@0
   858
	iTextCursor.LostFocus();
sl@0
   859
	iWsOwner->UpdateWindowOrdinalPrioritys();
sl@0
   860
	if (iClientHandle!=0)
sl@0
   861
		QueueEvent(EEventFocusLost);
sl@0
   862
	TWalkWindowTreeFocusChanged wwt(EFalse);
sl@0
   863
	WalkWindowTree(wwt,EWalkChildren);
sl@0
   864
	iWsOwner->SetClientPriority();
sl@0
   865
	}
sl@0
   866
sl@0
   867
void CWsWindowGroup::ReceivedFocus()
sl@0
   868
	{
sl@0
   869
	iWsOwner->UpdateWindowOrdinalPrioritys();
sl@0
   870
	iTextCursor.ReceivedFocus();
sl@0
   871
	// Used for event queue testing
sl@0
   872
	// Calling MoveToFront sets the queue of the focused window to first place, 
sl@0
   873
	// not doing so puts the queues in unusual situation thus stress testing the queue code. 
sl@0
   874
	// One such situation is where the focus queue is first but there is a gap before it (iEventPtr>iGlobalEventPtr)" 
sl@0
   875
#if defined(_DEBUG)
sl@0
   876
	if (++iSkipCount==5)
sl@0
   877
		{
sl@0
   878
		iSkipCount=0;
sl@0
   879
		}
sl@0
   880
	else
sl@0
   881
		{
sl@0
   882
		WsOwner()->EventQueue()->MoveToFront();
sl@0
   883
		}
sl@0
   884
#else
sl@0
   885
	WsOwner()->EventQueue()->MoveToFront();
sl@0
   886
#endif
sl@0
   887
	QueueEvent(EEventFocusGained);
sl@0
   888
	TWalkWindowTreeFocusChanged wwt(ETrue);
sl@0
   889
	WalkWindowTree(wwt,EWalkChildren);
sl@0
   890
	iWsOwner->SetClientPriority();
sl@0
   891
	UpdateKeyClickState();
sl@0
   892
	}
sl@0
   893
sl@0
   894
TInt CWsWindowGroup::NumWindowGroups(TBool aAllPriorities, TInt aPriority)
sl@0
   895
	{
sl@0
   896
	TInt count=0;
sl@0
   897
	TInt screenNo;
sl@0
   898
	for(screenNo=0;screenNo<CWsTop::NumberOfScreens();++screenNo)
sl@0
   899
		{
sl@0
   900
		count+=CWsWindowGroup::NumWindowGroupsOnScreen(CWsTop::Screen(screenNo)->RootWindow()->Child(),aAllPriorities,aPriority);
sl@0
   901
		}
sl@0
   902
	return(count);
sl@0
   903
	}
sl@0
   904
sl@0
   905
TInt CWsWindowGroup::NumWindowGroupsOnScreen(const CWsWindowGroup* aGroupWin,TBool aAllPriorities,TInt aPriority)
sl@0
   906
	{
sl@0
   907
	TInt count=0;
sl@0
   908
	while (aGroupWin)
sl@0
   909
		{
sl@0
   910
		if (aAllPriorities || aGroupWin->iOrdinalPriority==aPriority)
sl@0
   911
			++count;
sl@0
   912
		aGroupWin=aGroupWin->NextSibling();
sl@0
   913
		}
sl@0
   914
	return count;
sl@0
   915
	}
sl@0
   916
sl@0
   917
inline TInt CWsWindowGroup::NumWindowGroupsOnMyScreen(TInt aPriority)
sl@0
   918
	{
sl@0
   919
	return(CWsWindowGroup::NumWindowGroupsOnScreen(Parent()->Child(),EFalse,aPriority));
sl@0
   920
	}
sl@0
   921
sl@0
   922
void CWsWindowGroup::GetFocusWindowGroupL(TInt aScreenNumber)
sl@0
   923
	{
sl@0
   924
	CWsWindowGroup *groupWin=(aScreenNumber==KDummyScreenNumber)?CWsTop::FocusWindowGroup():CWsTop::Screen(aScreenNumber)->FocusWindowGroup();	
sl@0
   925
	if (!groupWin)
sl@0
   926
		User::Leave(KErrGeneral);
sl@0
   927
	CWsClient::SetReply(groupWin->Identifier());
sl@0
   928
	}
sl@0
   929
sl@0
   930
TInt CWsWindowGroup::GetWindowGroupListL(TInt aScreenNo,TBool aAllPriorities,TInt aPriority,TInt aCount,CArrayFixFlat<TInt>* aList)
sl@0
   931
	{
sl@0
   932
	TInt count=aList->Count();
sl@0
   933
	CWsWindowGroup* groupWin=CWsTop::Screen(aScreenNo)->RootWindow()->Child();
sl@0
   934
	while(!aAllPriorities && groupWin && groupWin->iOrdinalPriority!=aPriority)
sl@0
   935
		groupWin=groupWin->NextSibling();
sl@0
   936
	while(groupWin && (aAllPriorities || groupWin->iOrdinalPriority==aPriority) && count<aCount)
sl@0
   937
		{
sl@0
   938
		aList->AppendL(groupWin->Identifier());
sl@0
   939
		++count;
sl@0
   940
		groupWin=groupWin->NextSibling();
sl@0
   941
		}
sl@0
   942
	return count;
sl@0
   943
	}
sl@0
   944
	
sl@0
   945
TInt CWsWindowGroup::SendWindowGroupListL(TInt aScreenNumber, TBool aAllPriorities, TInt aPriority, TInt aCount)
sl@0
   946
	{
sl@0
   947
	if ((aCount<1) || (aCount>(KArrayMaxGranularity/sizeof(TInt))))
sl@0
   948
		User::Leave(KErrArgument);
sl@0
   949
	CArrayFixFlat<TInt>* list=new(ELeave) CArrayFixFlat<TInt>(aCount);
sl@0
   950
	CleanupStack::PushL(list);
sl@0
   951
	TInt count(0);	
sl@0
   952
	TInt requestedScreen=aScreenNumber;	
sl@0
   953
	
sl@0
   954
	if(requestedScreen==KDummyScreenNumber)
sl@0
   955
		{		
sl@0
   956
		// get list from current focus screen first
sl@0
   957
		TInt focusScreenNo=CWsTop::CurrentFocusScreen()->ScreenNumber();
sl@0
   958
		count=GetWindowGroupListL(focusScreenNo, aAllPriorities, aPriority, aCount, list);
sl@0
   959
		if(count<aCount)
sl@0
   960
			{
sl@0
   961
			// now get from the remaining screen
sl@0
   962
			TInt screenNo;
sl@0
   963
			for(screenNo=0;screenNo<CWsTop::NumberOfScreens() && count<aCount;++screenNo)
sl@0
   964
				{
sl@0
   965
				// skip focus screen
sl@0
   966
				if (screenNo==focusScreenNo)
sl@0
   967
					continue;
sl@0
   968
				// count hold total number of window groups collected so far
sl@0
   969
				count=GetWindowGroupListL(screenNo, aAllPriorities, aPriority, aCount, list);
sl@0
   970
				}			
sl@0
   971
			}
sl@0
   972
		}
sl@0
   973
	else
sl@0
   974
		{
sl@0
   975
		count=GetWindowGroupListL(requestedScreen, aAllPriorities, aPriority, aCount, list);	
sl@0
   976
		}
sl@0
   977
	
sl@0
   978
	if (list->Count() > 0)	
sl@0
   979
		CWsClient::ReplyBuf(&list->At(0),count*sizeof(TInt));
sl@0
   980
	CleanupStack::PopAndDestroy(list);
sl@0
   981
	return(count);	// How many actually returned, may be less than asked for, but not more
sl@0
   982
	}
sl@0
   983
sl@0
   984
void CWsWindowGroup::GetWindowGroupListAndChainL(TInt aScreen,TBool aAllPriorities,TInt aPriority
sl@0
   985
																,RArray<RWsSession::TWindowGroupChainInfo>& list,TInt& aCountLeft)
sl@0
   986
	{
sl@0
   987
	CWsWindowGroup *groupWin=CWsTop::Screen(aScreen)->RootWindow()->Child();
sl@0
   988
	while(!aAllPriorities && groupWin && groupWin->iOrdinalPriority!=aPriority)
sl@0
   989
		groupWin=groupWin->NextSibling();
sl@0
   990
	while(groupWin && (aAllPriorities || groupWin->iOrdinalPriority==aPriority) && aCountLeft>0)
sl@0
   991
		{
sl@0
   992
		RWsSession::TWindowGroupChainInfo windowId;
sl@0
   993
		windowId.iId=groupWin->Identifier();
sl@0
   994
		if(!groupWin->IsChained(windowId.iParentId))
sl@0
   995
			windowId.iParentId=-1;	//Unchained window group
sl@0
   996
		list.AppendL(windowId);
sl@0
   997
		--aCountLeft;
sl@0
   998
		groupWin=groupWin->NextSibling();
sl@0
   999
		}
sl@0
  1000
	}
sl@0
  1001
sl@0
  1002
TInt CWsWindowGroup::SendWindowGroupListAndChainL(TBool aAllPriorities, TInt aPriority, TInt aCount)
sl@0
  1003
	{
sl@0
  1004
	if ((aCount<1) || (aCount>(KArrayMaxGranularity/sizeof(RWsSession::TWindowGroupChainInfo))))
sl@0
  1005
		User::Leave(KErrArgument);
sl@0
  1006
	RArray<RWsSession::TWindowGroupChainInfo> list(aCount);
sl@0
  1007
	CleanupClosePushL(list);
sl@0
  1008
	TInt count=aCount;
sl@0
  1009
	TInt focusScreenNo=CWsTop::CurrentFocusScreen()->ScreenNumber();
sl@0
  1010
	GetWindowGroupListAndChainL(focusScreenNo,aAllPriorities,aPriority,list,count);
sl@0
  1011
	TInt screenNo;
sl@0
  1012
	for(screenNo=0;screenNo<CWsTop::NumberOfScreens();++screenNo)
sl@0
  1013
		{
sl@0
  1014
		if (screenNo!=focusScreenNo)
sl@0
  1015
			GetWindowGroupListAndChainL(screenNo,aAllPriorities,aPriority,list,count);
sl@0
  1016
		}
sl@0
  1017
	if (list.Count() > 0)
sl@0
  1018
		CWsClient::ReplyBuf(&list[0],aCount*sizeof(RWsSession::TWindowGroupChainInfo));
sl@0
  1019
	CleanupStack::PopAndDestroy(&list);
sl@0
  1020
	return(aCount-count);	// How many actually returned, may be less than asked for, but not more
sl@0
  1021
	}
sl@0
  1022
sl@0
  1023
TBool CWsWindowGroup::SendEventToAllGroups(TBool aAllPriorities,TBool aOnePerClient,const TWsClCmdSendEventToWindowGroup& aData)
sl@0
  1024
	{
sl@0
  1025
	TWsEvent event=aData.event;
sl@0
  1026
	if (event.Type()==EEventKey && event.Key()->iRepeats!=0)
sl@0
  1027
		CKeyboardRepeat::CancelRepeat(NULL);		//Otherwise we will trip an invarient
sl@0
  1028
	TInt priority=aData.parameter;
sl@0
  1029
	TBool sentToAll=ETrue;
sl@0
  1030
	TInt screenNo;
sl@0
  1031
	for(screenNo=0;screenNo<CWsTop::NumberOfScreens();++screenNo)
sl@0
  1032
		{
sl@0
  1033
		CWsWindowGroup *groupWin=CWsTop::Screen(screenNo)->RootWindow()->Child();
sl@0
  1034
		if (!aAllPriorities)
sl@0
  1035
			{
sl@0
  1036
			while(groupWin && groupWin->iOrdinalPriority!=priority)
sl@0
  1037
				groupWin=groupWin->NextSibling();
sl@0
  1038
			}
sl@0
  1039
		CWsWindowGroup* firstGroupWin=groupWin;
sl@0
  1040
		CWsClient* lastOwner=NULL;
sl@0
  1041
		CWsWindowGroup* groupWin2;
sl@0
  1042
		while(groupWin && (aAllPriorities || groupWin->iOrdinalPriority==priority))
sl@0
  1043
			{
sl@0
  1044
			if (aOnePerClient)
sl@0
  1045
				{
sl@0
  1046
				if (lastOwner==groupWin->iWsOwner)
sl@0
  1047
					goto ContinueLoop;
sl@0
  1048
				lastOwner=groupWin->iWsOwner;
sl@0
  1049
				for(groupWin2=firstGroupWin;groupWin2!=groupWin;groupWin2=groupWin2->NextSibling())
sl@0
  1050
					{
sl@0
  1051
					if (groupWin2->iWsOwner==groupWin->iWsOwner)
sl@0
  1052
						break;
sl@0
  1053
					}
sl@0
  1054
				if (groupWin2->iWsOwner==groupWin->iWsOwner && groupWin2!=groupWin)
sl@0
  1055
					goto ContinueLoop;
sl@0
  1056
				}
sl@0
  1057
			event.SetHandle(groupWin->ClientHandle());
sl@0
  1058
			if (!groupWin->EventQueue()->QueueEvent(event))
sl@0
  1059
				sentToAll=EFalse;
sl@0
  1060
		ContinueLoop:
sl@0
  1061
			groupWin=groupWin->NextSibling();
sl@0
  1062
			}
sl@0
  1063
		}
sl@0
  1064
	return sentToAll;
sl@0
  1065
	}
sl@0
  1066
sl@0
  1067
void CWsWindowGroup::SendMessageToAllGroupsL(CWsClient& aSender,TBool aAllPriorities,const TWsClCmdSendMessageToWindowGroup& aData)
sl@0
  1068
	{
sl@0
  1069
	TInt screenNo;
sl@0
  1070
	for(screenNo=0;screenNo<CWsTop::NumberOfScreens();++screenNo)
sl@0
  1071
		{
sl@0
  1072
		CWsWindowGroup* groupWin=CWsTop::Screen(screenNo)->RootWindow()->Child();		
sl@0
  1073
		if (!aAllPriorities)
sl@0
  1074
			{
sl@0
  1075
			while(groupWin && groupWin->iOrdinalPriority!=aData.identifierOrPriority)
sl@0
  1076
				groupWin=groupWin->NextSibling();
sl@0
  1077
			}
sl@0
  1078
		while(groupWin && (aAllPriorities || (groupWin->iOrdinalPriority==aData.identifierOrPriority)))
sl@0
  1079
			{
sl@0
  1080
			groupWin->QueueMessageL(aData.uid, aData.dataLength, aSender);
sl@0
  1081
			groupWin=groupWin->NextSibling();
sl@0
  1082
			}
sl@0
  1083
		}
sl@0
  1084
	}
sl@0
  1085
sl@0
  1086
CWsWindowGroup *CWsWindowGroup::WindowGroupFromIdentifier(TInt aIdentifier)
sl@0
  1087
	{
sl@0
  1088
	// apply to all screens
sl@0
  1089
	TInt screenNo;
sl@0
  1090
	for (screenNo=0; screenNo<CWsTop::NumberOfScreens(); ++screenNo)
sl@0
  1091
		{
sl@0
  1092
		CWsWindowGroup* group;
sl@0
  1093
		for(group=CWsTop::Screen(screenNo)->RootWindow()->Child(); group; group=group->NextSibling())
sl@0
  1094
			{
sl@0
  1095
			if (group->Identifier() == aIdentifier)
sl@0
  1096
				return group;
sl@0
  1097
			}
sl@0
  1098
			
sl@0
  1099
		}
sl@0
  1100
		
sl@0
  1101
	return NULL;
sl@0
  1102
	}
sl@0
  1103
sl@0
  1104
CWsWindowGroup *CWsWindowGroup::WindowGroupFromIdentifierL(TInt aIdentifier)
sl@0
  1105
	{
sl@0
  1106
	CWsWindowGroup *group=WindowGroupFromIdentifier(aIdentifier);
sl@0
  1107
	if (!group)
sl@0
  1108
		User::Leave(KErrNotFound);
sl@0
  1109
	return(group);
sl@0
  1110
	}
sl@0
  1111
sl@0
  1112
CWsWindowGroup *CWsWindowGroup::FindWindowGroupL(CWsClient* aClient, TInt aIdentifier,TInt aOffset,const TPtrC *aMatch,const TThreadId *aThreadId)
sl@0
  1113
	{
sl@0
  1114
	CWsWindowGroup *group;
sl@0
  1115
	if (aIdentifier)
sl@0
  1116
		{
sl@0
  1117
		group=WindowGroupFromIdentifier(aIdentifier);
sl@0
  1118
		if (group)	// NULL group will cause KErrNotFound to be returned
sl@0
  1119
			group=group->NextSibling();
sl@0
  1120
		}
sl@0
  1121
	else
sl@0
  1122
		{
sl@0
  1123
		// get window group for this session
sl@0
  1124
		//
sl@0
  1125
		group = aClient->Screen()->RootWindow()->Child();
sl@0
  1126
		}
sl@0
  1127
sl@0
  1128
	for(;group;group=group->NextSibling())
sl@0
  1129
		{
sl@0
  1130
		if (aThreadId)
sl@0
  1131
			{
sl@0
  1132
			if (group->WsOwner()->Client().Id()==*aThreadId)
sl@0
  1133
				break;	// Found one
sl@0
  1134
			}
sl@0
  1135
		else
sl@0
  1136
			{
sl@0
  1137
			const TDesC *groupName=&nullDescriptor;
sl@0
  1138
			if (group->GroupName())
sl@0
  1139
				groupName=group->GroupName();
sl@0
  1140
			if (groupName->Length()>=aOffset && groupName->Mid(aOffset).MatchF(*aMatch)>=0)
sl@0
  1141
				break;	// Found one
sl@0
  1142
			}
sl@0
  1143
		}
sl@0
  1144
	if (!group)
sl@0
  1145
		User::Leave(KErrNotFound);
sl@0
  1146
	return(group);
sl@0
  1147
	}
sl@0
  1148
sl@0
  1149
void CWsWindowGroup::AddPriorityKeyL(TUint aKeycode, TUint aModifierMask, TUint aModifiers)
sl@0
  1150
	{
sl@0
  1151
	iPriorityKeys=new(ELeave) TPriorityKey(aKeycode,aModifierMask,aModifiers,iPriorityKeys);
sl@0
  1152
	}
sl@0
  1153
sl@0
  1154
void CWsWindowGroup::RemovePriorityKey(TUint aKeycode, TUint aModifierMask, TUint aModifiers)
sl@0
  1155
	{
sl@0
  1156
	for(TPriorityKey **ppk=&iPriorityKeys;*ppk;ppk=&((*ppk)->iNext))
sl@0
  1157
		if ((*ppk)->Equals(aKeycode, aModifierMask, aModifiers))
sl@0
  1158
			{
sl@0
  1159
			TPriorityKey *next=(*ppk)->iNext;
sl@0
  1160
			delete *ppk;
sl@0
  1161
			*ppk=next;
sl@0
  1162
			break;
sl@0
  1163
			}
sl@0
  1164
	}
sl@0
  1165
sl@0
  1166
void CWsWindowGroup::RemoveAllPriorityKeys()
sl@0
  1167
	{
sl@0
  1168
	TPriorityKey *pk=iPriorityKeys;
sl@0
  1169
	while(pk)
sl@0
  1170
		{
sl@0
  1171
		TPriorityKey *next=pk->iNext;
sl@0
  1172
		delete pk;
sl@0
  1173
		pk=next;
sl@0
  1174
		}
sl@0
  1175
	}
sl@0
  1176
sl@0
  1177
TBool CWsWindowGroup::CheckForPriorityKey(const TKeyData &aKey, TInt aScanCode)
sl@0
  1178
	{
sl@0
  1179
	for(TPriorityKey *pk=iPriorityKeys;pk;pk=pk->iNext)
sl@0
  1180
		{
sl@0
  1181
		if (pk->KeyMatches(aKey))
sl@0
  1182
			{	
sl@0
  1183
			WsOwner()->PriorityKeyPressed(ClientHandle(),aKey, aScanCode);
sl@0
  1184
			return(ETrue);
sl@0
  1185
			}
sl@0
  1186
		}
sl@0
  1187
	return(EFalse);
sl@0
  1188
	}
sl@0
  1189
sl@0
  1190
void CWsWindowGroup::StatusDump(TDes &aBuf)
sl@0
  1191
	{
sl@0
  1192
	_LIT(KWSERVStatusDumpWindowGroupInfo,"CWsWindowGroup[0x%x]RWindowGroup[0x%x,%d],Pri=%d,Id=%d,SizeMode=%d");
sl@0
  1193
	aBuf.AppendFormat(KWSERVStatusDumpWindowGroupInfo,this,iClientHandle,LogHandle(),iOrdinalPriority,iIdentifier,iScreenDevice?iScreenDevice->AppMode():0);
sl@0
  1194
	}
sl@0
  1195
sl@0
  1196
void CWsWindowGroup::SignalMessageReady()
sl@0
  1197
	{
sl@0
  1198
	TWsEvent event;
sl@0
  1199
	event.SetType(EEventMessageReady);
sl@0
  1200
	event.SetHandle(ClientHandle());
sl@0
  1201
	event.SetTimeNow();
sl@0
  1202
	SEventMessageReady& eventMessageReady=*(SEventMessageReady*)event.EventData();
sl@0
  1203
	eventMessageReady.iWindowGroupIdentifier=Identifier();
sl@0
  1204
	eventMessageReady.iMessageUid=(*iMessageArray)[0].iUid;
sl@0
  1205
	eventMessageReady.iMessageParametersSize=iMessageArray->Length(0)-sizeof(TUid);
sl@0
  1206
	if(WsOwner()->EventQueue()->QueueEvent(event,EEventPriorityHigh))
sl@0
  1207
		{
sl@0
  1208
		iFlags|=EGroupFlagMessageSignalled;
sl@0
  1209
		}
sl@0
  1210
	}
sl@0
  1211
sl@0
  1212
void CWsWindowGroup::QueueMessageL(TUid aUid, TInt aDataLength, CWsClient& aSender)
sl@0
  1213
	{
sl@0
  1214
	WS_ASSERT_DEBUG(iFlags&(EGroupFlagMsgQueueActive|EGroupFlagMsgQueueNew) || iMessageArray->Count()>=1,EWsPanicMsgQueueError);
sl@0
  1215
	if (!(iFlags&(EGroupFlagMsgQueueActive|EGroupFlagMsgQueueNew)) && iMessageArray->Count()>=KMaxNumberOfMsgsInInactiveQueue)
sl@0
  1216
		{
sl@0
  1217
		WS_ASSERT_DEBUG(iMessageArray->Count()<=KMaxNumberOfMsgsInInactiveQueue,EWsPanicMsgQueueError);
sl@0
  1218
		iMessageArray->Delete(1,iMessageArray->Count()-1);
sl@0
  1219
		}
sl@0
  1220
	TWsMessage* message=NULL;
sl@0
  1221
	TRAPD(err,message=&iMessageArray->ExtendL(aDataLength+sizeof(aUid)));
sl@0
  1222
	if ((err || (iFlags&EGroupFlagMsgQueueNew)) && iMessageArray->Count()>KMaxNumberOfMsgsInQueue)
sl@0
  1223
		{
sl@0
  1224
		iFlags&=~(EGroupFlagMsgQueueActive|EGroupFlagMsgQueueNew);
sl@0
  1225
		iMessageArray->Delete(1,iMessageArray->Count()-(err?1:2));
sl@0
  1226
		iMessageArray->Compress();
sl@0
  1227
		}
sl@0
  1228
	User::LeaveIfError(err);
sl@0
  1229
	if (message)
sl@0
  1230
		{
sl@0
  1231
		message->iUid=aUid;
sl@0
  1232
		TPtr8 ptr(&message->iTheRest[0],aDataLength);
sl@0
  1233
		TRAP(err,aSender.RemoteReadL(ptr,0));
sl@0
  1234
		if (err)
sl@0
  1235
			{
sl@0
  1236
			iMessageArray->Delete(iMessageArray->Count()-1);
sl@0
  1237
			User::Leave(err);
sl@0
  1238
			}
sl@0
  1239
		if (!(iFlags&EGroupFlagMessageSignalled))
sl@0
  1240
			{
sl@0
  1241
			WS_ASSERT_DEBUG(iMessageArray->Count()==1,EWsPanicMsgQueueError);
sl@0
  1242
			SignalMessageReady();
sl@0
  1243
			}
sl@0
  1244
		}
sl@0
  1245
	}
sl@0
  1246
sl@0
  1247
void CWsWindowGroup::FetchMessageL()
sl@0
  1248
	{
sl@0
  1249
	if (!(iFlags&EGroupFlagMessageSignalled))
sl@0
  1250
		{
sl@0
  1251
		OwnerPanic(EWservPanicFetchMessage);
sl@0
  1252
		}
sl@0
  1253
	CWsClient::ReplyBuf(&((*iMessageArray)[0].iTheRest[0]),(TInt)iMessageArray->Length(0)-sizeof(TUid));
sl@0
  1254
	iMessageArray->Delete(0);
sl@0
  1255
	iFlags|=EGroupFlagMsgQueueActive;
sl@0
  1256
	iFlags&=~(EGroupFlagMessageSignalled|EGroupFlagMsgQueueNew);
sl@0
  1257
	if (iMessageArray->Count()>0)
sl@0
  1258
		{
sl@0
  1259
		SignalMessageReady();
sl@0
  1260
		}
sl@0
  1261
	}
sl@0
  1262
sl@0
  1263
TBool CWsWindowGroup::ScreenDeviceValid() const
sl@0
  1264
	{
sl@0
  1265
	return(iScreenDevice?iScreenDevice->ScreenDeviceValidState():(iScreen->ScreenSizeMode()==0));
sl@0
  1266
	}
sl@0
  1267
sl@0
  1268
TBool CWsWindowGroup::CanReceiveFocus() const
sl@0
  1269
	{
sl@0
  1270
	return(ReceivesFocus() && iWsOwner->NotClosing() && (ScreenDeviceValid() || iFlags&EGroupFlagHandlesDeviceChange));
sl@0
  1271
	}
sl@0
  1272
sl@0
  1273
void CWsWindowGroup::SetScreenChangeEventStateL(TBool aEnabled)
sl@0
  1274
	{
sl@0
  1275
	iFlags&=~EGroupFlagHandlesDeviceChange;
sl@0
  1276
	if (aEnabled)
sl@0
  1277
		{
sl@0
  1278
		iFlags|=EGroupFlagHandlesDeviceChange;
sl@0
  1279
		TWindowServerEvent::AddToScreenDeviceChangeEventListL(*this);
sl@0
  1280
		if (iScreen->ScreenSizeMode()!=0)
sl@0
  1281
			TWindowServerEvent::SendScreenDeviceChangedEvent(this);
sl@0
  1282
		}
sl@0
  1283
	else
sl@0
  1284
		TWindowServerEvent::RemoveFromScreenDeviceChangeEventList(*this);
sl@0
  1285
	iScreen->ResetFocus(NULL);
sl@0
  1286
	}
sl@0
  1287
sl@0
  1288
void CWsWindowGroup::SetScreenDeviceValidState(const DWsScreenDevice *aDevice)
sl@0
  1289
	{
sl@0
  1290
	if (iScreenDevice==aDevice)
sl@0
  1291
		{
sl@0
  1292
		TBool state=ScreenDeviceValid();
sl@0
  1293
		for(CWsClientWindow *win=Child();win;win=win->NextSibling())
sl@0
  1294
			{
sl@0
  1295
			win->SetScreenDeviceValidState(state);
sl@0
  1296
			}
sl@0
  1297
		}
sl@0
  1298
	}
sl@0
  1299
sl@0
  1300
void CWsWindowGroup::SetScreenDeviceValidStates(const DWsScreenDevice *aDevice)
sl@0
  1301
	{
sl@0
  1302
	for(CWsWindowGroup *groupWin=aDevice->RootWindow()->Child();groupWin;groupWin=groupWin->NextSibling())
sl@0
  1303
		groupWin->SetScreenDeviceValidState(aDevice);
sl@0
  1304
	}
sl@0
  1305
sl@0
  1306
TBool CWsWindowGroup::SetScreenDeviceValidStates(const TBool aScreenSizeChanged,const TBool aSwapWidthAndHeight, CScreen* aScreen)
sl@0
  1307
	{
sl@0
  1308
	TBool ret=EFalse;
sl@0
  1309
	CWsRootWindow* rootWindow = aScreen->RootWindow();
sl@0
  1310
sl@0
  1311
	CWsWindowGroup* groupWin;
sl@0
  1312
	CWsClientWindow* win;
sl@0
  1313
	for(groupWin=rootWindow->Child();groupWin;groupWin=groupWin->NextSibling())
sl@0
  1314
		{
sl@0
  1315
		TBool state=groupWin->ScreenDeviceValid();
sl@0
  1316
		for(win=groupWin->Child();win;win=win->NextSibling())
sl@0
  1317
			{
sl@0
  1318
			win->SetScreenDeviceValidStateFlag(state);
sl@0
  1319
			win->ResetHiddenFlagsInParentAndChildren();
sl@0
  1320
			}
sl@0
  1321
		}
sl@0
  1322
	if (aScreenSizeChanged)
sl@0
  1323
		{
sl@0
  1324
		rootWindow->ScreenSizeChanged(aSwapWidthAndHeight);
sl@0
  1325
		}
sl@0
  1326
sl@0
  1327
	aScreen->AddRedrawRegion(rootWindow->WindowArea());
sl@0
  1328
sl@0
  1329
	return ret;
sl@0
  1330
	}
sl@0
  1331
sl@0
  1332
void CWsWindowGroup::SetScreenDevice(DWsScreenDevice *aDevice)
sl@0
  1333
	{
sl@0
  1334
	iScreenDevice=aDevice;	
sl@0
  1335
	}
sl@0
  1336
sl@0
  1337
void CWsWindowGroup::NewOrientation(TInt aMode,CFbsBitGc::TGraphicsOrientation aRotation, CWsRootWindow* aRootWindow)
sl@0
  1338
	{
sl@0
  1339
	for(CWsWindowGroup *groupWin=aRootWindow->Child();groupWin;groupWin=groupWin->NextSibling())
sl@0
  1340
		{
sl@0
  1341
		DWsScreenDevice *device=groupWin->Device();
sl@0
  1342
		if (device)
sl@0
  1343
			device->NewOrientation(aMode,aRotation);
sl@0
  1344
		}
sl@0
  1345
	}
sl@0
  1346
sl@0
  1347
void CWsWindowGroup::ResetFocus(CWsWindowGroup *aClosingWindow)
sl@0
  1348
	{
sl@0
  1349
	if (iScreen)
sl@0
  1350
		{
sl@0
  1351
		iScreen->ResetFocus(aClosingWindow);
sl@0
  1352
		}
sl@0
  1353
	}
sl@0
  1354
sl@0
  1355
TBool CWsWindowGroup::IsChained(TInt& aParentId)
sl@0
  1356
	{
sl@0
  1357
	if (!iQueue)
sl@0
  1358
		return EFalse;
sl@0
  1359
	if (iQueue->First()==this)
sl@0
  1360
		aParentId=0;
sl@0
  1361
	else
sl@0
  1362
		aParentId=BeforeInChain()->Identifier();
sl@0
  1363
	return ETrue;
sl@0
  1364
	}
sl@0
  1365
sl@0
  1366
inline CWsWindowGroup* CWsWindowGroup::BeforeInChain()
sl@0
  1367
	{		//You should only call this function if you know the window has a parent
sl@0
  1368
	return reinterpret_cast<CWsWindowGroup*>(PtrSub(iChainLink.iPrev,_FOFF(CWsWindowGroup,iChainLink)));
sl@0
  1369
	}
sl@0
  1370
sl@0
  1371
TBool CWsWindowGroup::CheckCapability(TInt& aOrdinalPriority)
sl@0
  1372
	{
sl@0
  1373
	if(aOrdinalPriority>=KPasswordWindowGroupPriority)
sl@0
  1374
		{
sl@0
  1375
		if(!KSecurityPolicy_SwEvent().CheckPolicy(WsOwner()->Client(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed")))
sl@0
  1376
			{
sl@0
  1377
			aOrdinalPriority=KPasswordWindowGroupPriority-1;
sl@0
  1378
			return EFalse;
sl@0
  1379
			}
sl@0
  1380
		}
sl@0
  1381
 	return ETrue;
sl@0
  1382
	}
sl@0
  1383
	
sl@0
  1384
TBool CWsWindowGroup::HasVisibleTranslucentChild()
sl@0
  1385
	{
sl@0
  1386
	CWsWindowBase * child = iChild;
sl@0
  1387
	while (child)
sl@0
  1388
		{
sl@0
  1389
		if (child->WinType() == EWinTypeClient)
sl@0
  1390
			{
sl@0
  1391
			CWsClientWindow * cliwin = static_cast<CWsClientWindow *>(child);
sl@0
  1392
			if (cliwin->IsTranslucent() && cliwin->IsVisible())
sl@0
  1393
				return ETrue;
sl@0
  1394
			}
sl@0
  1395
		else if (static_cast<CWsWindowGroup*>(child)->HasVisibleTranslucentChild())
sl@0
  1396
			{
sl@0
  1397
			return ETrue;
sl@0
  1398
			}
sl@0
  1399
		child = child->NextSibling();
sl@0
  1400
		}
sl@0
  1401
	return EFalse;
sl@0
  1402
	}
sl@0
  1403
sl@0
  1404
TInt CWsWindowGroup::NumClientWindowGroups()
sl@0
  1405
	{
sl@0
  1406
	CWsObjectIx& objix=*WsOwner()->ObjectIndex();
sl@0
  1407
	const TWsObject* ptr=objix.FirstObject();
sl@0
  1408
	const TWsObject* end=ptr+objix.Length();
sl@0
  1409
	TInt count=0;
sl@0
  1410
	while(++ptr<end)		//First one should always have a NULL object
sl@0
  1411
		{
sl@0
  1412
		const CWsObject* obj=ptr->iObject;
sl@0
  1413
		if (obj && obj->Type()==WS_HANDLE_GROUP_WINDOW)
sl@0
  1414
			++count;
sl@0
  1415
		}
sl@0
  1416
	return count;
sl@0
  1417
	}
sl@0
  1418