windowing/windowserver/nonnga/SERVER/CLIENT.CPP
changeset 0 5d03bc08d59c
child 11 fed1595b188e
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1994-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 handling
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "CLIENT.H"
       
    19 
       
    20 #include "ANIM.H"
       
    21 #include "Direct.H"
       
    22 #include "EVENT.H"
       
    23 #include "KEYCLICK.H"
       
    24 #include "server.h"
       
    25 #include "gc.h"
       
    26 #include "rootwin.h"
       
    27 #include "windowgroup.h"
       
    28 #include "wstop.h"
       
    29 #include "panics.h"
       
    30 #include "../CLIENT/w32comm.h"
       
    31 #include "password.h"
       
    32 #include "pointer.h"
       
    33 #include <u32hal.h> // EHalGroupEmulator
       
    34 #include "WsMemMgr.h"
       
    35 
       
    36 GLREF_C void HeapDump();
       
    37 
       
    38 GLREF_D CDebugLogBase *wsDebugLog;
       
    39 
       
    40 GLREF_D TPtr nullDescriptor;
       
    41 
       
    42 TWsCmdHeaderBase CWsClient::iCurrentCommand;
       
    43 TBuf8<EClientBufferMaxSize> CWsClient::iCmdBuf;
       
    44 TUint CWsClient::iConnectionId=CDebugLogBase::EDummyConnectionId+1;
       
    45 CArrayFixFlat<TWsCursorArrayItem> *CWsClient::iSystemPointerCursors=NULL;
       
    46 TInt CWsClient::iDefaultSystemPointerCursorIndex=0;		//Negative when there isn't one
       
    47 CWsPointerCursor *CWsClient::iDefaultSystemPointerCursor;
       
    48 CWsClient *CWsClient::iSystemPointerCursorListOwner=NULL;
       
    49 CArrayFixFlat<TWsCursorArrayItem> *CWsClient::iTextCursorArray=NULL;
       
    50 TInt CWsClient::iReply;
       
    51 TInt CWsClient::iReplyOffset;
       
    52 CWsClient *CWsClient::iCurrentClient;
       
    53 
       
    54 /**
       
    55 Used for enforcing the redraw calling convention (in preparation for BR2412) in emulator builds.
       
    56 When enabled this will panic any client calling a CWindowGc draw operation outside a 
       
    57 RWindow::BeginRedraw() / RWindow::EndRedraw() pair (known as non-redraw drawing).
       
    58 
       
    59 Enable by adding "debug_wserv_exe_EnforceRedrawCallingConvention X" to epoc.ini 
       
    60 where X is either 0 (zero) for "off" or 1 (one) for "on". 
       
    61 
       
    62 Then enable globaly in WServ AutoFlush by defining __AUTO_FLUSH in ../client/client.h 
       
    63 or locally by calling RWsSession::SetAutoFlush(ETrue) for a specific client programatically, 
       
    64 or locally pressing Ctrl-Alt-Shift-F in the emulator.
       
    65 */
       
    66 TBool CWsClient::iDebug_EnforceRedrawCallingConvention = EFalse;
       
    67 
       
    68 _LIT(KWSERVSessionPanicCategory,"WSERV");
       
    69 
       
    70 TKeyArrayFix CursorKey(_FOFF(TWsCursorArrayItem,iIndex),ECmpTInt);
       
    71 
       
    72 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_WriteDeviceData,ECapabilityWriteDeviceData);
       
    73 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_SwEvent,ECapabilitySwEvent);
       
    74 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_PowerMgmt,ECapabilityPowerMgmt);
       
    75 
       
    76 CWsClient::CWsClient(RThread aClient) : iClient(aClient), iGraphicMessageQueue(this), iIsInitialised(EFalse)
       
    77 
       
    78 #if defined(__WINS__)
       
    79 	,iRemoveKeyCode(ETrue)
       
    80 #endif
       
    81 	{
       
    82 	iScreen=CWsTop::Screen();		//## Need to find better way to set this
       
    83 	}
       
    84 
       
    85 CWsClient::~CWsClient()
       
    86 	{
       
    87 	WindowServer().RemoveAllGraphicDrawers(*this); // deindexes all graphic drawers owned by this client
       
    88 
       
    89 	delete iTempCustomTextCursor.iCursor;
       
    90 	FreeSystemPointerCursorList();
       
    91 	CWsTop::ClientDestroyed(this);
       
    92 	if (wsDebugLog)
       
    93 		{
       
    94 		_LIT(ClientDestuct,"Client %d destructing");
       
    95 		wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,ClientDestuct, iConnectionHandle);
       
    96 		}
       
    97 	iInternalFlags|=EClientIsClosing;
       
    98 	delete iObjectIndex;
       
    99 	delete iEventQueue;
       
   100 	delete iRedrawQueue;
       
   101 	delete iPriorityKeyEvent;
       
   102 
       
   103 	CWsTop::SessionExited(this);
       
   104 	iScreen->Update();	/*	Mathias: Don't care about multiple screens yet
       
   105 	CWsTop::UpdateAllScreens(EFalse);
       
   106 */
       
   107 	iClient.Close();
       
   108 	}
       
   109 
       
   110 void CWsClient::CompleteInitializationL()
       
   111 	{
       
   112 	iObjectIndex=new(ELeave) CWsObjectIx();
       
   113 	iObjectIndex->ConstructL();
       
   114     iEventQueue=new(ELeave) CEventQueue(this);
       
   115 	iEventQueue->ConstructL();
       
   116     iRedrawQueue=new(ELeave) CRedrawQueue(this);
       
   117 	iRedrawQueue->ConstructL();
       
   118     iPriorityKeyEvent=new(ELeave) CPriorityKey(this);
       
   119 	CWsCliObj::NewL(this);
       
   120 	iComputeMode=RWsSession::EPriorityControlComputeOff;
       
   121 	CWsTop::NewSession(this);
       
   122 
       
   123 #ifdef __WINS__
       
   124 	TBool halValue = EFalse;
       
   125 	if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, 
       
   126 		(TAny*)"debug_wserv_exe_EnforceRedrawCallingConvention", &halValue) == KErrNone)
       
   127 		{
       
   128 		iDebug_EnforceRedrawCallingConvention = halValue;
       
   129 		}
       
   130 #endif
       
   131 
       
   132 	iIsInitialised = ETrue;
       
   133 	}
       
   134 
       
   135 TBool CWsClient::DebugEnforceRedrawCallingConvention()
       
   136 	{
       
   137 	return iDebug_EnforceRedrawCallingConvention;
       
   138 	}
       
   139 
       
   140 void CWsClient::StartInitializationL(TUint aConnectionHandle)
       
   141 	{
       
   142 	if (wsDebugLog)
       
   143 		wsDebugLog->NewClient(aConnectionHandle);
       
   144 	if (iObjectIndex)
       
   145 		{
       
   146 		PPanic(EWservPanicReInitialise);
       
   147 		}
       
   148 	else
       
   149 		{
       
   150 		iConnectionHandle=aConnectionHandle;
       
   151 		CompleteInitializationL();
       
   152 		}
       
   153 	}
       
   154 
       
   155 void CWsClient::HandleToWindow(TInt handle,CWsWindowBase **pWin)
       
   156 //
       
   157 // Convert a handle to object checking it is of the correct type.
       
   158 //
       
   159 	{
       
   160 	if ((*pWin=(CWsWindowBase *)HandleToObjUntyped(handle))==NULL ||
       
   161 		((*pWin)->Type()!=WS_HANDLE_WINDOW && (*pWin)->Type()!=WS_HANDLE_GROUP_WINDOW))
       
   162 		PPanic(EWservPanicWindow);
       
   163 	}
       
   164 
       
   165 void CWsClient::HandleToClientWindow(TInt handle,CWsClientWindow **pWin)
       
   166 //
       
   167 // Convert a handle to object checking it is of the correct type.
       
   168 //
       
   169 	{
       
   170 	if ((*pWin=(CWsClientWindow *)HandleToObj(handle, WS_HANDLE_WINDOW))==NULL)
       
   171 		PPanic(EWservPanicWindow);
       
   172 	}
       
   173 
       
   174 void CWsClient::CreateNewPointerCursorL(const TWsClCmdCreatePointerCursor &aCmd)
       
   175 	{
       
   176 	CWsPointerCursor *pc=new(ELeave) CWsPointerCursor(this);
       
   177 	CleanupStack::PushL(pc);
       
   178 	pc->ConstructL(aCmd);
       
   179 	CleanupStack::Pop();
       
   180 	}
       
   181 
       
   182 // Create a new custom text cursor
       
   183 void CWsClient::StartSetCustomTextCursorL(const TWsClCmdCustomTextCursorData& aCmd)
       
   184 	{
       
   185 	if (!iTextCursorArray)
       
   186 		{
       
   187 		const TInt textCursorArrayGranularity = 4;
       
   188 		iTextCursorArray = new(ELeave) CArrayFixFlat<TWsCursorArrayItem>(textCursorArrayGranularity);
       
   189 		}
       
   190 	TInt arrayIndex;
       
   191 	if (FindCursorArrayItem(iTextCursorArray, aCmd.identifier, arrayIndex))
       
   192 		User::Leave(KErrAlreadyExists);
       
   193 	delete iTempCustomTextCursor.iCursor;
       
   194 	iTempCustomTextCursor.iCursor = NULL;
       
   195 	iTempCustomTextCursor.iCursor = new(ELeave) CWsCustomTextCursor(this, aCmd.alignment);
       
   196 	static_cast<CWsCustomTextCursor*>(iTempCustomTextCursor.iCursor)->ConstructL(aCmd.flags);
       
   197 	iTempCustomTextCursor.iIndex = aCmd.identifier;
       
   198 	}
       
   199 
       
   200 // Add new custom text cursor to global list
       
   201 void CWsClient::CompleteSetCustomTextCursorL(TInt aError)
       
   202 	{
       
   203 	if (aError != KErrNone)
       
   204 		{
       
   205 		delete iTempCustomTextCursor.iCursor;
       
   206 		iTempCustomTextCursor.iCursor = NULL;
       
   207 		User::Leave(aError);
       
   208 		}
       
   209 
       
   210 	TWsCursorArrayItem entry = iTempCustomTextCursor;
       
   211 	iTempCustomTextCursor.iCursor = NULL;
       
   212 	CleanupStack::PushL(entry.iCursor);
       
   213 
       
   214 	TInt arrayIndex;
       
   215 	if (FindCursorArrayItem(iTextCursorArray, entry.iIndex, arrayIndex))
       
   216 		{
       
   217 		User::Leave(KErrAlreadyExists);
       
   218 		}
       
   219 	else
       
   220 		{
       
   221 		iTextCursorArray->InsertIsqL(entry, CursorKey);
       
   222 		}
       
   223 
       
   224 	CleanupStack::Pop(entry.iCursor);
       
   225 	}
       
   226 
       
   227 CWsCustomTextCursor* CWsClient::FindCustomTextCursor(TInt aIdentifier)
       
   228 	{
       
   229 	TInt arrayIndex;
       
   230 	if (!FindCursorArrayItem(iTextCursorArray, aIdentifier, arrayIndex))
       
   231 		{
       
   232 		return NULL;
       
   233 		}
       
   234 	return TextCursor(arrayIndex);
       
   235 	}
       
   236 
       
   237 void CWsClient::CreateNewSpriteL(const TWsClCmdCreateSprite &aCmd)
       
   238 	{
       
   239 	CWsSprite *sprite=new(ELeave) CWsSprite(this);
       
   240 	CleanupStack::PushL(sprite);
       
   241 	sprite->ConstructL(aCmd);
       
   242 	CleanupStack::Pop();
       
   243 	}
       
   244 
       
   245 void CWsClient::CreateNewBitmapL(const TWsClCmdCreateBitmap &aCmd)
       
   246 	{
       
   247 	DWsBitmap *bitmap=new(ELeave) DWsBitmap(this);
       
   248 	CleanupStack::PushL(bitmap);
       
   249 	bitmap->ConstructL(aCmd);
       
   250 	CleanupStack::Pop();
       
   251 	}
       
   252 
       
   253 /** Creates a new window.
       
   254 
       
   255 @param aCmd The command received from the client
       
   256 @internalComponent
       
   257 @released
       
   258 */
       
   259 void CWsClient::CreateNewWindowL(const TWsClCmdCreateWindow &aCmd)
       
   260 	{
       
   261 	CWsWindowBase *parent;
       
   262 	HandleToWindow(aCmd.parent,&parent);
       
   263 	CWsClientWindow *win=NULL;
       
   264 	TBool deviceIsInvalid=EFalse;
       
   265 	CScreen* screen = parent->Screen();
       
   266 
       
   267 	if (parent->WinType()==EWinTypeGroup)
       
   268 		{
       
   269 		__ASSERT_DEBUG(!((CWsWindowGroup*)parent)->ScreenDeviceDeleted(),PPanic(EWservPanicGroupWinScreenDeviceDeleted));
       
   270 		win=new(ELeave) CWsClientWindow(this, screen);
       
   271 		deviceIsInvalid=!((CWsWindowGroup *)parent)->ScreenDeviceValid();
       
   272 		}
       
   273 	else
       
   274 		{
       
   275 		win=new(ELeave) CWsClientWindow(this, screen);
       
   276 		}
       
   277 	CleanupStack::PushL(win);
       
   278 	win->ConstructL(aCmd,parent,deviceIsInvalid);
       
   279 	CleanupStack::Pop(win);
       
   280 	}
       
   281 
       
   282 void CWsClient::CreateNewWindowGroupL(const TWsClCmdCreateWindowGroup &aCmd)
       
   283 	{
       
   284 	CWsWindowGroup::NewL(this, NULL, aCmd); //Screen is set inside the ConstructL since support for multiple screens was introduced
       
   285 	}
       
   286 
       
   287 void CWsClient::CreateNewAnimDllL(const TWsClCmdUnion &aParams)
       
   288 	{
       
   289 	CWsAnimDll *animDll=new(ELeave) CWsAnimDll(this);
       
   290 	CleanupStack::PushL(animDll);
       
   291 	animDll->LoadL(BufferTPtr((TText *)(aParams.LoadAnimDll+1),aParams.LoadAnimDll->length));
       
   292 	CleanupStack::Pop();
       
   293 	}	
       
   294 
       
   295 void CWsClient::CreateNewScreenDeviceL( TInt aDefaultScreenNumber, TUint aClientScreenDevicePointer)
       
   296 	{
       
   297 	DWsScreenDevice *screenDevice=new(ELeave) DWsScreenDevice( this, aDefaultScreenNumber,aClientScreenDevicePointer);
       
   298 	CleanupStack::PushL(screenDevice);
       
   299 	screenDevice->ConstructL();
       
   300 	CleanupStack::Pop(screenDevice);
       
   301 	if (iPrimaryScreenDevice==NULL)
       
   302 		{
       
   303 		iPrimaryScreenDevice=screenDevice;
       
   304 		// When client create screen device, change default screen to the one specified.
       
   305 		// Client should do this immediately after establishing session
       
   306 		iScreen = iPrimaryScreenDevice->Screen();
       
   307 		InitialiseScreenDevices();
       
   308 		}
       
   309 	}
       
   310 
       
   311 void CWsClient::InitialiseScreenDevices()
       
   312 	{
       
   313 	const TWsObject* ptr=iObjectIndex->FirstObject();
       
   314 	const TWsObject* end=ptr+iObjectIndex->Length();
       
   315 	WS_ASSERT_DEBUG(ptr->iObject==NULL, EWsPanicObjectIndexError);
       
   316 	while(++ptr<end)
       
   317 		{
       
   318 		if (ptr->iObject && ptr->iObject->Type()==WS_HANDLE_GROUP_WINDOW)
       
   319 			{
       
   320 			CWsWindowGroup *gw =STATIC_CAST(CWsWindowGroup*,ptr->iObject);
       
   321 			if(gw->Device()==NULL)
       
   322 				{
       
   323 				gw->SetScreenDevice(iPrimaryScreenDevice);
       
   324 				}
       
   325 			}
       
   326 		}
       
   327 	}
       
   328 
       
   329 void CWsClient::CreateNewClickL(const TUid& aUid)
       
   330 	{
       
   331 	CClick *click=new(ELeave) CClick(this);
       
   332 	CleanupStack::PushL(click);
       
   333 	click->ConstructL(aUid);
       
   334 	CleanupStack::Pop(click);
       
   335 	}
       
   336 
       
   337 void CWsClient::RequestComplete(TRequestStatus * &aStatus, TInt aErr)
       
   338 	{
       
   339 	Client().RequestComplete(aStatus,aErr);
       
   340 	}
       
   341 
       
   342 void CWsClient::PanicCurrentClient(TClientPanic aPanic)
       
   343 	{
       
   344 	iCurrentClient->PPanic(aPanic);
       
   345 	}
       
   346 
       
   347 void CWsClient::PPanic(TClientPanic aPanic) const
       
   348 //This function is allowed to leave with out the 'L' convention for special reasons
       
   349 	{
       
   350 	SessionPanic(aPanic);
       
   351 	User::Leave(EPanicLeave);
       
   352 	}
       
   353 
       
   354 void CWsClient::SessionPanic(TClientPanic aReason) const
       
   355 	{
       
   356 	if (wsDebugLog)
       
   357 		wsDebugLog->Panic(iConnectionHandle, aReason);
       
   358 	if (!iInternalFlags&EPanicClientAsSoonAsPossible) // keep the first error code
       
   359 		{
       
   360 		iInternalFlags|=EPanicClientAsSoonAsPossible;
       
   361 		iPanicReason=aReason;
       
   362 		}
       
   363 	}
       
   364 
       
   365 void CWsClient::SessionTerminate()
       
   366 	{
       
   367 	if (wsDebugLog)
       
   368 		wsDebugLog->Panic(iConnectionHandle, 0);
       
   369 
       
   370 	const RThread thread=Client();
       
   371 	RProcess process;
       
   372 	if (thread.Process(process)==KErrNone)
       
   373 		{
       
   374 		process.Terminate(0);
       
   375 		process.Close();
       
   376 		}
       
   377 	}
       
   378 
       
   379 void CWsClient::ReplyBuf(const TDesC16 &aDes)
       
   380 	{
       
   381 	WS_ASSERT_DEBUG(!iCurrentClient->ClientMessage().IsNull(), EWsPanicInvalidMessageHandle);
       
   382 	if(iCurrentClient->ClientMessage().Write(KReplyBufferMessageSlot,aDes,iReplyOffset) != KErrNone)
       
   383 		PanicCurrentClient(EWservPanicDescriptor);
       
   384 	iReplyOffset+=aDes.Length();
       
   385 	if (wsDebugLog)
       
   386 		wsDebugLog->ReplyBuf(aDes);
       
   387 	}
       
   388 
       
   389 void CWsClient::ReplyBuf(const TDesC8 &aDes)
       
   390 	{
       
   391 	WS_ASSERT_DEBUG(!iCurrentClient->ClientMessage().IsNull(), EWsPanicInvalidMessageHandle);
       
   392 	if(iCurrentClient->ClientMessage().Write(KReplyBufferMessageSlot,aDes,iReplyOffset) != KErrNone)
       
   393 		PanicCurrentClient(EWservPanicDescriptor);
       
   394 	iReplyOffset+=aDes.Length();
       
   395 	if (wsDebugLog)
       
   396 		wsDebugLog->ReplyBuf(aDes);
       
   397 	}
       
   398 
       
   399 void CWsClient::ReplyBuf(const TAny *aSource, TInt aLength)
       
   400 //
       
   401 // Send a buffer to the client process.
       
   402 //
       
   403 	{
       
   404 	TPtrC8 src(reinterpret_cast<const TUint8*>(aSource),aLength);
       
   405 	ReplyBuf(src);
       
   406 	}
       
   407 
       
   408 void CWsClient::ReplySize(const TSize &aSize)
       
   409 	{
       
   410 	ReplyBuf(&aSize,sizeof(aSize));
       
   411 	}
       
   412 
       
   413 void CWsClient::ReplyPoint(const TPoint &aPoint)
       
   414 	{
       
   415 	ReplyBuf(&aPoint,sizeof(aPoint));
       
   416 	}
       
   417 
       
   418 void CWsClient::ReplyRect(const TRect &aRect)
       
   419 	{
       
   420 	ReplyBuf(&aRect,sizeof(aRect));
       
   421 	}
       
   422 
       
   423 void CWsClient::SetReply(TInt reply)
       
   424 	{
       
   425 	iReply=reply;
       
   426 	if (wsDebugLog)
       
   427 		wsDebugLog->Reply(reply);
       
   428 	}
       
   429 
       
   430 const TUint8 *CWsClient::EndOfCommandBuffer()
       
   431 	{
       
   432 	return(iCmdBuf.Ptr()+iCmdBuf.Size());
       
   433 	}
       
   434 
       
   435 const TPtrC CWsClient::BufferTPtr(TText *aStart,TInt aLen)
       
   436 	{
       
   437 	TPtrC ptr;
       
   438 	if (!BufferTPtrGc(aStart,aLen,ptr))
       
   439 		PanicCurrentClient(EWservPanicBufferPtr);
       
   440 	return(ptr);
       
   441 	}
       
   442 
       
   443 TBool CWsClient::BufferTPtrGc(TText* aStart,TInt aLen, TPtrC& aPtr)
       
   444 	{
       
   445 	if (iCurrentCommand.iOpcode>0)
       
   446 		{
       
   447 		if ((REINTERPRET_CAST(TUint8*,aStart)<iCmdBuf.Ptr()
       
   448 										|| REINTERPRET_CAST(TUint8*,aStart+aLen)>(iCmdBuf.Ptr()+iCmdBuf.Size())))
       
   449 			return(EFalse);
       
   450 		}
       
   451 	else
       
   452 		{
       
   453 		if (aLen>=iCurrentCommand.iCmdLength)
       
   454 			return(EFalse);
       
   455 		}
       
   456 	aPtr.Set(aStart,aLen);
       
   457 	return(ETrue);
       
   458 	}
       
   459 
       
   460 const TPtrC8 CWsClient::BufferTPtr8(TUint8* aStart,TInt aLen)
       
   461 	{
       
   462 	if (iCurrentCommand.iOpcode>0 && (REINTERPRET_CAST(TUint8*,aStart)<iCmdBuf.Ptr()
       
   463 										|| REINTERPRET_CAST(TUint8*,aStart+aLen)>(iCmdBuf.Ptr()+iCmdBuf.Size())))
       
   464 		PanicCurrentClient(EWservPanicBufferPtr);
       
   465 	return(TPtrC8(aStart,aLen));
       
   466 	}
       
   467 
       
   468 /**
       
   469 Process a command buffer
       
   470 
       
   471 @internalComponent
       
   472 @released
       
   473 */
       
   474 void CWsClient::CommandBufL()
       
   475 	{
       
   476 	if (wsDebugLog)
       
   477 		{
       
   478 		wsDebugLog->CommandBuf(iConnectionHandle);
       
   479 		RThread client = Client(); 
       
   480 		wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything, client.FullName());
       
   481 		}
       
   482 	iReplyOffset=0;
       
   483 	iCurrentClient=this;
       
   484 	CWsObject *destObj=NULL;
       
   485 	const TUint8 *nextCmd=iCmdBuf.Ptr();
       
   486 	const TUint8 *endCmd=nextCmd+iCmdBuf.Length();
       
   487 
       
   488 	do
       
   489 		{
       
   490 		const TWsCmdHeader *pCmd=(TWsCmdHeader *)nextCmd;
       
   491 		TUint opcode=pCmd->iBase.iOpcode;
       
   492 		TInt headerLen=sizeof(pCmd->iBase);
       
   493 		iCurrentCommand=pCmd->iBase;
       
   494 		
       
   495 		// For performance reasons the handle is only included
       
   496 		// if it is different from the previous command. The EWsOpcodeHandle
       
   497 		// flag indicates whether a new handle has been included in the
       
   498 		// current command. If not we use the same handle as the previous
       
   499 		// command.
       
   500 		if (opcode&EWsOpcodeHandle)
       
   501 			{
       
   502 			opcode&=~EWsOpcodeHandle;
       
   503 			iCurrentCommand.iOpcode=reinterpret_cast<TUint16&>(opcode);
       
   504 			destObj=HandleToObjUntyped(pCmd->iDestHandle);
       
   505 			headerLen=sizeof(*pCmd);
       
   506 			}
       
   507 		nextCmd+=headerLen;
       
   508 		const TAny *cmdParams=nextCmd;
       
   509 		nextCmd+=pCmd->iBase.iCmdLength;
       
   510 		if (destObj==NULL || nextCmd>endCmd)		// Invalid handle or Corrupt buffer
       
   511 			{
       
   512 			SessionPanic(destObj==NULL ? EWservPanicHandle : EWservPanicBuffer);
       
   513 			break;
       
   514 			}
       
   515 	#if defined(_DEBUG)
       
   516 		iLastCommand=(nextCmd==endCmd);
       
   517 	#endif
       
   518 		// Storing destObj->Type() to a temporary variable objType allows the value of destObj->Type()
       
   519 		// to be used if destObj is deleted during destObj->CommandL().
       
   520   	  	WH_HANDLES objType=destObj->Type(); 
       
   521 		if (wsDebugLog)
       
   522 			wsDebugLog->Command(objType, opcode, cmdParams, destObj->LogHandle());
       
   523 		destObj->CommandL(opcode, cmdParams);
       
   524 
       
   525 		} while(nextCmd<endCmd);
       
   526 
       
   527 #if defined(_DEBUG)
       
   528 	User::Heap().Check();
       
   529 #endif
       
   530 	}
       
   531 
       
   532 void CWsClient::CommandL(TInt aOpcode, const RMessage2& aMessage)
       
   533 	{
       
   534 	switch(aOpcode)
       
   535 		{
       
   536 		case EWsClOpEventReady:
       
   537 			EventReady(aMessage);
       
   538 			break;
       
   539 		case EWsClOpPriorityKeyReady:
       
   540 			PriorityKeyEventReady(aMessage);
       
   541 			break;
       
   542 		case EWsClOpRedrawReady:
       
   543 			RedrawEventReady(aMessage);
       
   544 			break;
       
   545 		case EWsClOpGraphicMessageReady:
       
   546 			iGraphicMessageQueue.EventReady(aMessage);
       
   547 			break;
       
   548 		default:
       
   549 			{
       
   550 			PPanic(EWservPanicOpcode);
       
   551 			break;
       
   552 			}
       
   553 		}
       
   554 	}
       
   555 
       
   556 void CWsClient::CommandL(TInt aOpcode, const TAny *aCmdData)
       
   557 	{
       
   558 	TWsClCmdUnion pData;
       
   559 	pData.any=aCmdData;
       
   560 	switch(aOpcode)
       
   561 		{
       
   562 		case EWsClOpCreateWindowGroup:
       
   563 			CreateNewWindowGroupL(*pData.CreateWindowGroup);
       
   564 			break;
       
   565 		case EWsClOpCreateWindow:
       
   566 			CreateNewWindowL(*pData.CreateWindow);
       
   567 			break;
       
   568 		case EWsClOpCreateGc:
       
   569 			CWsGc::NewL(this);
       
   570 			break;
       
   571 		case EWsClOpCreateAnimDll:
       
   572 			if (!CheckBuffer(pData.LoadAnimDll->length, KMaxFileName))
       
   573 				PanicCurrentClient(EWservPanicBufferPtr);
       
   574 			CreateNewAnimDllL(pData);
       
   575 			break;
       
   576 		case EWsClOpCreateGraphic:
       
   577 			CWsGraphicDrawerObject::NewL(this,pData);
       
   578 			break;
       
   579 		case EWsClOpCreateScreenDevice:
       
   580 			{
       
   581 			TInt screenNumber = pData.CreateScreenDevice->screenNumber;
       
   582 			TUint clientScreenDevicePointer = pData.CreateScreenDevice->clientScreenDevicePointer;
       
   583 			if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
   584 				{
       
   585 				PPanic(EWservPanicScreenNumber);
       
   586 				}
       
   587 			else
       
   588 				{
       
   589 				CreateNewScreenDeviceL(screenNumber,clientScreenDevicePointer);
       
   590 				}
       
   591 			}
       
   592 			break;
       
   593 		case EWsClOpCreateSprite:
       
   594 			CreateNewSpriteL(*pData.CreateSprite);
       
   595 			break;
       
   596 		case EWsClOpCreatePointerCursor:
       
   597 			CreateNewPointerCursorL(*pData.CreatePointerCursor);
       
   598 			break;
       
   599 		case EWsClOpStartSetCustomTextCursor:
       
   600 			StartSetCustomTextCursorL(*pData.CustomTextCursorData);
       
   601 			break;
       
   602 		case EWsClOpCompleteSetCustomTextCursor:
       
   603 			CompleteSetCustomTextCursorL(*pData.Int);
       
   604 			break;
       
   605 		case EWsClOpCreateBitmap:
       
   606 			CreateNewBitmapL(*pData.CreateBitmap);
       
   607 			break;
       
   608 		case EWsClOpCreateDirectScreenAccess:
       
   609 			CWsDirectScreenAccess::NewL(this);
       
   610 			break;
       
   611 		case EWsClOpCreateClick:
       
   612 			CreateNewClickL(*pData.Uid);
       
   613 			break;
       
   614 		case EWsClOpSetHotKey:
       
   615 			{
       
   616 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetHotKey API")))
       
   617 				{
       
   618 				User::Leave(KErrPermissionDenied);
       
   619 				}
       
   620 			TWindowServerEvent::SetHotKeyL(*pData.SetHotKey);
       
   621 			}
       
   622 			break;
       
   623 		case EWsClOpClearHotKeys:
       
   624 			{
       
   625 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::ClearHotKeys API")))
       
   626 				{
       
   627 				User::Leave(KErrPermissionDenied);
       
   628 				}
       
   629 			TWindowServerEvent::ClearHotKeysL(*pData.UInt);
       
   630 			}
       
   631 			break;
       
   632 		case EWsClOpRestoreDefaultHotKey:
       
   633 			TWindowServerEvent::ResetDefaultHotKeyL(*pData.UInt);
       
   634 			break;
       
   635 		case EWsClOpSetShadowVector:
       
   636 			{
       
   637 			for(TInt i=0;i<CWsTop::NumberOfScreens();i++)
       
   638 				{
       
   639 				CScreen *screen = CWsTop::Screen(i);
       
   640 				screen->SetShadowVector(*pData.Point);
       
   641 				}
       
   642 			}
       
   643 			break;
       
   644 		case EWsClOpShadowVector:
       
   645 			{
       
   646 			TPoint vector(iScreen->ShadowVector());
       
   647 			ReplyBuf(&vector,sizeof(TPoint));
       
   648 			}
       
   649 			break;
       
   650 		case EWsClOpSetKeyboardRepeatRate:
       
   651 			{
       
   652 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetKeyboardRepeatRate API")))
       
   653 				{
       
   654 				User::Leave(KErrPermissionDenied);
       
   655 				}
       
   656 			if ((pData.SetKeyboardRepeatRate->initial.Int()<0) || (pData.SetKeyboardRepeatRate->time.Int()<0))
       
   657 				{
       
   658 				User::Leave(KErrArgument);
       
   659 				}
       
   660 			CKeyboardRepeat::SetRepeatTime(pData.SetKeyboardRepeatRate->initial,pData.SetKeyboardRepeatRate->time);
       
   661 			}
       
   662 			break;
       
   663 		case EWsClOpGetKeyboardRepeatRate:
       
   664 			{
       
   665 			SKeyRepeatSettings settings;
       
   666 			CKeyboardRepeat::GetRepeatTime(settings.iInitialTime,settings.iTime);
       
   667 			ReplyBuf(&settings,sizeof(settings));
       
   668 			}
       
   669 			break;
       
   670 		case EWsClOpSetDoubleClick:
       
   671 			{
       
   672 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetDoubleClick API")))
       
   673 				{
       
   674 				User::Leave(KErrPermissionDenied);
       
   675 				}
       
   676 			WsPointer::SetDoubleClick(pData.SetDoubleClick->interval,pData.SetDoubleClick->distance);
       
   677 			}
       
   678 			break;
       
   679 		case EWsClOpGetDoubleClickSettings:
       
   680 			{
       
   681 			SDoubleClickSettings settings;
       
   682 			WsPointer::GetDoubleClickSettings(settings.iInterval,settings.iDistance);
       
   683 			ReplyBuf(&settings,sizeof(settings));
       
   684 			}
       
   685 			break;
       
   686 		case EWsClOpEventReady:
       
   687 			break;
       
   688 		case EWsClOpGetEvent:
       
   689 			GetEventData();
       
   690 			break;
       
   691 		case EWsClOpPurgePointerEvents:
       
   692 			PurgePointerEvents();
       
   693 			break;
       
   694 		case EWsClOpEventReadyCancel:
       
   695 			CancelEvent();
       
   696 			break;
       
   697 		case EWsClOpRedrawReady:
       
   698 			break;
       
   699 		case EWsClOpRedrawReadyCancel:
       
   700 			CancelRedrawEvent();
       
   701 			break;
       
   702 		case EWsClOpGetRedraw:
       
   703 			GetRedrawData();
       
   704 			break;
       
   705 		case EWsClOpPriorityKeyReady:
       
   706 			break;
       
   707 		case EWsClOpPriorityKeyReadyCancel:
       
   708 			CancelPriorityKeyEvent();
       
   709 			break;
       
   710 		case EWsClOpGetPriorityKey:
       
   711 			GetPriorityKeyData();
       
   712 			break;
       
   713 		case EWsClOpNumWindowGroups:
       
   714 			SetReply(CWsWindowGroup::NumWindowGroups(EFalse, *pData.Int));
       
   715 			break;
       
   716 		case EWsClOpNumWindowGroupsAllPriorities:
       
   717 			SetReply(CWsWindowGroup::NumWindowGroups(ETrue, 0));
       
   718 			break;
       
   719 		case EWsClOpNumWindowGroupsOnScreen:
       
   720 			{
       
   721 			TInt screenNumber=pData.NumWinGroups->screenNumber;
       
   722 			if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
   723 				{
       
   724 				PPanic(EWservPanicScreenNumber);
       
   725 				}
       
   726 			else
       
   727 				{
       
   728 				SetReply(CWsWindowGroup::NumWindowGroupsOnScreen(CWsTop::Screen(screenNumber)->RootWindow()->Child(),(pData.NumWinGroups->priority==EAllPriorities),pData.NumWinGroups->priority));
       
   729 				}
       
   730 			}
       
   731 			break;
       
   732 		case EWsClOpWindowGroupList:
       
   733 			{
       
   734 			TInt screenNumber=pData.WindowGroupList->screenNumber;
       
   735 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   736 				{
       
   737 				PPanic(EWservPanicScreenNumber);
       
   738 				}
       
   739 			else
       
   740 				{
       
   741 				SetReply(CWsWindowGroup::SendWindowGroupListL(screenNumber,(pData.WindowGroupList->priority==EAllPriorities), pData.WindowGroupList->priority, pData.WindowGroupList->count));
       
   742 				}
       
   743 			}
       
   744 			break;
       
   745 		case EWsClOpWindowGroupListAllPriorities:
       
   746 			{
       
   747 			TInt screenNumber=pData.WindowGroupList->screenNumber;
       
   748 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   749 				{
       
   750 				PPanic(EWservPanicScreenNumber);
       
   751 				}
       
   752 			else
       
   753 				{
       
   754 				SetReply(CWsWindowGroup::SendWindowGroupListL(screenNumber,ETrue, 0, pData.WindowGroupList->count));
       
   755 				}
       
   756 			}
       
   757 			break;
       
   758 		case EWsClOpWindowGroupListAndChain:
       
   759 			SetReply(CWsWindowGroup::SendWindowGroupListAndChainL(EFalse, pData.WindowGroupList->priority, pData.WindowGroupList->count));
       
   760 			break;
       
   761 		case EWsClOpWindowGroupListAndChainAllPriorities:
       
   762 			SetReply(CWsWindowGroup::SendWindowGroupListAndChainL(ETrue, 0, pData.WindowGroupList->count));
       
   763 			break;
       
   764 		case EWsClOpGetDefaultOwningWindow:
       
   765 			{
       
   766 			TInt screenNumber = *pData.Int;
       
   767 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   768 				{
       
   769 				PPanic(EWservPanicScreenNumber);
       
   770 				}
       
   771 			else
       
   772 				{
       
   773 				CScreen* screen = (screenNumber ==KDummyScreenNumber) ? iScreen : CWsTop::Screen(screenNumber);
       
   774 				SetReply(screen->DefaultOwningWindowGroup() ? screen->DefaultOwningWindowGroup()->Identifier():0);
       
   775 				}
       
   776 			}
       
   777 			break;
       
   778 		case EWsClOpGetFocusWindowGroup:
       
   779 			{
       
   780 			TInt screenNumber = *pData.Int;
       
   781 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   782 				{
       
   783 				PPanic(EWservPanicScreenNumber);
       
   784 				}
       
   785 			else
       
   786 				{
       
   787 				CWsWindowGroup::GetFocusWindowGroupL(screenNumber);
       
   788 				}
       
   789 			}
       
   790 			break;
       
   791 		case EWsClOpSetWindowGroupOrdinalPosition:
       
   792 			CWsWindowGroup::WindowGroupFromIdentifierL(pData.SetWindowGroupOrdinalPosition->identifier)->SetOrdinalPosition(pData.SetWindowGroupOrdinalPosition->position);
       
   793 			break;
       
   794 		case EWsClOpGetWindowGroupHandle:
       
   795 			SetReply(CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->ClientHandle());
       
   796 			break;
       
   797 		case EWsClOpGetWindowGroupOrdinalPriority:
       
   798 			SetReply(CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->OrdinalPriority());
       
   799 			break;
       
   800 		case EWsClOpGetWindowGroupClientThreadId:
       
   801 			{
       
   802 			TThreadId id=CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->WsOwner()->Client().Id();
       
   803 			ReplyBuf(&id,sizeof(id));
       
   804 			}
       
   805 			break;
       
   806 		case EWsClOpSendEventToWindowGroup:
       
   807 			{
       
   808 			CWsWindowGroup *group=CWsWindowGroup::WindowGroupFromIdentifierL(pData.SendEventToWindowGroup->parameter);
       
   809 			TWsEvent event=pData.SendEventToWindowGroup->event;
       
   810 			event.SetHandle(group->ClientHandle());
       
   811 			// Events in enum TEventCode is protected by capabilities
       
   812 			if (group->WsOwner()!=this && event.Type()>=EEventNull && event.Type()<EEventUser)
       
   813 				{
       
   814 				if (event.Type()<EEventPowerMgmt || event.Type()>=EEventReserved)
       
   815 					{
       
   816 					if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToWindowGroup API")))
       
   817 						User::Leave(KErrPermissionDenied);
       
   818 					}
       
   819 				else
       
   820 					{
       
   821 					if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToWindowGroup API")))
       
   822 						User::Leave(KErrPermissionDenied);
       
   823 					}
       
   824 				}
       
   825 			if (event.Type()==EEventKey && event.Key()->iRepeats!=0)
       
   826 				CKeyboardRepeat::CancelRepeat(NULL);		//Otherwise we will trip an invarient
       
   827 			if (!group->EventQueue()->QueueEvent(event))
       
   828 				User::Leave(KErrNoMemory);
       
   829 			}
       
   830 			break;
       
   831 		case EWsClOpSendEventToAllWindowGroup:
       
   832 		case EWsClOpSendEventToAllWindowGroupPriority:
       
   833 		case EWsClOpSendEventToOneWindowGroupPerClient:
       
   834 			{
       
   835 			TWsEvent event=pData.SendEventToWindowGroup->event;
       
   836 			if (event.Type()<0)
       
   837 				{
       
   838 				User::Leave(KErrArgument);
       
   839 				}
       
   840 			if(event.Type()<EEventUser)
       
   841 				{
       
   842 				if (event.Type()<EEventPowerMgmt || event.Type()>=EEventReserved)
       
   843 					{
       
   844 					if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToAllWindowGroup API")))
       
   845 						User::Leave(KErrPermissionDenied);
       
   846 					}
       
   847 				else 
       
   848 					{
       
   849 					if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToAllWindowGroup API")))
       
   850 						User::Leave(KErrPermissionDenied);
       
   851 					}											
       
   852 				}
       
   853 			if (!CWsWindowGroup::SendEventToAllGroups(aOpcode!=EWsClOpSendEventToAllWindowGroupPriority
       
   854 													,aOpcode==EWsClOpSendEventToOneWindowGroupPerClient,*pData.SendEventToWindowGroup))
       
   855 				User::Leave(KErrNoMemory);
       
   856 			}
       
   857 			break;
       
   858 		case EWsClOpSendMessageToWindowGroup:
       
   859 			{
       
   860 			CWsWindowGroup *group=CWsWindowGroup::WindowGroupFromIdentifierL(pData.SendMessageToWindowGroup->identifierOrPriority);
       
   861 			if (group->WsOwner()!=this)
       
   862 				{
       
   863 				if (!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendMessageToWindowGroup API")))
       
   864 					{
       
   865 					User::Leave(KErrPermissionDenied);
       
   866 					}
       
   867 				}
       
   868 			group->QueueMessageL(pData.SendMessageToWindowGroup->uid, pData.SendMessageToWindowGroup->dataLength, *this);
       
   869 			}
       
   870 			break;
       
   871 		case EWsClOpSendMessageToAllWindowGroups:
       
   872 		case EWsClOpSendMessageToAllWindowGroupsPriority:
       
   873 			{
       
   874 			if ((pData.SendMessageToWindowGroup->dataLength<0) || (pData.SendMessageToWindowGroup->dataLength>=(KMaxTInt/2)))
       
   875 				{
       
   876 				User::Leave(KErrArgument);
       
   877 				}
       
   878 			CWsWindowGroup::SendMessageToAllGroupsL(*this,aOpcode==EWsClOpSendMessageToAllWindowGroups,*pData.SendMessageToWindowGroup);
       
   879 			}
       
   880 			break;
       
   881 		case EWsClOpFetchMessage:
       
   882 			CWsWindowGroup::WindowGroupFromIdentifierL(pData.FetchMessage->windowGroupIdentifier)->FetchMessageL();
       
   883 			break;
       
   884 		case EWsClOpGetWindowGroupNameFromIdentifier:
       
   885 			ReplyGroupName(CWsWindowGroup::WindowGroupFromIdentifierL(pData.GetWindowGroupNameFromIdentifier->identifier)->GroupName(),pData.GetWindowGroupNameFromIdentifier->maxLength);
       
   886 			break;
       
   887 		case EWsClOpFindWindowGroupIdentifier:
       
   888 			{
       
   889 			if (pData.FindWindowGroupIdentifier->length<0)
       
   890 				User::Leave(KErrArgument);
       
   891 			TPtrC ptr(BufferTPtr((TText *)(pData.FindWindowGroupIdentifier+1),pData.FindWindowGroupIdentifier->length));
       
   892 			SetReply(CWsWindowGroup::FindWindowGroupL(this, pData.FindWindowGroupIdentifier->identifier,
       
   893 							pData.FindWindowGroupIdentifier->offset,&ptr,NULL)->Identifier());
       
   894 			}
       
   895 			break;
       
   896 		case EWsClOpFindWindowGroupIdentifierThread:
       
   897 			SetReply(CWsWindowGroup::FindWindowGroupL(this, pData.FindWindowGroupIdentifierThread->identifier,0,NULL,
       
   898 											&pData.FindWindowGroupIdentifierThread->threadId)->Identifier());
       
   899 			break;
       
   900 		case EWsClOpSetBackgroundColor:
       
   901 			for(TInt i=0;i<CWsTop::NumberOfScreens();i++)
       
   902 				{
       
   903 				CWsTop::Screen(i)->RootWindow()->SetColor(*pData.rgb);
       
   904 				}
       
   905 			break;
       
   906 		case EWsClOpGetBackgroundColor:
       
   907 			SetReply(iScreen->RootWindow()->BackColor().Internal());
       
   908 			break;
       
   909 		case EWsClOpClaimSystemPointerCursorList:
       
   910 			{
       
   911 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::ClaimSystemPointerCursorList API")))
       
   912 				{
       
   913 				User::Leave(KErrPermissionDenied);
       
   914 				}
       
   915 			ClaimSystemPointerCursorListL();
       
   916 			}
       
   917 			break;
       
   918 		case EWsClOpFreeSystemPointerCursorList:
       
   919 			FreeSystemPointerCursorList();
       
   920 			break;
       
   921 		case EWsClOpSetSystemPointerCursor:
       
   922 			CWsObject *pointercursor;
       
   923 			if ((pointercursor=HandleToObj(pData.SetSystemPointerCursor->handle, WS_HANDLE_POINTER_CURSOR))==NULL)
       
   924 				PPanic(EWservPanicSprite);
       
   925 			SetSystemPointerCursorL(pData.SetSystemPointerCursor->number, (CWsPointerCursor *)pointercursor);
       
   926 			break;
       
   927 		case EWsClOpClearSystemPointerCursor:
       
   928 			ClearSystemPointerCursor(*pData.Int);
       
   929 			break;
       
   930 		case EWsClOpSetPointerCursorArea:
       
   931 			{
       
   932 			if(KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorArea API")))
       
   933 				{
       
   934 				if (!iScreen->IsValidScreenSizeMode(*pData.Int))
       
   935 					PPanic(EWservPanicScreenModeNumber);
       
   936 				iScreen->SetPointerCursorArea(pData.SetPointerCursorArea->mode,pData.SetPointerCursorArea->area);
       
   937 				}
       
   938 			}
       
   939 			break;
       
   940 		case EWsClOpPointerCursorArea:
       
   941 			if (!iScreen->IsValidScreenSizeMode(*pData.Int))
       
   942 				PPanic(EWservPanicScreenModeNumber);
       
   943 			ReplyRect(iScreen->GetPointerCursorArea(*pData.Int));
       
   944 			break;
       
   945 		case EWsClOpSetPointerCursorMode:
       
   946 			{
       
   947 			CWsWindowGroup* focusWinGp=CWsTop::FocusWindowGroup();
       
   948 			if (focusWinGp && focusWinGp->WsOwner()==this)
       
   949 				{
       
   950 				WsPointer::SetPointerCursorMode(*pData.Mode);
       
   951 				WsPointer::UpdatePointerCursor();
       
   952 				}
       
   953 			}
       
   954 			break;
       
   955 		case EWsClOpSetClientCursorMode :
       
   956 			{
       
   957 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorModeIfFocused API")))
       
   958 				{
       
   959 				User::Leave(KErrPermissionDenied);
       
   960 				}
       
   961 			WsPointer::SetPointerCursorMode(*pData.Mode);
       
   962 			WsPointer::UpdatePointerCursor();
       
   963 			}
       
   964 			break;
       
   965 		case EWsClOpPointerCursorMode:
       
   966 			SetReply(WsPointer::PointerCursorMode());
       
   967 			break;
       
   968 		case EWsClOpSetDefaultSystemPointerCursor:
       
   969 			SetDefaultSystemPointerCursor(*pData.Int);
       
   970 			break;
       
   971 		case EWsClOpClearDefaultSystemPointerCursor:
       
   972 			SetDefaultSystemPointerCursor(ENoDefaultSystemPointerCursor);
       
   973 			break;
       
   974 		case EWsClOpSetPointerCursorPosition:
       
   975 			{
       
   976 			CWsWindowGroup* focusWinGp=CWsTop::FocusWindowGroup();
       
   977 			if ((!focusWinGp || focusWinGp->WsOwner()!=this)&&
       
   978 				(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorPosition API"))))
       
   979 				{
       
   980 				User::Leave(KErrPermissionDenied);
       
   981 				}
       
   982 			WsPointer::SetPointerCursorPos(*pData.Point);
       
   983 			}
       
   984 			break;
       
   985 		case EWsClOpPointerCursorPosition:
       
   986 			ReplyPoint(WsPointer::PointerCursorPos());
       
   987 			break;
       
   988 		case EWsClOpSetModifierState:
       
   989 			{
       
   990 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetModifierState API")))
       
   991 				{
       
   992 				User::Leave(KErrPermissionDenied);
       
   993 				}
       
   994 			TWindowServerEvent::SetModifierState(pData.SetModifierState->modifier,pData.SetModifierState->state);
       
   995 			}
       
   996 			break;
       
   997 		case EWsClOpGetModifierState:
       
   998 			SetReply(TWindowServerEvent::GetModifierState());
       
   999 			break;
       
  1000 		case EWsClOpHeapCount:
       
  1001 			SetReply(CWsMemoryManager::Static()->Count());
       
  1002 			break;
       
  1003  		case EWsClOpDebugInfo:
       
  1004  			DebugInfoL(pData.DebugInfo->iFunction,pData.DebugInfo->iParam,EFalse);
       
  1005  			break;
       
  1006  		case EWsClOpDebugInfoReplyBuf:
       
  1007  			DebugInfoL(pData.DebugInfo->iFunction,pData.DebugInfo->iParam,ETrue);
       
  1008  			break;
       
  1009 		case EWsClOpResourceCount:
       
  1010 			SetReply(iObjectIndex->Count());
       
  1011 			break;
       
  1012 		case EWsClOpHeapSetFail:
       
  1013 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::HeapSetFail API")))
       
  1014 				{
       
  1015 				PPanic(EWservPanicPermissionDenied);
       
  1016 				}
       
  1017 #if !defined(_DEBUG)
       
  1018 			if (pData.HeapSetFail->type!=RHeap::ENone)
       
  1019 				TWindowServerEvent::NotifyOom();
       
  1020 #endif
       
  1021 			User::__DbgSetAllocFail(RHeap::EUser,pData.HeapSetFail->type,pData.HeapSetFail->value);
       
  1022 			//__UHEAP_SETFAIL(pData.HeapSetFail->type,pData.HeapSetFail->value);
       
  1023 			break;
       
  1024 		case EWsClOpRawEvent:
       
  1025 			{
       
  1026 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SimulateRawEvent API")))
       
  1027 				{
       
  1028 				PPanic(EWservPanicPermissionDenied);
       
  1029 				}
       
  1030 			TRawEvent event(*pData.RawEvent);
       
  1031 			if (WsPointer::PreProcessEvent(event))
       
  1032 				TWindowServerEvent::ProcessRawEvent(event);
       
  1033 			}
       
  1034 			break;
       
  1035 		case EWsClOpKeyEvent:
       
  1036 			{
       
  1037 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SimulateKeyEvent API")))
       
  1038 				{
       
  1039 				PPanic(EWservPanicPermissionDenied);
       
  1040 				}
       
  1041 			TWindowServerEvent::ProcessKeyEvent(*pData.KeyEvent,0);
       
  1042 			}
       
  1043 			break;
       
  1044 		case EWsClOpLogMessage:
       
  1045 			if (wsDebugLog)
       
  1046 				{
       
  1047 				if (CheckBuffer(*pData.Int, KLogMessageLength))
       
  1048 					wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,BufferTPtr((TText *)(pData.Int+1),*pData.Int),0);
       
  1049 				}
       
  1050 			break;
       
  1051 		case EWsClOpPasswordEntered:
       
  1052 			CWsPassword::PasswordEntered(this);
       
  1053 			break;
       
  1054 		case EWsClOpComputeMode:
       
  1055 			SetComputeMode(*pData.ComputeMode);
       
  1056 			break;
       
  1057 		case EWsClOpSendOffEventsToShell:
       
  1058 			{
       
  1059 			if(!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::RequestOffEvents API")))
       
  1060 				{
       
  1061 				User::Leave(KErrPermissionDenied);
       
  1062 				}
       
  1063 			SetReply(CWsTop::SetSendOffEventsToShell(this,*pData.OffEventsToShell));
       
  1064 			}
       
  1065 			break;
       
  1066 		case EWsClOpGetDefModeMaxNumColors:
       
  1067 			{
       
  1068 			SDefModeMaxNumColors colors;
       
  1069 			TInt screenNumber = *pData.Int;
       
  1070 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
  1071 				{
       
  1072 				PPanic(EWservPanicScreenNumber);
       
  1073 				}
       
  1074 			else
       
  1075 				{
       
  1076 				CScreen* screen = (screenNumber==KDummyScreenNumber)?iScreen:CWsTop::Screen(screenNumber);
       
  1077 				screen->MaxNumColors(colors.iColors,colors.iGrays);
       
  1078 				colors.iDisplayMode=screen->FirstDefaultDisplayMode();
       
  1079 				}
       
  1080 			ReplyBuf(&colors,sizeof(colors));
       
  1081 			}
       
  1082 			break;
       
  1083 		case EWsClOpGetColorModeList:
       
  1084 			{
       
  1085 			TInt screenNumber = *pData.Int;
       
  1086 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
  1087 				{
       
  1088 				PPanic(EWservPanicScreenNumber);
       
  1089 				}
       
  1090 			else
       
  1091 				{
       
  1092 				SetReply((screenNumber==KDummyScreenNumber) ? iScreen->ColorModesFlag() : CWsTop::Screen(screenNumber)->ColorModesFlag());
       
  1093 				}
       
  1094 			}
       
  1095 			break;
       
  1096 		case EWsClOpSetDefaultFadingParams:
       
  1097 			{
       
  1098 			if(KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetDefaultFadingParameters API")))
       
  1099 				{
       
  1100 				iScreen->SetFadingParams(WservEncoding::ExtractFirst8BitValue(*pData.UInt),WservEncoding::ExtractSecond8BitValue(*pData.UInt));
       
  1101 				}
       
  1102 			}
       
  1103 			break;
       
  1104 		case EWsClOpPrepareForSwitchOff:
       
  1105 			{
       
  1106 			if(KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::PrepareForSwitchOff API")))
       
  1107 				{
       
  1108 				// Andy - this used to stop the heartbeat - should it now stop animations?
       
  1109 				}
       
  1110 			}
       
  1111 			break;
       
  1112 		case EWsClOpSetFaded:
       
  1113 			{
       
  1114 			// Deprecated - retained for BC with applications that retrieve the fade count
       
  1115 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetSystemFaded API")))
       
  1116 				{
       
  1117 				User::Leave(KErrPermissionDenied);
       
  1118 				}
       
  1119 			TUint8 blackMap;
       
  1120 			TUint8 whiteMap;
       
  1121 			if (pData.SetSystemFaded->UseDefaultMap())
       
  1122 				{
       
  1123 				iScreen->GetFadingParams(blackMap,whiteMap);
       
  1124 				}
       
  1125 			else
       
  1126 				{
       
  1127 				pData.SetSystemFaded->GetFadingParams(blackMap,whiteMap);
       
  1128 				}
       
  1129 			iScreen->RootWindow()->SetSystemFaded(pData.SetSystemFaded->Faded(),blackMap,whiteMap); 
       
  1130 			if (CWsTop::IsFadeEnabled()) 
       
  1131 				{
       
  1132 				Screen()->AcceptFadeRequest( iScreen->RootWindow(), 
       
  1133 											 pData.SetSystemFaded->Faded(), 
       
  1134 											 EFalse, 
       
  1135 											 ETrue );
       
  1136 				}
       
  1137 			}
       
  1138 		break;
       
  1139 		case EWsClOpLogCommand:
       
  1140 			CWsTop::LogCommand(*pData.LogCommand);
       
  1141 			break;
       
  1142 #if defined(__WINS__)
       
  1143 		case EWsClOpRemoveKeyCode:
       
  1144 			iRemoveKeyCode=*pData.Bool;
       
  1145 			break;
       
  1146 		case EWsClOpSimulateXyInput:
       
  1147 			WsPointer::SetXyInputType(*pData.XyInput);
       
  1148 			break;
       
  1149 #endif
       
  1150 		case EWsClOpNoFlickerFree:
       
  1151 			{
       
  1152 			// should only be used by WServ test code
       
  1153 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for EWsClOpNoFlickerFree message")))
       
  1154 				{
       
  1155 				PPanic(EWservPanicPermissionDenied);
       
  1156 				}
       
  1157 			iScreen->FreeOffScreenBitmap();
       
  1158 			break;
       
  1159 			}
       
  1160 		case EWsClOpSetFocusScreen:
       
  1161 			{
       
  1162 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetFocusScreen API")))
       
  1163 				{
       
  1164 				User::Leave(KErrPermissionDenied);
       
  1165 				}
       
  1166 			TInt focusScreen=*pData.Int;
       
  1167 			if (focusScreen>=0 && focusScreen<CWsTop::NumberOfScreens())
       
  1168 				SetReply(CWsTop::SetCurrentFocusScreen(focusScreen));
       
  1169 			else
       
  1170 				SessionPanic(EWservPanicScreenNumber);
       
  1171 			break;
       
  1172 			}
       
  1173 		case EWsClOpGetFocusScreen:
       
  1174 			SetReply(CWsTop::CurrentFocusScreen()->ScreenNumber());
       
  1175 			break;
       
  1176 		case EWsClOpGetNumberOfScreens:
       
  1177 			SetReply(CWsTop::NumberOfScreens());
       
  1178 			break;
       
  1179 		case EWsClOpClearAllRedrawStores:
       
  1180 			CWsTop::ClearAllRedrawStores();
       
  1181 			break;
       
  1182 		case EWsClOpGetGraphicMessage:
       
  1183 			iGraphicMessageQueue.GetGraphicMessage();
       
  1184 			break;
       
  1185 		case EWsClOpGraphicMessageCancel:
       
  1186 			iGraphicMessageQueue.CancelRead();
       
  1187 			break;
       
  1188 		case EWsClOpGraphicAbortMessage:
       
  1189 			iGraphicMessageQueue.AbortMessage(*pData.Int);
       
  1190 			break;
       
  1191 		case EWsClOpGraphicFetchHeaderMessage:
       
  1192 			SetReply(iGraphicMessageQueue.TopClientHandle());
       
  1193 			break;
       
  1194 		default:
       
  1195 			PPanic(EWservPanicOpcode);
       
  1196 			break;
       
  1197 		}
       
  1198 	}
       
  1199 
       
  1200 void CWsClient::DebugInfoL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const
       
  1201 	{
       
  1202 	switch(aFunction)
       
  1203 		{
       
  1204 		case EWsDebugInfoHeap:
       
  1205 			if (aHasReplyBuf)
       
  1206 				{
       
  1207 				TWsDebugHeapInfo heapInfo;
       
  1208 				RHeap& heap=User::Heap();
       
  1209 				heapInfo.iCount=heap.AllocSize(heapInfo.iTotal);
       
  1210 				heapInfo.iAvailable=heap.Available(heapInfo.iLargestAvailable);
       
  1211 				ReplyBuf(&heapInfo,sizeof(heapInfo));
       
  1212 				}
       
  1213 			SetReply(KErrArgument);
       
  1214 			break;
       
  1215 		case EWsDebugSetCheckHeapOnDisconnectClient:
       
  1216 			if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::DebugInfoL API")))
       
  1217 				{
       
  1218 				User::Leave(KErrPermissionDenied);
       
  1219 				}
       
  1220 			CWsTop::SetCheckHeapOnDisconnectClient(this);
       
  1221 			break;
       
  1222 		case EWsDebugSetCheckHeapOnDisconnectMode:
       
  1223 			if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::DebugInfoL API")))
       
  1224 				{
       
  1225 				User::Leave(KErrPermissionDenied);
       
  1226 				}
       
  1227 			CWsTop::SetCheckHeapOnDisconnectMode(STATIC_CAST(TWsCheckHeapOnDisconnectMode,aParam));
       
  1228 			break;
       
  1229 		case EWsDebugFetchCheckHeapResult:
       
  1230 			SetReply(CWsTop::FetchCheckHeapResult());
       
  1231 			break;
       
  1232 		default:
       
  1233 			SetReply(KErrNotSupported);
       
  1234 			break;
       
  1235 		}
       
  1236 	}
       
  1237 
       
  1238 void CWsClient::ReplyGroupName(HBufC *aName, TInt aMaxLength) const
       
  1239 	{
       
  1240 	if (aName)
       
  1241 		{
       
  1242 		if (aName->Length()>aMaxLength)
       
  1243 			{
       
  1244 			ReplyBuf(aName->Left(aMaxLength));
       
  1245 			SetReply(KErrOverflow);
       
  1246 			}
       
  1247 		else
       
  1248 			ReplyBuf(*aName);
       
  1249 		}
       
  1250 	else
       
  1251 		ReplyBuf(nullDescriptor);
       
  1252 	}
       
  1253 
       
  1254 void CWsClient::TriggerRedraw()
       
  1255 	{
       
  1256 	RedrawQueue()->TriggerRedraw();
       
  1257 	}
       
  1258 
       
  1259 void CWsClient::UpdateWindowOrdinalPrioritys()
       
  1260 	{
       
  1261 	for(CWsWindowGroup *win=iScreen->RootWindow()->Child();win;win=win->NextSibling())
       
  1262 		if (win->WsOwner()==this)
       
  1263 			win->UpdateOrdinalPriority(ETrue);
       
  1264 	}
       
  1265 
       
  1266 void CWsClient::DeleteSystemPointerListEntry(TInt aIndex)
       
  1267 	{
       
  1268 	PointerCursor (aIndex)->Close();
       
  1269 	iSystemPointerCursors->Delete(aIndex);
       
  1270 	}
       
  1271 
       
  1272 CWsPointerCursor *CWsClient::SystemPointerCursor(TInt aIndex)
       
  1273 	{
       
  1274 	TInt arrayIndex;
       
  1275 	if (iSystemPointerCursors)
       
  1276 		{
       
  1277 		if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1278 			{
       
  1279 			return PointerCursor (arrayIndex);
       
  1280 			}
       
  1281 		// Cursor not defined so try for default cursor
       
  1282 		if (FindCursorArrayItem(iSystemPointerCursors, 0, arrayIndex))
       
  1283 			{
       
  1284 			return PointerCursor (arrayIndex);
       
  1285 			}
       
  1286 		}
       
  1287 	// If that fails simply return NULL for no cursor
       
  1288 	return(NULL);
       
  1289 	}
       
  1290 
       
  1291 void CWsClient::SetSystemPointerCursorL(TInt aIndex, CWsPointerCursor *aCursor)
       
  1292 	{
       
  1293 	if (iSystemPointerCursorListOwner!=this)
       
  1294 		PPanic(EWservPanicNotSystemPointerCursorListOwner);
       
  1295 	TInt arrayIndex;
       
  1296 	if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1297 		{
       
  1298 		PointerCursor (arrayIndex)->Close();
       
  1299 		PointerCursor (arrayIndex) = aCursor;
       
  1300 		}
       
  1301 	else
       
  1302 		{
       
  1303 		TWsCursorArrayItem entry;
       
  1304 		entry.iIndex=aIndex;
       
  1305 		entry.iCursor=aCursor;
       
  1306 		iSystemPointerCursors->InsertIsqL(entry, CursorKey);
       
  1307 		}
       
  1308 	aCursor->Open();
       
  1309 	if (aIndex==iDefaultSystemPointerCursorIndex)
       
  1310 		iDefaultSystemPointerCursor=aCursor;
       
  1311 	WsPointer::UpdatePointerCursor();
       
  1312 	}
       
  1313 
       
  1314 void CWsClient::ClearSystemPointerCursor(TInt aIndex)
       
  1315 	{
       
  1316 	if (iSystemPointerCursorListOwner!=this)
       
  1317 		PPanic(EWservPanicNotSystemPointerCursorListOwner);
       
  1318 	TInt arrayIndex;
       
  1319 	if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1320 		{
       
  1321 		DeleteSystemPointerListEntry(arrayIndex);
       
  1322 		if (aIndex==iDefaultSystemPointerCursorIndex)
       
  1323 			iDefaultSystemPointerCursor=NULL;
       
  1324 		}
       
  1325 	}
       
  1326 
       
  1327 void CWsClient::ClaimSystemPointerCursorListL()
       
  1328 	{
       
  1329 	if (iSystemPointerCursorListOwner)
       
  1330 		User::Leave(KErrInUse);
       
  1331 	const TInt systemPointerCursorGranularity = 4;
       
  1332 	iSystemPointerCursors = new(ELeave) CArrayFixFlat<TWsCursorArrayItem> (systemPointerCursorGranularity);
       
  1333 	iSystemPointerCursorListOwner=this;
       
  1334 	}
       
  1335 
       
  1336 void CWsClient::FreeSystemPointerCursorList()
       
  1337 	{
       
  1338 	if (iSystemPointerCursorListOwner==this)
       
  1339 		{
       
  1340 		iSystemPointerCursorListOwner=NULL;
       
  1341 		while(iSystemPointerCursors->Count()>0)
       
  1342 			DeleteSystemPointerListEntry(0);
       
  1343 		iDefaultSystemPointerCursor=NULL;
       
  1344 		iDefaultSystemPointerCursorIndex=0;
       
  1345 		delete iSystemPointerCursors;
       
  1346 		iSystemPointerCursors=NULL;
       
  1347 		}
       
  1348 	}
       
  1349 
       
  1350 void CWsClient::SetDefaultSystemPointerCursor(TInt aIndex)
       
  1351 	{
       
  1352 	TInt arrayIndex;
       
  1353 	if (iSystemPointerCursorListOwner!=this)
       
  1354 		PPanic(EWservPanicNotSystemPointerCursorListOwner);
       
  1355 	iDefaultSystemPointerCursorIndex=aIndex;
       
  1356 	iDefaultSystemPointerCursor=NULL;
       
  1357 	if (aIndex != ENoDefaultSystemPointerCursor &&
       
  1358 		FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1359 		iDefaultSystemPointerCursor = PointerCursor (arrayIndex);
       
  1360 	else
       
  1361 		iDefaultSystemPointerCursor=NULL;
       
  1362 	WsPointer::UpdatePointerCursor();
       
  1363 	}
       
  1364 
       
  1365 TBool CWsClient::FindCursorArrayItem(CArrayFixFlat<TWsCursorArrayItem>* aCursorArray,
       
  1366 									 TInt aIndex,TInt& aPosition)
       
  1367 	{
       
  1368 	if (!aCursorArray)
       
  1369 		{
       
  1370 		return EFalse; // No hit if the array isn't even allocated
       
  1371 		}
       
  1372 	TWsCursorArrayItem entry;
       
  1373 	entry.iIndex=aIndex;
       
  1374 	return aCursorArray->FindIsq(entry, CursorKey, aPosition)==KErrNone;
       
  1375 	}
       
  1376 
       
  1377 void CWsClient::SetClientPriority()
       
  1378 	{
       
  1379 	if (iComputeMode!=RWsSession::EPriorityControlDisabled)
       
  1380 		{
       
  1381 		Client().SetProcessPriority(
       
  1382 			iComputeMode==RWsSession::EPriorityControlComputeOn || CWsTop::FocusWindowGroupOwner()!=this ?
       
  1383 			  EPriorityBackground :
       
  1384 			  EPriorityForeground);
       
  1385 		}
       
  1386 	}
       
  1387 
       
  1388 void CWsClient::SetComputeMode(RWsSession::TComputeMode aComputeMode)
       
  1389 	{
       
  1390 	if (aComputeMode!=RWsSession::EPriorityControlDisabled &&
       
  1391 		 aComputeMode!=RWsSession::EPriorityControlComputeOn &&
       
  1392 		  aComputeMode!=RWsSession::EPriorityControlComputeOff)
       
  1393 		PPanic(EWservPanicSetComputeMode);
       
  1394 	iComputeMode=aComputeMode;
       
  1395 	SetClientPriority();
       
  1396 	}
       
  1397 
       
  1398 void CWsClient::CompleteMessage(const RMessage2& aMessage,TInt aReason)
       
  1399 	{
       
  1400 	if (!aMessage.IsNull())
       
  1401 		{
       
  1402 		if (iInternalFlags&EPanicClientAsSoonAsPossible)
       
  1403 			{
       
  1404 			aMessage.Panic(KWSERVSessionPanicCategory,iPanicReason);
       
  1405 			iInternalFlags&=~EPanicClientAsSoonAsPossible;
       
  1406 			}
       
  1407 		else
       
  1408 			{
       
  1409 			aMessage.Complete(aReason);
       
  1410 			}
       
  1411 		}
       
  1412 	}
       
  1413 
       
  1414 void CWsClient::ServiceError(const RMessage2& /*aMessage*/,TInt aError)
       
  1415 	{
       
  1416 	CompleteMessage(iClientMessage,aError);
       
  1417 	}
       
  1418 
       
  1419 void CWsClient::ServiceL(const RMessage2 &aMessage)
       
  1420 //
       
  1421 // Handle messages for the window server server.
       
  1422 //
       
  1423 	{
       
  1424 	iClientMessage=aMessage; // from now on use always the message stored in the session
       
  1425 	if (iInternalFlags&EPanicClientAsSoonAsPossible)
       
  1426 		{
       
  1427 		iClientMessage.Panic(KWSERVSessionPanicCategory,iPanicReason);
       
  1428 		}
       
  1429 	else
       
  1430 		{
       
  1431 		iPanicReason=KErrNone;
       
  1432 		iReply=KErrNone;
       
  1433 		TBool completeRequest=ETrue;
       
  1434 		DoServiceL(iClientMessage, completeRequest);
       
  1435 		if (completeRequest)
       
  1436 			{
       
  1437 			if(!iResponseHandle)
       
  1438 				{
       
  1439 				CompleteMessage(iClientMessage,iReply);
       
  1440 				}
       
  1441 			else
       
  1442 				{
       
  1443 // Prior to 9.0 RMessagePtr2.Complete doesn't have the option of sending a handle back
       
  1444 // However, since the security is lower simply sending the handle id is ok
       
  1445 				iClientMessage.Complete(*iResponseHandle);
       
  1446 				iResponseHandle = NULL;
       
  1447 				}
       
  1448 			}
       
  1449 		}
       
  1450 	}
       
  1451 
       
  1452 void CWsClient::SetResponseHandle(RHandleBase* aHandle)
       
  1453 	{
       
  1454 	iResponseHandle = aHandle;
       
  1455 	}
       
  1456 
       
  1457 void CWsClient::DoServiceL(const RMessage2& aMessage, TBool& aCompleteRequest)
       
  1458 	{
       
  1459 	const TInt function=aMessage.Function();
       
  1460 	switch (function)
       
  1461 		{
       
  1462 	case EWservMessInit:
       
  1463 		StartInitializationL(iConnectionId++);
       
  1464 		break;
       
  1465 	case EWservMessSyncMsgBuf:
       
  1466 	case EWservMessCommandBuffer:
       
  1467 		{
       
  1468 		if (!IsInitialised())			
       
  1469 			{
       
  1470 			PPanic(EWservPanicUninitialisedClient);
       
  1471 			}
       
  1472 			
       
  1473 		const TInt err=aMessage.Read(KBufferMessageSlot,iCmdBuf);
       
  1474 		if (err==KErrNone)
       
  1475 			{
       
  1476 			TRAPD(error,CommandBufL());
       
  1477 			iCurrentClient=NULL;
       
  1478 #if defined(_DEBUG)
       
  1479 			if (!iLastCommand && err!=KErrNone)
       
  1480 				{
       
  1481 				SessionPanic(EWservPanicFunctionLeave);
       
  1482 				}
       
  1483 #endif
       
  1484 			if (error<KErrNone)
       
  1485 				SetReply(error);
       
  1486 			}
       
  1487 		else if (err!=KErrDied)
       
  1488 			{
       
  1489 			PPanic(EWservPanicDescriptor);
       
  1490 			}
       
  1491 		if(function == EWservMessCommandBuffer && CWsTop::FinishEveryFlush())
       
  1492 			{
       
  1493 			if(Screen()->IsUpdatePending())	
       
  1494 				Screen()->DoRedrawNow();
       
  1495 			}
       
  1496 		else
       
  1497 			aCompleteRequest=(function!=EWservMessAsynchronousService);
       
  1498 		break;
       
  1499 		}
       
  1500 	case EWservMessShutdown:
       
  1501 		{
       
  1502 		if(!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for EWservMessShutdown message ")))
       
  1503 			{
       
  1504 			PPanic(EWservPanicPermissionDenied);
       
  1505 			}
       
  1506 		if (aMessage.Int0()==EWservShutdownCheck)
       
  1507 			CWsTop::Exit();
       
  1508 		else
       
  1509 			{
       
  1510 			PPanic(EWservPanicHandle);
       
  1511 			}
       
  1512 		}
       
  1513 		break;
       
  1514 	case EWservMessFinish:
       
  1515 		{
       
  1516 		if(Screen()->IsUpdatePending())	
       
  1517 			Screen()->DoRedrawNow();
       
  1518 		break;
       
  1519 		}
       
  1520 	default:
       
  1521 		if (function&EWservMessAsynchronousService)
       
  1522 			{
       
  1523 			TRAPD(err,CommandL((function&~EWservMessAsynchronousService), aMessage));
       
  1524 			aCompleteRequest=(err!=KErrNone);
       
  1525 			WS_ASSERT_DEBUG((!(iInternalFlags&EPanicClientAsSoonAsPossible))==(!aCompleteRequest), EWsPanicPanicFlagError);
       
  1526 			}
       
  1527 		else if (function&EWservMessAnimDllAsyncCommand)
       
  1528 			{
       
  1529 			CWsAnimDll* const animDll=STATIC_CAST(CWsAnimDll*,HandleToObj(aMessage.Int0(), WS_HANDLE_ANIM_DLL));
       
  1530 			if (!animDll)
       
  1531 				{
       
  1532 				SessionPanic(EWservPanicHandle);
       
  1533 				break;
       
  1534 				}
       
  1535 			// it looks wrong to call CommandReply here (not AsyncCommandReply, or something, which doesn't exist), but basically, we can't add a virtual AsyncCommandReplyL to CAnim to correspond to RAnim::AsyncCommandReply as that would break binary and source compatibility for Anim plug-ins; instead asynchronous commands are done by the plug-in having to complete the RMessagePtr2 returned by iFunctions->Message() (or a copy of of that object) for asynchronous commands only
       
  1536 			TRAPD(err,animDll->AnimObjectL(aMessage.Int1())->CommandReply(function&~EWservMessAnimDllAsyncCommand,NULL));
       
  1537 			aCompleteRequest=(err!=KErrNone);
       
  1538 			WS_ASSERT_DEBUG((!(iInternalFlags&EPanicClientAsSoonAsPossible))==(!aCompleteRequest), EWsPanicPanicFlagError);
       
  1539 			}
       
  1540 		else
       
  1541 			{
       
  1542 			SetReply(KErrNotSupported);
       
  1543 			}
       
  1544 		break;
       
  1545 		}
       
  1546 	}
       
  1547 
       
  1548 void CWsClient::RemoteRead(TDes16& aDes, TInt aOffset)
       
  1549 	{
       
  1550 	if (iClientMessage.Read(KRemoteBufferMessageSlot,aDes,aOffset)!=KErrNone)
       
  1551 		{
       
  1552 		SessionPanic(EWservPanicDescriptor);
       
  1553 		}
       
  1554 	}
       
  1555 
       
  1556 void CWsClient::RemoteRead(TDes8& aDes, TInt aOffset)
       
  1557 	{
       
  1558 	if (iClientMessage.Read(KRemoteBufferMessageSlot,aDes,aOffset)!=KErrNone)
       
  1559 		{
       
  1560 		SessionPanic(EWservPanicDescriptor);
       
  1561 		}
       
  1562 	}
       
  1563 
       
  1564 void CWsClient::RemoteReadL(TDes16& aDes, TInt aOffset)
       
  1565 	{
       
  1566 	iClientMessage.ReadL(KRemoteBufferMessageSlot,aDes,aOffset);
       
  1567 	}
       
  1568 
       
  1569 void CWsClient::RemoteReadL(TDes8& aDes, TInt aOffset)
       
  1570 	{
       
  1571 	iClientMessage.ReadL(KRemoteBufferMessageSlot,aDes,aOffset);
       
  1572 	}
       
  1573 
       
  1574 void CWsClient::DeleteStatics()
       
  1575 	{
       
  1576 	if (iTextCursorArray)
       
  1577 		{
       
  1578 		const TInt count = iTextCursorArray->Count();
       
  1579 		for (TInt index=0;index<count;index++)
       
  1580 			{
       
  1581 			delete iTextCursorArray->At(index).iCursor;
       
  1582 			}
       
  1583 		delete iTextCursorArray;
       
  1584 		iTextCursorArray = NULL;
       
  1585 		}
       
  1586 	}
       
  1587 		
       
  1588 // CWsClient implementing MWsClient \\\\\\\\\\\\\\\\\\\\\\\\
       
  1589 
       
  1590 TBool CWsClient::HasCapability(TCapability aCapability) const
       
  1591 	{
       
  1592 	return iClient.HasCapability(aCapability);
       
  1593 	}
       
  1594 
       
  1595 TSecureId CWsClient::SecureId() const
       
  1596 	{
       
  1597 	return iClient.SecureId();
       
  1598 	}
       
  1599 
       
  1600 TVendorId CWsClient::VendorId() const
       
  1601 	{
       
  1602 	return iClient.VendorId();
       
  1603 	}
       
  1604 /**
       
  1605 Makes a new copy of the aData. so it could be deleted after this call.
       
  1606 */
       
  1607 TInt CWsClient::SendMessage(const CWsGraphicDrawer* aOnBehalfOf,const TDesC8& aData)
       
  1608 	{
       
  1609 	CWsGraphicMessageQueue::CMessage* msg = CWsGraphicMessageQueue::CMessage::New(aData);
       
  1610 	if(msg)
       
  1611 		{
       
  1612 		return SendMessage(aOnBehalfOf,*msg);
       
  1613 		}
       
  1614 	return KErrGeneral;
       
  1615 	}
       
  1616 
       
  1617 TInt CWsClient::SendMessage(const CWsGraphicDrawer* aOnBehalfOf,CWsMessageData& aData)
       
  1618 	{
       
  1619 	WS_ASSERT_DEBUG(aData.Data().Size(), EWsPanicWsGraphic);
       
  1620 	const CWsGraphicDrawerObject* obj = DrawerObject(aOnBehalfOf);
       
  1621 	WS_ASSERT_DEBUG(obj, EWsPanicWsGraphic);
       
  1622 	if(obj)
       
  1623 		{
       
  1624 		// assign message id
       
  1625 		if(iMessageIdSeq == KMaxTInt) // Wrap if iMessageIdSeq has reached KMaxTInt
       
  1626 			iMessageIdSeq = 0;
       
  1627 		iMessageIdSeq++;
       
  1628 		// correct other handles
       
  1629 		aData.iClientHandle = (obj->ClientHandle() | (EWsGraphMessageTypeUser & 0x03));
       
  1630 		aData.iDrawer = obj->Drawer();
       
  1631 		aData.iId = iMessageIdSeq;
       
  1632 		iGraphicMessageQueue.Queue(&aData);
       
  1633 		return iMessageIdSeq;
       
  1634 		}
       
  1635 	return KErrGeneral;
       
  1636 	}
       
  1637 
       
  1638 /** adds a message to the message queue
       
  1639 @return a postive number to uniquely identify the message
       
  1640 */
       
  1641 
       
  1642 
       
  1643 CWsGraphicDrawerObject* CWsClient::DrawerObject(const CWsGraphicDrawer* aDrawer)
       
  1644 	{
       
  1645 	const TInt count = ObjectIndex()->Length();
       
  1646 	for(TInt i=0; i<count; i++)
       
  1647 		{
       
  1648 		CWsObject* obj = const_cast<CWsObject*>(ObjectIndex()->At(i));
       
  1649 		if(obj && (WS_HANDLE_GRAPHIC_DRAWER == obj->Type()))
       
  1650 			{
       
  1651 			CWsGraphicDrawerObject* candidate = static_cast<CWsGraphicDrawerObject*>(obj);
       
  1652 			if(candidate->Drawer() == aDrawer)
       
  1653 				{
       
  1654 				return candidate;
       
  1655 				}
       
  1656 			}
       
  1657 		}
       
  1658 	return NULL;
       
  1659 	}
       
  1660 
       
  1661 const CWsGraphicDrawerObject* CWsClient::DrawerObject(const CWsGraphicDrawer* aDrawer) const
       
  1662 	{
       
  1663 	CWsObjectIx* objectIndex = const_cast<CWsClient*>(this)->ObjectIndex();
       
  1664 	const TInt count = objectIndex->Length();
       
  1665 	for(TInt i=0; i<count; i++)
       
  1666 		{
       
  1667 		CWsObject* obj = const_cast<CWsObject*>(objectIndex->At(i));
       
  1668 		if(obj && (WS_HANDLE_GRAPHIC_DRAWER == obj->Type()))
       
  1669 			{
       
  1670 			const CWsGraphicDrawerObject* candidate = static_cast<CWsGraphicDrawerObject*>(obj);
       
  1671 			if(candidate->Drawer() == aDrawer)
       
  1672 				{
       
  1673 				return candidate;
       
  1674 				}
       
  1675 			}
       
  1676 		}
       
  1677 	return NULL;
       
  1678 	}
       
  1679 
       
  1680 //
       
  1681 
       
  1682 CWsCliObj* CWsCliObj::NewL(CWsClient *aOwner)
       
  1683 	{
       
  1684 	CWsCliObj* self = new(ELeave) CWsCliObj(aOwner);
       
  1685 	CleanupStack::PushL(self);
       
  1686 	self->ConstructL();
       
  1687 	CleanupStack::Pop(self);
       
  1688 	return self;
       
  1689 	}
       
  1690 
       
  1691 CWsCliObj::CWsCliObj(CWsClient *aOwner) : CWsObject(aOwner,WS_HANDLE_CLIENT)
       
  1692 	{
       
  1693 	__DECLARE_NAME(_S("CWsCliObj"));
       
  1694 	}
       
  1695 	
       
  1696 void CWsCliObj::ConstructL()
       
  1697 	{
       
  1698 	NewObjL();	
       
  1699 	}
       
  1700 
       
  1701 void CWsCliObj::CommandL(TInt aOpcode, const TAny *aCmdData)
       
  1702 	{
       
  1703 	iWsOwner->CommandL(aOpcode,aCmdData);
       
  1704 	}
       
  1705 
       
  1706 CWsObject* CWsClient::HandleToObjUntyped(TInt aHandle)
       
  1707 	{
       
  1708 	return(iObjectIndex->HandleToObject(aHandle));
       
  1709 	}
       
  1710 
       
  1711 CWsObject* CWsClient::HandleToObj(TInt aHandle, WH_HANDLES aType)
       
  1712 	{
       
  1713 	CWsObject* object = HandleToObjUntyped(aHandle);
       
  1714 	if (object && object->Type() == aType)
       
  1715 		{
       
  1716 		return object;
       
  1717 		}
       
  1718 	return NULL;
       
  1719 	}