windowing/windowserver/nga/SERVER/openwfc/CLIENT.CPP
changeset 0 5d03bc08d59c
child 13 1cb83e7796ad
child 19 ac96196b945c
child 36 01a6848ebfd7
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 #include <e32hashtab.h>  // for RHashMap
       
    36 #include "registeredsurfacemap.h"
       
    37 #include <graphics/wselement.h>
       
    38 
       
    39 #include "windowelementset.h"
       
    40 #include "drawresource.h"
       
    41 
       
    42 extern CDebugLogBase* wsDebugLog;
       
    43 _LIT(KWSERVSessionPanicCategory,"WSERV");
       
    44 
       
    45 GLREF_D TPtr nullDescriptor;
       
    46 
       
    47 TWsCmdHeaderBase CWsClient::iCurrentCommand;
       
    48 TBuf8<EClientBufferMaxSize> CWsClient::iCmdBuf;
       
    49 TInt CWsClient::iReply;
       
    50 TInt CWsClient::iReplyOffset;
       
    51 CWsClient* CWsClient::iCurrentClient;
       
    52 CWsObject* CWsClient::iDestObj;
       
    53 const TUint8* CWsClient::iNextCmd;
       
    54 CIdle* CWsClient::iMoreCommands=NULL;
       
    55 
       
    56 TUint CWsClient::iConnectionId = CDebugLogBase::EDummyConnectionId+1;
       
    57 CArrayFixFlat<CWsClient::TWsCursorArrayItem>* CWsClient::iSystemPointerCursors = NULL;
       
    58 TInt CWsClient::iDefaultSystemPointerCursorIndex = 0;		//Negative when there isn't one
       
    59 CWsPointerCursor* CWsClient::iDefaultSystemPointerCursor;
       
    60 CWsClient* CWsClient::iSystemPointerCursorListOwner = NULL;
       
    61 CArrayFixFlat<CWsClient::TWsCursorArrayItem>* CWsClient::iTextCursorArray = NULL;
       
    62 
       
    63 TKeyArrayFix CWsClient::iCursorKey(_FOFF(CWsClient::TWsCursorArrayItem,iIndex), ECmpTInt);
       
    64 
       
    65 /**
       
    66 Used for enforcing the redraw calling convention in emulator builds.
       
    67 When enabled this will panic any client calling a CWindowGc draw operation outside a 
       
    68 RWindow::BeginRedraw() / RWindow::EndRedraw() pair (known as non-redraw drawing).
       
    69 
       
    70 Enable by adding "debug_wserv_exe_EnforceRedrawCallingConvention X" to epoc.ini 
       
    71 where X is either 0 (zero) for "off" or 1 (one) for "on". 
       
    72 
       
    73 Then enable globally in WServ AutoFlush by defining __AUTO_FLUSH in ../client/client.h 
       
    74 or locally by calling RWsSession::SetAutoFlush(ETrue) for a specific client programatically, 
       
    75 or locally pressing Ctrl-Alt-Shift-F in the emulator.
       
    76 */
       
    77 TBool CWsClient::iDebug_EnforceRedrawCallingConvention = EFalse;
       
    78 
       
    79 // Security policy stings
       
    80 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_WriteDeviceData,ECapabilityWriteDeviceData);
       
    81 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_SwEvent,ECapabilitySwEvent);
       
    82 static _LIT_SECURITY_POLICY_C1(KSecurityPolicy_PowerMgmt,ECapabilityPowerMgmt);
       
    83 
       
    84 //
       
    85 // class CWsClient
       
    86 // 
       
    87 
       
    88 CWsClient::CWsClient(RThread aClient) : iClient(aClient), iGraphicMessageQueue(this), iInternalFlags(ERemoveKeyCode|EFinishedProcessingCommands)
       
    89 	{
       
    90 	iScreen = CWsTop::Screen();
       
    91 	}
       
    92 
       
    93 CWsClient::~CWsClient()
       
    94 	{
       
    95 	CWsTop::WindowServer()->RemoveAllGraphicDrawers(*this); // deindexes all graphic drawers owned by this client
       
    96 
       
    97 	delete iTempCustomTextCursor.iCursor;
       
    98 	FreeSystemPointerCursorList();
       
    99 	CWsTop::ClientDestroyed(this);
       
   100 	if (wsDebugLog)
       
   101 		{
       
   102 		_LIT(ClientDestuct,"Client %d destructing");
       
   103 		wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,ClientDestuct, iConnectionHandle);
       
   104 		}
       
   105 		
       
   106 	iInternalFlags |= EClientIsClosing;
       
   107 	delete iObjectIndex;
       
   108 	delete iEventQueue;
       
   109 	delete iRedrawQueue;
       
   110 	delete iPriorityKeyEvent;
       
   111 	CWsTop::ClearSurfaceMap(this);
       
   112 
       
   113 	CWsTop::SessionExited(this);
       
   114 	iClient.Close();
       
   115 	}
       
   116 
       
   117 void CWsClient::CompleteInitializationL()
       
   118 	{
       
   119 	iObjectIndex = new(ELeave) CWsObjectIx();
       
   120 	iObjectIndex->ConstructL();
       
   121 	
       
   122     iEventQueue = new(ELeave) CEventQueue(this);
       
   123 	iEventQueue->ConstructL();
       
   124     
       
   125     iRedrawQueue = new(ELeave) CRedrawQueue(this);
       
   126 	iRedrawQueue->ConstructL();
       
   127     
       
   128     iPriorityKeyEvent = new(ELeave) CPriorityKey(this);
       
   129 	
       
   130 	CWsCliObj::NewL(this);
       
   131 	
       
   132 	iComputeMode = RWsSession::EPriorityControlComputeOff;
       
   133 	
       
   134 	CWsTop::NewSession(this);
       
   135 	
       
   136 #ifdef __WINS__
       
   137 	TBool halValue = EFalse;
       
   138 	if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, 
       
   139 		(TAny*)"debug_wserv_exe_EnforceRedrawCallingConvention", &halValue) == KErrNone)
       
   140 		{
       
   141 		iDebug_EnforceRedrawCallingConvention = halValue;
       
   142 		}
       
   143 #endif
       
   144 	
       
   145 	iInternalFlags |= EIsInitialised;
       
   146 	}
       
   147 
       
   148 TBool CWsClient::DebugEnforceRedrawCallingConvention()
       
   149 	{
       
   150 	return iDebug_EnforceRedrawCallingConvention;
       
   151 	}
       
   152 
       
   153 void CWsClient::StartInitializationL(TUint aConnectionHandle)
       
   154 	{
       
   155 	if (wsDebugLog)
       
   156 		wsDebugLog->NewClient(aConnectionHandle);
       
   157 	
       
   158 	if (iObjectIndex)
       
   159 		PPanic(EWservPanicReInitialise);
       
   160 	else
       
   161 		{
       
   162 		iConnectionHandle = aConnectionHandle;
       
   163 		CompleteInitializationL();
       
   164 		}
       
   165 	}
       
   166 
       
   167 //
       
   168 // Convert a handle to object checking it is of the correct type.
       
   169 //
       
   170 void CWsClient::HandleToWindow(TInt aHandle,CWsWindowBase** pWin)
       
   171 	{
       
   172 	if ((*pWin=(CWsWindowBase* )HandleToObjUntyped(aHandle))==NULL ||
       
   173 		((*pWin)->Type()!=WS_HANDLE_WINDOW && (*pWin)->Type()!=WS_HANDLE_GROUP_WINDOW))
       
   174 		PPanic(EWservPanicWindow);
       
   175 	}
       
   176 
       
   177 //
       
   178 // Convert a handle to object checking it is of the correct type.
       
   179 //
       
   180 void CWsClient::HandleToClientWindow(TInt aHandle,CWsClientWindow** pWin)
       
   181 	{
       
   182 	if ((*pWin=(CWsClientWindow*)HandleToObj(aHandle, WS_HANDLE_WINDOW))==NULL)
       
   183 		PPanic(EWservPanicWindow);
       
   184 	}
       
   185 
       
   186 void CWsClient::CreateNewPointerCursorL(const TWsClCmdCreatePointerCursor &aCmd)
       
   187 	{
       
   188 	CWsPointerCursor* pc=new(ELeave) CWsPointerCursor(this);
       
   189 	CleanupStack::PushL(pc);
       
   190 	pc->ConstructL(aCmd);
       
   191 	CleanupStack::Pop();
       
   192 	}
       
   193 
       
   194 // Create a new custom text cursor
       
   195 void CWsClient::StartSetCustomTextCursorL(const TWsClCmdCustomTextCursorData& aCmd)
       
   196 	{
       
   197 	if (!iTextCursorArray)
       
   198 		{
       
   199 		const TInt textCursorArrayGranularity = 4;
       
   200 		iTextCursorArray = new(ELeave) CArrayFixFlat<TWsCursorArrayItem>(textCursorArrayGranularity);
       
   201 		}
       
   202 		
       
   203 	TInt arrayIndex = KErrNotFound;
       
   204 	if (FindCursorArrayItem(iTextCursorArray, aCmd.identifier, arrayIndex))
       
   205 		User::Leave(KErrAlreadyExists);
       
   206 	
       
   207 	delete iTempCustomTextCursor.iCursor;
       
   208 	iTempCustomTextCursor.iCursor = NULL;
       
   209 	iTempCustomTextCursor.iCursor = new(ELeave) CWsCustomTextCursor(this, aCmd.alignment);
       
   210 	
       
   211 	static_cast<CWsCustomTextCursor*>(iTempCustomTextCursor.iCursor)->ConstructL(aCmd.flags);
       
   212 	iTempCustomTextCursor.iIndex = aCmd.identifier;
       
   213 	}
       
   214 
       
   215 // Add new custom text cursor to global list
       
   216 void CWsClient::CompleteSetCustomTextCursorL(TInt aError)
       
   217 	{
       
   218 	if (aError)
       
   219 		{
       
   220 		delete iTempCustomTextCursor.iCursor;
       
   221 		iTempCustomTextCursor.iCursor = NULL;
       
   222 		User::Leave(aError);
       
   223 		}
       
   224 
       
   225 	TWsCursorArrayItem entry = iTempCustomTextCursor;
       
   226 	iTempCustomTextCursor.iCursor = NULL;
       
   227 	CleanupStack::PushL(entry.iCursor);
       
   228 
       
   229 	TInt arrayIndex;
       
   230 	if (FindCursorArrayItem(iTextCursorArray, entry.iIndex, arrayIndex))
       
   231 		User::Leave(KErrAlreadyExists);
       
   232 	else
       
   233 		iTextCursorArray->InsertIsqL(entry, iCursorKey);
       
   234 
       
   235 	CleanupStack::Pop(entry.iCursor);
       
   236 	}
       
   237 
       
   238 CWsCustomTextCursor* CWsClient::FindCustomTextCursor(TInt aIdentifier)
       
   239 	{
       
   240 	TInt arrayIndex;
       
   241 	if (!FindCursorArrayItem(iTextCursorArray, aIdentifier, arrayIndex))
       
   242 		return NULL;
       
   243 
       
   244 	return TextCursor(arrayIndex);
       
   245 	}
       
   246 
       
   247 void CWsClient::CreateNewSpriteL(const TWsClCmdCreateSprite &aCmd)
       
   248 	{
       
   249 	CWsSprite* sprite = new(ELeave) CWsSprite(this);
       
   250 	CleanupStack::PushL(sprite);
       
   251 	sprite->ConstructL(aCmd);
       
   252 	CleanupStack::Pop();
       
   253 	}
       
   254 
       
   255 void CWsClient::CreateNewBitmapL(const TWsClCmdCreateBitmap &aCmd)
       
   256 	{
       
   257 	DWsBitmap* bitmap = new(ELeave) DWsBitmap(this);
       
   258 	CleanupStack::PushL(bitmap);
       
   259 	bitmap->ConstructL(aCmd);
       
   260 	CleanupStack::Pop();
       
   261 	}
       
   262 
       
   263 /** Creates a new window.
       
   264 
       
   265 If the parent is a window group then a new CWsTopClientWindow instance is created. If the parent is
       
   266 a window then a new CWsClientWindow instance is created.
       
   267 
       
   268 @param aCmd The command received from the client
       
   269 @internalComponent
       
   270 @released
       
   271 */
       
   272 void CWsClient::CreateNewWindowL(const TWsClCmdCreateWindow &aCmd)
       
   273 	{
       
   274 	CWsWindowBase* parent;
       
   275 	HandleToWindow(aCmd.parent,&parent);
       
   276 	CWsClientWindow* win = NULL;
       
   277 	TBool deviceIsInvalid = EFalse;
       
   278 	CScreen* screen = parent->Screen();
       
   279 	if (parent->WinType()==EWinTypeGroup)
       
   280 		{
       
   281 		__ASSERT_DEBUG(!((CWsWindowGroup*)parent)->ScreenDeviceDeleted(),PPanic(EWservPanicGroupWinScreenDeviceDeleted));
       
   282 		win=new(ELeave) CWsTopClientWindow(this, screen);
       
   283 		deviceIsInvalid=!((CWsWindowGroup*)parent)->ScreenDeviceValid();
       
   284 		}
       
   285 	else
       
   286 		win=new(ELeave) CWsClientWindow(this, screen);
       
   287 
       
   288 	CleanupStack::PushL(win);
       
   289 	win->ConstructL(aCmd,parent,deviceIsInvalid);
       
   290 	CleanupStack::Pop(win);
       
   291 	}
       
   292 
       
   293 void CWsClient::CreateNewWindowGroupL(const TWsClCmdCreateWindowGroup &aCmd)
       
   294 	{
       
   295 	CWsWindowGroup::NewL(this, NULL, aCmd); //screen is initialised inside the constructL
       
   296 	}
       
   297 
       
   298 void CWsClient::CreateNewAnimDllL(const TWsClCmdUnion &aParams)
       
   299 	{
       
   300 	CWsAnimDll* animDll = new(ELeave) CWsAnimDll(this);
       
   301 	CleanupStack::PushL(animDll);
       
   302 	animDll->LoadL(BufferTPtr((TText*)(aParams.LoadAnimDll+1),aParams.LoadAnimDll->length));
       
   303 	CleanupStack::Pop();
       
   304 	}	
       
   305 
       
   306 void CWsClient::CreateNewScreenDeviceL(TInt aDefaultScreenNumber, TUint aClientScreenDevicePointer)
       
   307 	{
       
   308 	DWsScreenDevice* screenDevice = new(ELeave) DWsScreenDevice(this, aDefaultScreenNumber,aClientScreenDevicePointer);
       
   309 	CleanupStack::PushL(screenDevice);
       
   310 	screenDevice->ConstructL();
       
   311 	CleanupStack::Pop(screenDevice);
       
   312 	if (iPrimaryScreenDevice==NULL)
       
   313 		{
       
   314 		iPrimaryScreenDevice=screenDevice;
       
   315 		// When client create screen device, change default screen to the one specified.
       
   316 		// Client should do this immediately after establishing session
       
   317 		iScreen = iPrimaryScreenDevice->Screen();
       
   318 		InitialiseScreenDevices();
       
   319 		}
       
   320 	}
       
   321 
       
   322 void CWsClient::InitialiseScreenDevices()
       
   323 	{
       
   324 	const TWsObject* ptr = iObjectIndex->FirstObject();
       
   325 	const TWsObject* end = ptr+iObjectIndex->Length();
       
   326 	WS_ASSERT_DEBUG(ptr->iObject==NULL, EWsPanicObjectIndexError);
       
   327 	while(++ptr<end)
       
   328 		{
       
   329 		if (ptr->iObject && ptr->iObject->Type()==WS_HANDLE_GROUP_WINDOW)
       
   330 			{
       
   331 			CWsWindowGroup* gw = static_cast<CWsWindowGroup*>(ptr->iObject);
       
   332 			if(!gw->Device())
       
   333 				gw->SetScreenDevice(iPrimaryScreenDevice);
       
   334 			}
       
   335 		}
       
   336 	}
       
   337 
       
   338 void CWsClient::CreateNewClickHandlerL(const TUid& aUid)
       
   339 	{
       
   340 	CClick* click = new(ELeave) CClick(this);
       
   341 	CleanupStack::PushL(click);
       
   342 	click->ConstructL(aUid);
       
   343 	CleanupStack::Pop(click);
       
   344 	}
       
   345 
       
   346 void CWsClient::RequestComplete(TRequestStatus*  &aStatus, TInt aErr)
       
   347 	{
       
   348 	Client().RequestComplete(aStatus,aErr);
       
   349 	}
       
   350 
       
   351 void CWsClient::PanicCurrentClient(TClientPanic aPanic)
       
   352 	{
       
   353 	iCurrentClient->PPanic(aPanic);
       
   354 	}
       
   355 
       
   356 void CWsClient::PPanic(TClientPanic aPanic) const
       
   357 //This function is allowed to leave with out the 'L' convention for special reasons
       
   358 	{
       
   359 	SessionPanic(aPanic);
       
   360 	User::Leave(EPanicLeave);
       
   361 	}
       
   362 
       
   363 void CWsClient::SessionPanic(TClientPanic aReason) const
       
   364 	{
       
   365 	if (wsDebugLog)
       
   366 		wsDebugLog->Panic(iConnectionHandle, aReason);
       
   367 	
       
   368 	if (!(iInternalFlags&EPanicClientAsSoonAsPossible)) // keep the first error code
       
   369 		{
       
   370 		iInternalFlags |= EPanicClientAsSoonAsPossible;
       
   371 		iPanicReason = aReason;
       
   372 		}
       
   373 	}
       
   374 
       
   375 void CWsClient::SessionTerminate()
       
   376 	{
       
   377 	if (wsDebugLog)
       
   378 		wsDebugLog->Panic(iConnectionHandle, 0);
       
   379 
       
   380 	const RThread thread=Client();
       
   381 	RProcess process;
       
   382 	if (thread.Process(process)==KErrNone)
       
   383 		{
       
   384 		process.Terminate(0);
       
   385 		process.Close();
       
   386 		}
       
   387 	}
       
   388 
       
   389 /**	
       
   390 Returns the remaining space in the descriptor
       
   391 */
       
   392 TInt CWsClient::ReplyBufSpace() 
       
   393 	{
       
   394 	const TInt retVal = iCurrentClient->ClientMessage().GetDesLength(KReplyBufferMessageSlot);
       
   395 	
       
   396 	if (iReplyOffset>=0 && retVal>=iReplyOffset)
       
   397 		return retVal-iReplyOffset;
       
   398 	else
       
   399 		return (retVal<0 ? retVal : KErrBadDescriptor);
       
   400 	}
       
   401 
       
   402 void CWsClient::ReplyBuf(const TDesC16 &aDes)	// static
       
   403 	{
       
   404 	WS_ASSERT_DEBUG(!iCurrentClient->ClientMessage().IsNull(), EWsPanicInvalidMessageHandle);
       
   405 	
       
   406 	if(iCurrentClient->ClientMessage().Write(KReplyBufferMessageSlot,aDes,iReplyOffset) != KErrNone)
       
   407 		PanicCurrentClient(EWservPanicDescriptor);
       
   408 	
       
   409 	iReplyOffset += aDes.Length();
       
   410 	if (wsDebugLog)
       
   411 		wsDebugLog->ReplyBuf(aDes);
       
   412 	}
       
   413 
       
   414 void CWsClient::ReplyBuf(const TDesC8 &aDes)	// static
       
   415 	{
       
   416 	WS_ASSERT_DEBUG(!iCurrentClient->ClientMessage().IsNull(), EWsPanicInvalidMessageHandle);
       
   417 	
       
   418 	if(iCurrentClient->ClientMessage().Write(KReplyBufferMessageSlot, aDes, iReplyOffset) != KErrNone)
       
   419 		PanicCurrentClient(EWservPanicDescriptor);
       
   420 	
       
   421 	iReplyOffset += aDes.Length();
       
   422 	if (wsDebugLog)
       
   423 		wsDebugLog->ReplyBuf(aDes);
       
   424 	}
       
   425 
       
   426 void CWsClient::ReplyBuf(const TAny* aSource, TInt aLength)	// static
       
   427 //
       
   428 // Send a buffer to the client process.
       
   429 //
       
   430 	{
       
   431 	TPtrC8 src(reinterpret_cast<const TUint8*>(aSource),aLength);
       
   432 	ReplyBuf(src);
       
   433 	}
       
   434 
       
   435 void CWsClient::ReplySize(const TSize &aSize)	// static
       
   436 	{
       
   437 	ReplyBuf(&aSize, sizeof(aSize));
       
   438 	}
       
   439 
       
   440 void CWsClient::ReplyPoint(const TPoint &aPoint)	// static
       
   441 	{
       
   442 	ReplyBuf(&aPoint, sizeof(aPoint));
       
   443 	}
       
   444 
       
   445 void CWsClient::ReplyRect(const TRect &aRect)	// static
       
   446 	{
       
   447 	ReplyBuf(&aRect, sizeof(aRect));
       
   448 	}
       
   449 
       
   450 void CWsClient::SetReply(TInt reply)
       
   451 	{
       
   452 	iReply = reply;
       
   453 	if (wsDebugLog)
       
   454 		wsDebugLog->Reply(reply);
       
   455 	}
       
   456 
       
   457 const TUint8* CWsClient::EndOfCommandBuffer()
       
   458 	{
       
   459 	return(iCmdBuf.Ptr()+iCmdBuf.Size());
       
   460 	}
       
   461 
       
   462 const TPtrC CWsClient::BufferTPtr(TText *aStart,TInt aLen)
       
   463 	{
       
   464 	TPtrC ptr;
       
   465 	if (!BufferTPtrGc(aStart,aLen,ptr))
       
   466 		PanicCurrentClient(EWservPanicBufferPtr);
       
   467 	return(ptr);
       
   468 	}
       
   469 
       
   470 TBool CWsClient::BufferTPtrGc(TText* aStart,TInt aLen, TPtrC& aPtr)
       
   471 	{
       
   472 	if (iCurrentCommand.iOpcode>0)
       
   473 		{
       
   474 		if ((REINTERPRET_CAST(TUint8*,aStart)<iCmdBuf.Ptr()
       
   475 										|| REINTERPRET_CAST(TUint8*,aStart+aLen)>(iCmdBuf.Ptr()+iCmdBuf.Size())))
       
   476 			return(EFalse);
       
   477 		}
       
   478 	else
       
   479 		{
       
   480 		if (aLen>=iCurrentCommand.iCmdLength)
       
   481 			return(EFalse);
       
   482 		}
       
   483 	aPtr.Set(aStart,aLen);
       
   484 	return(ETrue);
       
   485 	}
       
   486 
       
   487 const TPtrC8 CWsClient::BufferTPtr8(TUint8* aStart,TInt aLen)
       
   488 	{
       
   489 	if (iCurrentCommand.iOpcode>0 && (REINTERPRET_CAST(TUint8*,aStart)<iCmdBuf.Ptr()
       
   490 										|| REINTERPRET_CAST(TUint8*,aStart+aLen)>(iCmdBuf.Ptr()+iCmdBuf.Size())))
       
   491 		PanicCurrentClient(EWservPanicBufferPtr);
       
   492 		
       
   493 	return(TPtrC8(aStart,aLen));
       
   494 	}
       
   495 
       
   496 /**
       
   497 Process a command buffer
       
   498 
       
   499 @internalComponent
       
   500 @released
       
   501 */
       
   502 void CWsClient::DispatchCommandsInBufL()	// (step #4)
       
   503 	{		
       
   504 	if (wsDebugLog)
       
   505 		{
       
   506  		wsDebugLog->CommandBuf(iConnectionHandle);
       
   507  		RThread client = Client(); 
       
   508  		wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything, client.FullName());
       
   509 		}
       
   510 	const TUint8* endCmd=iCmdBuf.Ptr()+iCmdBuf.Length();
       
   511 	do
       
   512 		{
       
   513 		const TWsCmdHeader* pCmd=
       
   514 				reinterpret_cast<const TWsCmdHeader*>(iNextCmd);
       
   515 		TUint opcode = pCmd->iBase.iOpcode;
       
   516 		TInt headerLen = sizeof(pCmd->iBase);
       
   517 		iCurrentCommand = pCmd->iBase;
       
   518 		
       
   519 		// For performance reasons the handle is only included
       
   520 		// if it is different from the previous command. The EWsOpcodeHandle
       
   521 		// flag indicates whether a new handle has been included in the
       
   522 		// current command. If not we use the same handle as the previous
       
   523 		// command.
       
   524 		if (opcode&EWsOpcodeHandle)
       
   525 			{
       
   526 			// Find the WServ object associated with this op code
       
   527 			opcode &= ~EWsOpcodeHandle;
       
   528 			iCurrentCommand.iOpcode = reinterpret_cast<TUint16&>(opcode);
       
   529 			iDestObj=HandleToObjUntyped(pCmd->iDestHandle);
       
   530 			headerLen = sizeof(*pCmd);
       
   531 			}
       
   532 			
       
   533 		iNextCmd += headerLen;
       
   534 		const TAny* cmdParams = iNextCmd;
       
   535 		iNextCmd += pCmd->iBase.iCmdLength;
       
   536 		if (!iDestObj || iNextCmd>endCmd)		// Invalid handle or Corrupt buffer
       
   537 			{
       
   538 			SessionPanic(iDestObj==NULL ? EWservPanicHandle : EWservPanicBuffer);
       
   539 			iInternalFlags|=EFinishedProcessingCommands;
       
   540 			break;
       
   541 			}
       
   542 
       
   543 		if (iNextCmd==endCmd)
       
   544 			iInternalFlags|=EFinishedProcessingCommands;
       
   545 			
       
   546 		if (wsDebugLog)
       
   547 			wsDebugLog->Command(iDestObj->Type(), opcode, cmdParams, iDestObj->LogHandle());
       
   548 		
       
   549 		// Dispatch the command to the WServ object that will process it
       
   550 		iDestObj->CommandL(opcode, cmdParams);	// (call #5)
       
   551 		} 
       
   552 	while(iNextCmd<endCmd && !TWindowServerEvent::EventReceiver()->IsReadyToRun());
       
   553 	
       
   554 	}
       
   555 
       
   556 void CWsClient::DoServiceCommandBuf() // (step #3.1)
       
   557 	{
       
   558 	iCurrentClient=this;
       
   559 	iInternalFlags&=~EFinishedProcessingCommands;
       
   560 	TRAPD(err, DispatchCommandsInBufL());	// (call #4)
       
   561 	
       
   562 #if defined(_DEBUG)
       
   563 	if (err!=KErrNone && !(iInternalFlags&(EFinishedProcessingCommands|EPanicClientAsSoonAsPossible)))
       
   564 		SessionPanic(EWservPanicFunctionLeave);
       
   565 #endif
       
   566 
       
   567 	if (err<KErrNone)
       
   568 		SetReply(err);
       
   569 
       
   570 	if (iInternalFlags&(EFinishedProcessingCommands|EPanicClientAsSoonAsPossible))
       
   571 		CompleteMessage(iClientMessage,iReply);	// (finish)
       
   572 	else
       
   573 		iMoreCommands->Start(TCallBack(CWsClient::DoContinueDeferredServiceOfCommandBuf,this));	// (call #3.1.1)
       
   574 	
       
   575 	iCurrentClient=NULL;
       
   576 #if defined(_DEBUG)
       
   577 	User::Heap().Check();
       
   578 #endif
       
   579 	}
       
   580 
       
   581 TInt CWsClient::DoContinueDeferredServiceOfCommandBuf(TAny* aClient)	// (step #3.1.1)
       
   582 	{
       
   583 	static_cast<CWsClient*>(aClient)->DoServiceCommandBuf();	// (call #3.1)
       
   584 	return KErrNone;
       
   585 	}
       
   586 
       
   587 
       
   588 void CWsClient::ExecuteAsyncClientCommandL(TInt aOpcode, const RMessage2& aMessage)	// (step #3.2)
       
   589 	{
       
   590 	switch(aOpcode)
       
   591 		{
       
   592 		case EWsClOpEventReady:
       
   593 			EventReady(aMessage);
       
   594 			break;
       
   595 		case EWsClOpPriorityKeyReady:
       
   596 			PriorityKeyEventReady(aMessage);
       
   597 			break;
       
   598 		case EWsClOpRedrawReady:
       
   599 			RedrawEventReady(aMessage);
       
   600 			break;
       
   601 		case EWsClOpGraphicMessageReady:
       
   602 			iGraphicMessageQueue.EventReady(aMessage);
       
   603 			break;
       
   604 		default:
       
   605 			{
       
   606 			PPanic(EWservPanicOpcode);
       
   607 			break;
       
   608 			}
       
   609 		}
       
   610 	}
       
   611 
       
   612 
       
   613 
       
   614 void CWsClient::ExecuteCommandL(TInt aOpcode, const TAny* aCmdData)	// (step #6)
       
   615 	{
       
   616 	TWsClCmdUnion pData;
       
   617 	pData.any=aCmdData;
       
   618 	switch(aOpcode)
       
   619 		{
       
   620 		case EWsClOpCreateWindowGroup:
       
   621 			CreateNewWindowGroupL(*pData.CreateWindowGroup);
       
   622 			break;
       
   623 		case EWsClOpCreateWindow:
       
   624 			CreateNewWindowL(*pData.CreateWindow);
       
   625 			break;
       
   626 		case EWsClOpCreateGc:
       
   627 			CWsGc::NewL(this);
       
   628 			break;
       
   629 		case EWsClOpCreateAnimDll:
       
   630 			if (!CheckBuffer(pData.LoadAnimDll->length, KMaxFileName))
       
   631 				PanicCurrentClient(EWservPanicBufferPtr);
       
   632 			CreateNewAnimDllL(pData);
       
   633 			break;
       
   634 		case EWsClOpCreateGraphic:
       
   635 			CWsGraphicDrawerObject::NewL(this,pData);
       
   636 			break;
       
   637 		case EWsClOpCreateScreenDevice:
       
   638 			{
       
   639 			const TInt screenNumber = pData.CreateScreenDevice->screenNumber;
       
   640 			const TUint clientScreenDevicePointer = pData.CreateScreenDevice->clientScreenDevicePointer;
       
   641 			if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
   642 				{
       
   643 				PPanic(EWservPanicScreenNumber);
       
   644 				}
       
   645 			else
       
   646 				{
       
   647 				CreateNewScreenDeviceL(screenNumber,clientScreenDevicePointer);
       
   648 				}
       
   649 			}
       
   650 			break;
       
   651 		case EWsClOpCreateSprite:
       
   652 			CreateNewSpriteL(*pData.CreateSprite);
       
   653 			break;
       
   654 		case EWsClOpCreatePointerCursor:
       
   655 			CreateNewPointerCursorL(*pData.CreatePointerCursor);
       
   656 			break;
       
   657 		case EWsClOpStartSetCustomTextCursor:
       
   658 			StartSetCustomTextCursorL(*pData.CustomTextCursorData);
       
   659 			break;
       
   660 		case EWsClOpCompleteSetCustomTextCursor:
       
   661 			CompleteSetCustomTextCursorL(*pData.Int);
       
   662 			break;
       
   663 		case EWsClOpCreateBitmap:
       
   664 			CreateNewBitmapL(*pData.CreateBitmap);
       
   665 			break;
       
   666 		case EWsClOpCreateDirectScreenAccess:
       
   667 			CWsDirectScreenAccess::NewL(this,EFalse);
       
   668 			break;
       
   669 		case EWsClOpCreateDirectScreenAccessRegionTrackingOnly:
       
   670 			CWsDirectScreenAccess::NewL(this,ETrue);	//creates a DSA object that will not draw to the screen, but will use just the region tracking functionality
       
   671 			break;
       
   672 		case EWsClOpCreateClick:
       
   673 			CreateNewClickHandlerL(*pData.Uid);
       
   674 			break;
       
   675 		case EWsClOpSetHotKey:
       
   676 			{
       
   677 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetHotKey API")))
       
   678 				{
       
   679 				User::Leave(KErrPermissionDenied);
       
   680 				}
       
   681 			TWindowServerEvent::SetHotKeyL(*pData.SetHotKey);
       
   682 			}
       
   683 			break;
       
   684 		case EWsClOpClearHotKeys:
       
   685 			{
       
   686 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::ClearHotKeys API")))
       
   687 				{
       
   688 				User::Leave(KErrPermissionDenied);
       
   689 				}
       
   690 			TWindowServerEvent::ClearHotKeysL(*pData.UInt);
       
   691 			}
       
   692 			break;
       
   693 		case EWsClOpRestoreDefaultHotKey:
       
   694 			TWindowServerEvent::ResetDefaultHotKeyL(*pData.UInt);
       
   695 			break;
       
   696 		case EWsClOpSetShadowVector:
       
   697 			PPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client
       
   698 			break;
       
   699 		case EWsClOpShadowVector:
       
   700 			PPanic(EWservPanicOpcode); //this op code is deprecated, should never be generated by the client
       
   701 			break;
       
   702 		case EWsClOpSetKeyboardRepeatRate:
       
   703 			{
       
   704 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetKeyboardRepeatRate API")))
       
   705 				{
       
   706 				User::Leave(KErrPermissionDenied);
       
   707 				}
       
   708 			if ((pData.SetKeyboardRepeatRate->initial.Int()<0) || (pData.SetKeyboardRepeatRate->time.Int()<0))
       
   709 				{
       
   710 				User::Leave(KErrArgument);
       
   711 				}
       
   712 			CKeyboardRepeat::SetRepeatTime(pData.SetKeyboardRepeatRate->initial,pData.SetKeyboardRepeatRate->time);
       
   713 			}
       
   714 			break;
       
   715 		case EWsClOpGetKeyboardRepeatRate:
       
   716 			{
       
   717 			SKeyRepeatSettings settings;
       
   718 			CKeyboardRepeat::GetRepeatTime(settings.iInitialTime,settings.iTime);
       
   719 			ReplyBuf(&settings,sizeof(settings));
       
   720 			}
       
   721 			break;
       
   722 		case EWsClOpSetDoubleClick:
       
   723 			{
       
   724 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetDoubleClick API")))
       
   725 				{
       
   726 				User::Leave(KErrPermissionDenied);
       
   727 				}
       
   728 			TWsPointer::SetDoubleClick(pData.SetDoubleClick->interval,pData.SetDoubleClick->distance);
       
   729 			}
       
   730 			break;
       
   731 		case EWsClOpGetDoubleClickSettings:
       
   732 			{
       
   733 			SDoubleClickSettings settings;
       
   734 			TWsPointer::GetDoubleClickSettings(settings.iInterval,settings.iDistance);
       
   735 			ReplyBuf(&settings,sizeof(settings));
       
   736 			}
       
   737 			break;
       
   738 		case EWsClOpEventReady:
       
   739 			// No need to do anything
       
   740 			break;
       
   741 		case EWsClOpGetEvent:
       
   742 			HandleClientRequestForEventData();
       
   743 			// Check flag if the group message queue is overflow and has pended messages  
       
   744 			if (iInternalFlags & EWgMsgQueueOverflow)
       
   745 				{
       
   746 				iInternalFlags &= ~EWgMsgQueueOverflow;
       
   747 				CWsWindowGroup::ReleasePendedMessagesToAllGroups(this);
       
   748 				}
       
   749 			break;
       
   750 		case EWsClOpPurgePointerEvents:
       
   751 			PurgePointerEvents();
       
   752 			break;
       
   753 		case EWsClOpEventReadyCancel:
       
   754 			CancelClientRequestForEventData();
       
   755 			break;
       
   756 		case EWsClOpRedrawReady:
       
   757 			iInternalFlags&=~EIsPerformingRedrawEvent;
       
   758 			break;
       
   759 		case EWsClOpRedrawReadyCancel:
       
   760 			CancelClientRequestForRedrawEvent();
       
   761 			break;
       
   762 		case EWsClOpGetRedraw:
       
   763 			HandleClientRequestForRedrawData();
       
   764 			break;
       
   765 		case EWsClOpPriorityKeyReady:
       
   766 			// No need to do anything
       
   767 			break;
       
   768 		case EWsClOpPriorityKeyReadyCancel:
       
   769 			CancelClientRequestForPriorityKeyEvent();
       
   770 			break;
       
   771 		case EWsClOpGetPriorityKey:
       
   772 			HandleClientRequestForPriorityKeyData();
       
   773 			break;
       
   774 		case EWsClOpNumWindowGroups:
       
   775 			SetReply(CWsWindowGroup::NumWindowGroups(EFalse,* pData.Int));
       
   776 			break;
       
   777 		case EWsClOpNumWindowGroupsAllPriorities:
       
   778 			SetReply(CWsWindowGroup::NumWindowGroups(ETrue, 0));
       
   779 			break;
       
   780 		case EWsClOpNumWindowGroupsOnScreen:
       
   781 			{
       
   782 			const TInt screenNumber=pData.NumWinGroups->screenNumber;
       
   783 			if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
   784 				PPanic(EWservPanicScreenNumber);
       
   785 			else
       
   786 				SetReply(CWsWindowGroup::NumWindowGroupsOnScreen(CWsTop::Screen(screenNumber)->RootWindow()->Child(),(pData.NumWinGroups->priority==EAllPriorities),pData.NumWinGroups->priority));
       
   787 			}
       
   788 			break;
       
   789 		case EWsClOpWindowGroupList:
       
   790 			{
       
   791 			const TInt screenNumber=pData.WindowGroupList->screenNumber;
       
   792 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   793 				PPanic(EWservPanicScreenNumber);
       
   794 			else
       
   795 				SetReply(CWsWindowGroup::SendWindowGroupListL(screenNumber,(pData.WindowGroupList->priority==EAllPriorities), pData.WindowGroupList->priority, pData.WindowGroupList->count));
       
   796 			}
       
   797 			break;
       
   798 		case EWsClOpWindowGroupListAllPriorities:
       
   799 			{
       
   800 			const TInt screenNumber=pData.WindowGroupList->screenNumber;
       
   801 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   802 				PPanic(EWservPanicScreenNumber);
       
   803 			else
       
   804 				SetReply(CWsWindowGroup::SendWindowGroupListL(screenNumber,ETrue, 0, pData.WindowGroupList->count));
       
   805 			}
       
   806 			break;
       
   807 		case EWsClOpWindowGroupListAndChain:
       
   808 			SetReply(CWsWindowGroup::SendWindowGroupListAndChainL(EFalse, pData.WindowGroupList->priority, pData.WindowGroupList->count));
       
   809 			break;
       
   810 		case EWsClOpWindowGroupListAndChainAllPriorities:
       
   811 			SetReply(CWsWindowGroup::SendWindowGroupListAndChainL(ETrue, 0, pData.WindowGroupList->count));
       
   812 			break;
       
   813 		case EWsClOpGetDefaultOwningWindow:
       
   814 			{
       
   815 			const TInt screenNumber = *pData.Int;
       
   816 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   817 				PPanic(EWservPanicScreenNumber);
       
   818 			else
       
   819 				{
       
   820 				CScreen* screen = (screenNumber ==KDummyScreenNumber) ? iScreen : CWsTop::Screen(screenNumber);
       
   821 				SetReply(screen->DefaultOwningWindowGroup() ? screen->DefaultOwningWindowGroup()->Identifier():0);
       
   822 				}
       
   823 			}
       
   824 			break;
       
   825 		case EWsClOpGetFocusWindowGroup:
       
   826 			{
       
   827 			const TInt screenNumber = *pData.Int;
       
   828 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
   829 				PPanic(EWservPanicScreenNumber);
       
   830 			else
       
   831 				CWsWindowGroup::GetFocusWindowGroupL(screenNumber);
       
   832 			}
       
   833 			break;
       
   834 		case EWsClOpSetWindowGroupOrdinalPosition:
       
   835 			CWsWindowGroup::WindowGroupFromIdentifierL(pData.SetWindowGroupOrdinalPosition->identifier)->SetOrdinalPosition(pData.SetWindowGroupOrdinalPosition->position);
       
   836 			break;
       
   837 		case EWsClOpGetWindowGroupHandle:
       
   838 			SetReply(CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->ClientHandle());
       
   839 			break;
       
   840 		case EWsClOpGetWindowGroupOrdinalPriority:
       
   841 			SetReply(CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->OrdinalPriority());
       
   842 			break;
       
   843 		case EWsClOpGetWindowGroupClientThreadId:
       
   844 			{
       
   845 			TThreadId id=CWsWindowGroup::WindowGroupFromIdentifierL(*pData.Int)->WsOwner()->Client().Id();
       
   846 			ReplyBuf(&id,sizeof(id));
       
   847 			}
       
   848 			break;
       
   849 		case EWsClOpSendEventToWindowGroup:
       
   850 			{
       
   851 			CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(pData.SendEventToWindowGroup->parameter);
       
   852 			TWsEvent event=pData.SendEventToWindowGroup->event;
       
   853 			event.SetHandle(group->ClientHandle());
       
   854 			// Events in enum TEventCode is protected by capabilities
       
   855 			if (group->WsOwner()!=this && event.Type()>=EEventNull && event.Type()<EEventUser)
       
   856 				{
       
   857 				if (event.Type()<EEventPowerMgmt || event.Type()>=EEventReserved)
       
   858 					{
       
   859 					if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToWindowGroup API")))
       
   860 						User::Leave(KErrPermissionDenied);
       
   861 					}
       
   862 				else
       
   863 					{
       
   864 					if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToWindowGroup API")))
       
   865 						User::Leave(KErrPermissionDenied);
       
   866 					}
       
   867 				}
       
   868 			if (event.Type()==EEventKey && event.Key()->iRepeats!=0)
       
   869 				CKeyboardRepeat::CancelRepeat(NULL);		//Otherwise we will trip an invarient
       
   870 			if (!group->EventQueue()->QueueEvent(event))
       
   871 				User::Leave(KErrNoMemory);
       
   872 			}
       
   873 			break;
       
   874 		case EWsClOpSendEventToAllWindowGroup:
       
   875 		case EWsClOpSendEventToAllWindowGroupPriority:
       
   876 		case EWsClOpSendEventToOneWindowGroupPerClient:
       
   877 			{
       
   878 			TWsEvent event=pData.SendEventToWindowGroup->event;
       
   879 			if (event.Type()<0)
       
   880 				User::Leave(KErrArgument);
       
   881 			if(event.Type()<EEventUser)
       
   882 				{
       
   883 				if (event.Type()<EEventPowerMgmt || event.Type()>=EEventReserved)
       
   884 					{
       
   885 					if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToAllWindowGroup API")))
       
   886 						User::Leave(KErrPermissionDenied);
       
   887 					}
       
   888 				else 
       
   889 					{
       
   890 					if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendEventToAllWindowGroup API")))
       
   891 						User::Leave(KErrPermissionDenied);
       
   892 					}
       
   893 				}
       
   894 			if (!CWsWindowGroup::SendEventToAllGroups(aOpcode!=EWsClOpSendEventToAllWindowGroupPriority
       
   895 													,aOpcode==EWsClOpSendEventToOneWindowGroupPerClient,*pData.SendEventToWindowGroup))
       
   896 				User::Leave(KErrNoMemory);
       
   897 			}
       
   898 			break;
       
   899 		case EWsClOpSendMessageToWindowGroup:
       
   900 			{
       
   901 			CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(pData.SendMessageToWindowGroup->identifierOrPriority);
       
   902 			if (group->WsOwner()!=this)
       
   903 				{
       
   904 				if (!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SendMessageToWindowGroup API")))
       
   905 					{
       
   906 					User::Leave(KErrPermissionDenied);
       
   907 					}
       
   908 				}
       
   909 			group->QueueMessageL(pData.SendMessageToWindowGroup->uid, pData.SendMessageToWindowGroup->dataLength,* this);
       
   910 			}
       
   911 			break;
       
   912 		case EWsClOpSendMessageToAllWindowGroups:
       
   913 		case EWsClOpSendMessageToAllWindowGroupsPriority:
       
   914 			{
       
   915 			if ((pData.SendMessageToWindowGroup->dataLength<0) || (pData.SendMessageToWindowGroup->dataLength>=(KMaxTInt/2)))
       
   916 				{
       
   917 				User::Leave(KErrArgument);
       
   918 				}
       
   919 			CWsWindowGroup::SendMessageToAllGroupsL(*this,aOpcode==EWsClOpSendMessageToAllWindowGroups,*pData.SendMessageToWindowGroup);
       
   920 			}
       
   921 			break;
       
   922 		case EWsClOpFetchMessage:
       
   923 			CWsWindowGroup::WindowGroupFromIdentifierL(pData.FetchMessage->windowGroupIdentifier)->FetchMessageL();
       
   924 			break;
       
   925 		case EWsClOpGetWindowGroupNameFromIdentifier:
       
   926 			ReplyGroupName(CWsWindowGroup::WindowGroupFromIdentifierL(pData.GetWindowGroupNameFromIdentifier->identifier)->GroupName(),pData.GetWindowGroupNameFromIdentifier->maxLength);
       
   927 			break;
       
   928 		case EWsClOpFindWindowGroupIdentifier:
       
   929 			{
       
   930 			if (pData.FindWindowGroupIdentifier->length<0)
       
   931 				User::Leave(KErrArgument);
       
   932 			TPtrC ptr(BufferTPtr((TText*)(pData.FindWindowGroupIdentifier+1),pData.FindWindowGroupIdentifier->length));
       
   933 			SetReply(CWsWindowGroup::FindWindowGroupL(this, pData.FindWindowGroupIdentifier->identifier,
       
   934 							pData.FindWindowGroupIdentifier->offset,&ptr,NULL)->Identifier());
       
   935 			}
       
   936 			break;
       
   937 		case EWsClOpFindWindowGroupIdentifierThread:
       
   938 			SetReply(CWsWindowGroup::FindWindowGroupL(this, pData.FindWindowGroupIdentifierThread->identifier,0,NULL,
       
   939 											&pData.FindWindowGroupIdentifierThread->threadId)->Identifier());
       
   940 			break;
       
   941 		case EWsClOpSetBackgroundColor:
       
   942 			for(TInt i=0;i<CWsTop::NumberOfScreens();i++)
       
   943 				{
       
   944 				CWsTop::Screen(i)->RootWindow()->SetColor(*pData.rgb);
       
   945 				}
       
   946 			break;
       
   947 		case EWsClOpGetBackgroundColor:
       
   948 			SetReply(iScreen->RootWindow()->BackColor().Internal());
       
   949 			break;
       
   950 		case EWsClOpClaimSystemPointerCursorList:
       
   951 			{
       
   952 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::ClaimSystemPointerCursorList API")))
       
   953 				{
       
   954 				User::Leave(KErrPermissionDenied);
       
   955 				}
       
   956 			ClaimSystemPointerCursorListL();
       
   957 			}
       
   958 			break;
       
   959 		case EWsClOpFreeSystemPointerCursorList:
       
   960 			FreeSystemPointerCursorList();
       
   961 			break;
       
   962 		case EWsClOpSetSystemPointerCursor:
       
   963 			{
       
   964 			CWsObject* pointercursor = NULL;
       
   965 			if ((pointercursor=HandleToObj(pData.SetSystemPointerCursor->handle, WS_HANDLE_POINTER_CURSOR))==NULL)
       
   966 				PPanic(EWservPanicSprite);
       
   967 			
       
   968 			SetSystemPointerCursorL(pData.SetSystemPointerCursor->number, (CWsPointerCursor* )pointercursor);
       
   969 			}
       
   970 			break;
       
   971 		case EWsClOpClearSystemPointerCursor:
       
   972 			ClearSystemPointerCursor(*pData.Int);
       
   973 			break;
       
   974 		case EWsClOpSetPointerCursorArea:
       
   975 			{
       
   976 			if(KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorArea API")))
       
   977 				{
       
   978 				if (!iScreen->IsValidScreenSizeMode(*pData.Int))
       
   979 					PPanic(EWservPanicScreenModeNumber);
       
   980 				iScreen->SetPointerCursorArea(pData.SetPointerCursorArea->mode,pData.SetPointerCursorArea->area);
       
   981 				}
       
   982 			}
       
   983 			break;
       
   984 		case EWsClOpPointerCursorArea:
       
   985 			if (!iScreen->IsValidScreenSizeMode(*pData.Int))
       
   986 				PPanic(EWservPanicScreenModeNumber);
       
   987 			
       
   988 			ReplyRect(iScreen->GetPointerCursorArea(*pData.Int));
       
   989 			break;
       
   990 		case EWsClOpSetPointerCursorMode:
       
   991 			{
       
   992 			CWsWindowGroup* focusWinGp=CWsTop::FocusWindowGroup();
       
   993 			if (focusWinGp && focusWinGp->WsOwner()==this)
       
   994 				{
       
   995 				TWsPointer::SetPointerCursorMode(*pData.Mode);
       
   996 				TWsPointer::UpdatePointerCursor();
       
   997 				}
       
   998 			}
       
   999 			break;
       
  1000 		case EWsClOpSetClientCursorMode :
       
  1001 			{
       
  1002 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorModeIfFocused API")))
       
  1003 				{
       
  1004 				User::Leave(KErrPermissionDenied);
       
  1005 				}
       
  1006 			TWsPointer::SetPointerCursorMode(*pData.Mode);
       
  1007 			TWsPointer::UpdatePointerCursor();
       
  1008 			}
       
  1009 			break;
       
  1010 		case EWsClOpPointerCursorMode:
       
  1011 			SetReply(TWsPointer::PointerCursorMode());
       
  1012 			break;
       
  1013 		case EWsClOpSetDefaultSystemPointerCursor:
       
  1014 			SetDefaultSystemPointerCursor(*pData.Int);
       
  1015 			break;
       
  1016 		case EWsClOpClearDefaultSystemPointerCursor:
       
  1017 			SetDefaultSystemPointerCursor(ENoDefaultSystemPointerCursor);
       
  1018 			break;
       
  1019 		case EWsClOpSetPointerCursorPosition:
       
  1020 			{
       
  1021 			CWsWindowGroup* focusWinGp=CWsTop::FocusWindowGroup();
       
  1022 			if ((!focusWinGp || focusWinGp->WsOwner()!=this)&&
       
  1023 				(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetPointerCursorPosition API"))))
       
  1024 				{
       
  1025 				User::Leave(KErrPermissionDenied);
       
  1026 				}
       
  1027 			TWsPointer::SetPointerCursorPos(*pData.Point);
       
  1028 			}
       
  1029 			break;
       
  1030 		case EWsClOpPointerCursorPosition:
       
  1031 			ReplyPoint(TWsPointer::PointerCursorPos());
       
  1032 			break;
       
  1033 		case EWsClOpSetModifierState:
       
  1034 			{
       
  1035 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetModifierState API")))
       
  1036 				{
       
  1037 				User::Leave(KErrPermissionDenied);
       
  1038 				}
       
  1039 			TWindowServerEvent::SetModifierState(pData.SetModifierState->modifier,pData.SetModifierState->state);
       
  1040 			}
       
  1041 			break;
       
  1042 		case EWsClOpGetModifierState:
       
  1043 			SetReply(TWindowServerEvent::GetModifierState());
       
  1044 			break;
       
  1045 		case EWsClOpHeapCount:
       
  1046 			SetReply(CWsMemoryManager::Static()->Count());
       
  1047 			break;
       
  1048  		case EWsClOpDebugInfo:
       
  1049 			DebugInfoL(pData.DebugInfo->iFunction,pData.DebugInfo->iParam,EFalse);
       
  1050  			break;
       
  1051  		case EWsClOpDebugInfoReplyBuf:
       
  1052 			DebugInfoL(pData.DebugInfo->iFunction,pData.DebugInfo->iParam,ETrue);
       
  1053  			break;
       
  1054 		case EWsClOpResourceCount:
       
  1055 			SetReply(iObjectIndex->Count());
       
  1056 			break;
       
  1057 		case EWsClOpHeapSetFail:
       
  1058 			{
       
  1059 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::HeapSetFail API")))
       
  1060 				{
       
  1061 				PPanic(EWservPanicPermissionDenied);
       
  1062 				}
       
  1063 #if !defined(_DEBUG)
       
  1064 			if (pData.HeapSetFail->type!=RHeap::ENone)
       
  1065 				TWindowServerEvent::NotifyOom();
       
  1066 #endif
       
  1067 			// if there is a memory manager and we are making the allocator fail next or 
       
  1068 			// deteministic we want to make sure we test both when the memory manager
       
  1069 			// succeeds and fails in allocating after freeing up memory. we do that by
       
  1070 			// remapping the rate and explicitly telling the memory manager to fail:
       
  1071 			// requested rate  | fail on retry, actual rate
       
  1072 			//        1        |    true      ,    1
       
  1073 			//        2        |    false     ,    1
       
  1074 			//        3        |    true      ,    2
       
  1075 			CWsMemoryManager* memoryManager = NULL;
       
  1076 			TInt rate = pData.HeapSetFail->value;
       
  1077 			TBool memoryManagerRetryFail = EFalse;
       
  1078 			if((pData.HeapSetFail->type == RAllocator::EFailNext || pData.HeapSetFail->type == RAllocator::EDeterministic))
       
  1079 				{
       
  1080 				memoryManager = CWsMemoryManager::Static();
       
  1081 				if(memoryManager)
       
  1082 					{
       
  1083 					memoryManagerRetryFail = (rate % 2 == 1);
       
  1084 					rate = rate / 2 + (memoryManagerRetryFail ? 1 : 0);
       
  1085 					}
       
  1086 				}
       
  1087 
       
  1088 			switch (pData.HeapSetFail->type)
       
  1089 				{	//This log message means you can safely ignore the allocation failures in between
       
  1090 					//see CWindowServer::ReleaseMemory()
       
  1091 				case RAllocator::ENone:
       
  1092 					RDebug::Printf("WSERV Heap: __DbgSetAllocFail() <<<ENone");
       
  1093 					break;
       
  1094 				case RAllocator::EReset:
       
  1095 					RDebug::Printf("WSERV Heap: __DbgSetAllocFail() <<<EReset");
       
  1096 					break;
       
  1097 				default:	
       
  1098 					if (memoryManagerRetryFail)
       
  1099 						RDebug::Printf("WSERV Heap: Memory Manager set to fail on retry");
       
  1100 					RDebug::Printf("WSERV Heap: __DbgSetAllocFail(EUser,%i,%i)>>>", pData.HeapSetFail->type, rate);
       
  1101 					break;
       
  1102 				}
       
  1103 
       
  1104 			if (memoryManager && memoryManagerRetryFail)
       
  1105 				memoryManager->SetFailNextRetry();
       
  1106 			
       
  1107 			if (pData.HeapSetFail->burst >= 0)
       
  1108 				User::__DbgSetBurstAllocFail(RHeap::EUser, pData.HeapSetFail->type, rate, pData.HeapSetFail->burst);
       
  1109 			else
       
  1110 				User::__DbgSetAllocFail(RHeap::EUser, pData.HeapSetFail->type, rate);
       
  1111 			break;
       
  1112 			}
       
  1113 		case EWsClOpRawEvent:
       
  1114 			{
       
  1115 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SimulateRawEvent API")))
       
  1116 				{
       
  1117 				PPanic(EWservPanicPermissionDenied);
       
  1118 				}
       
  1119 			TRawEvent event(*pData.RawEvent);
       
  1120 			if (TWsPointer::PreProcessDriverEvent(event))
       
  1121 				TWindowServerEvent::ProcessRawEvent(event);
       
  1122 			}
       
  1123 			break;
       
  1124 		case EWsClOpKeyEvent:
       
  1125 			{
       
  1126 			if(!KSecurityPolicy_SwEvent().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SimulateKeyEvent API")))
       
  1127 				{
       
  1128 				PPanic(EWservPanicPermissionDenied);
       
  1129 				}
       
  1130 			TWindowServerEvent::ProcessKeyEvent(*pData.KeyEvent,0);
       
  1131 			}
       
  1132 			break;
       
  1133 		case EWsClOpLogMessage:
       
  1134 			if (wsDebugLog)
       
  1135 				{
       
  1136 				if (CheckBuffer(*pData.Int, KLogMessageLength))
       
  1137 					wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,BufferTPtr((TText* )(pData.Int+1),*pData.Int),0);
       
  1138 				}
       
  1139 			break;
       
  1140 		case EWsClOpPasswordEntered:
       
  1141 			CWsPassword::PasswordEntered(this);
       
  1142 			break;
       
  1143 		case EWsClOpComputeMode:
       
  1144 			SetComputeMode(*pData.ComputeMode);
       
  1145 			break;
       
  1146 		case EWsClOpSendOffEventsToShell:
       
  1147 			{
       
  1148 			if(!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::RequestOffEvents API")))
       
  1149 				{
       
  1150 				User::Leave(KErrPermissionDenied);
       
  1151 				}
       
  1152 			SetReply(CWsTop::SetSendOffEventsToShell(this,*pData.OffEventsToShell));
       
  1153 			}
       
  1154 			break;
       
  1155 		case EWsClOpGetDefModeMaxNumColors:
       
  1156 			{
       
  1157 			SDefModeMaxNumColors colors;
       
  1158 			const TInt screenNumber = *pData.Int;
       
  1159 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
  1160 				PPanic(EWservPanicScreenNumber);
       
  1161 			else
       
  1162 				{
       
  1163 				CScreen* screen = (screenNumber==KDummyScreenNumber)?iScreen:CWsTop::Screen(screenNumber);
       
  1164 				screen->MaxNumColors(colors.iColors,colors.iGrays);
       
  1165 				colors.iDisplayMode=screen->FirstDefaultDisplayMode();
       
  1166 				}
       
  1167 			ReplyBuf(&colors,sizeof(colors));
       
  1168 			}
       
  1169 			break;
       
  1170 		case EWsClOpGetColorModeList:
       
  1171 			{
       
  1172 			const TInt screenNumber = *pData.Int;
       
  1173 			if (screenNumber<KDummyScreenNumber || screenNumber>=CWsTop::NumberOfScreens())
       
  1174 				PPanic(EWservPanicScreenNumber);
       
  1175 			else
       
  1176 				SetReply((screenNumber==KDummyScreenNumber) ? iScreen->ColorModesFlag() : CWsTop::Screen(screenNumber)->ColorModesFlag());
       
  1177 			}
       
  1178 			break;
       
  1179 		case EWsClOpSetDefaultFadingParams:
       
  1180 			{
       
  1181 			if(KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetDefaultFadingParameters API")))
       
  1182 				{
       
  1183 				iScreen->SetFadingParams(WservEncoding::ExtractFirst8BitValue(*pData.UInt),WservEncoding::ExtractSecond8BitValue(*pData.UInt));
       
  1184 				}
       
  1185 			}
       
  1186 			break;
       
  1187 		case EWsClOpPrepareForSwitchOff:
       
  1188 			{
       
  1189 			if(KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::PrepareForSwitchOff API")))
       
  1190 				{
       
  1191 				}
       
  1192 			}
       
  1193 			break;
       
  1194 		case EWsClOpSetFaded:
       
  1195 			{
       
  1196 			// Deprecated - retained for BC with applications that retrieve the fade count
       
  1197 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetSystemFaded API")))
       
  1198 				User::Leave(KErrPermissionDenied);
       
  1199 
       
  1200 			TUint8 blackMap;
       
  1201 			TUint8 whiteMap;
       
  1202 			if (pData.SetSystemFaded->UseDefaultMap())
       
  1203 				iScreen->GetFadingParams(blackMap,whiteMap);
       
  1204 			else
       
  1205 				pData.SetSystemFaded->GetFadingParams(blackMap,whiteMap);
       
  1206 			
       
  1207 			iScreen->RootWindow()->SetSystemFaded(pData.SetSystemFaded->Faded(),blackMap,whiteMap);
       
  1208 			}
       
  1209 		break;
       
  1210 		case EWsClOpLogCommand:
       
  1211 			CWsTop::LogCommand(*pData.LogCommand);
       
  1212 			break;
       
  1213 #if defined(__WINS__)
       
  1214 		case EWsClOpRemoveKeyCode:
       
  1215 			iInternalFlags&=~ERemoveKeyCode;
       
  1216 			if (*pData.Bool)
       
  1217 				iInternalFlags|=ERemoveKeyCode;
       
  1218 			break;
       
  1219 		case EWsClOpSimulateXyInput:
       
  1220 			TWsPointer::SetXyInputType(*pData.XyInput);
       
  1221 			break;
       
  1222 #endif
       
  1223 		case EWsClOpNoFlickerFree:
       
  1224 			PPanic(EWservPanicOpcode); //not supported anymore
       
  1225 			break;
       
  1226 		case EWsClOpSetFocusScreen:
       
  1227 			{
       
  1228 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetFocusScreen API")))
       
  1229 				{
       
  1230 				User::Leave(KErrPermissionDenied);
       
  1231 				}
       
  1232 			TInt focusScreen=*pData.Int;
       
  1233 			if (focusScreen>=0 && focusScreen<CWsTop::NumberOfScreens())
       
  1234 				SetReply(CWsTop::SetCurrentFocusScreen(focusScreen));
       
  1235 			else
       
  1236 				SessionPanic(EWservPanicScreenNumber);
       
  1237 			break;
       
  1238 			}
       
  1239 		case EWsClOpGetFocusScreen:
       
  1240 			SetReply(CWsTop::CurrentFocusScreen()->ScreenNumber());
       
  1241 			break;
       
  1242 		case EWsClOpGetNumberOfScreens:
       
  1243 			SetReply(CWsTop::NumberOfScreens());
       
  1244 			break;
       
  1245 		case EWsClOpClearAllRedrawStores:
       
  1246 			CWsTop::ClearAllRedrawStores();
       
  1247 			break;
       
  1248 		case EWsClOpGetGraphicMessage:
       
  1249 			iGraphicMessageQueue.GetGraphicMessage();
       
  1250 			break;
       
  1251 		case EWsClOpGraphicMessageCancel:
       
  1252 			iGraphicMessageQueue.CancelRead();
       
  1253 			break;
       
  1254 		case EWsClOpGraphicAbortMessage:
       
  1255 			iGraphicMessageQueue.AbortMessage(*pData.Int);
       
  1256 			break;
       
  1257 		case EWsClOpGraphicFetchHeaderMessage:
       
  1258 			SetReply(iGraphicMessageQueue.TopClientHandle());
       
  1259 			break;
       
  1260 		case EWsClOpRegisterSurface:
       
  1261 			SetReply(RegisterSurface(pData));
       
  1262 			break;
       
  1263 		case EWsClOpUnregisterSurface:
       
  1264 			UnregisterSurface(pData);
       
  1265 			break;
       
  1266 		case EWsClOpSetCloseProximityThresholds:
       
  1267 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),
       
  1268 					__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetCloseProximityThresholds")))
       
  1269 				{
       
  1270 				User::Leave(KErrPermissionDenied);
       
  1271 				}
       
  1272 			SetReply(TWsPointer::SetCloseProximityThresholds(pData.ZThresholdPair->enterThreshold,
       
  1273 															 pData.ZThresholdPair->exitThreshold));
       
  1274 			break;
       
  1275 		case EWsClOpSetHighPressureThresholds:
       
  1276 			if(!KSecurityPolicy_WriteDeviceData().CheckPolicy(ClientMessage(),
       
  1277 					__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::SetHighPressureThresholds")))
       
  1278 				{
       
  1279 				User::Leave(KErrPermissionDenied);
       
  1280 				}
       
  1281 			SetReply(TWsPointer::SetHighPressureThresholds(pData.ZThresholdPair->enterThreshold,
       
  1282 					 									   pData.ZThresholdPair->exitThreshold));
       
  1283 			break;
       
  1284 		case EWsClOpGetEnterCloseProximityThreshold:
       
  1285 			SetReply(TWsPointer::GetEnterCloseProximityThreshold());
       
  1286 			break;
       
  1287 		case EWsClOpGetExitCloseProximityThreshold:
       
  1288 			SetReply(TWsPointer::GetExitCloseProximityThreshold());
       
  1289 			break;
       
  1290 		case EWsClOpGetEnterHighPressureThreshold:
       
  1291 			SetReply(TWsPointer::GetEnterHighPressureThreshold());
       
  1292 			break;
       
  1293 		case EWsClOpGetExitHighPressureThreshold:
       
  1294 			SetReply(TWsPointer::GetExitHighPressureThreshold());
       
  1295 			break;
       
  1296 		case EWsClOpCreateDrawableSource:
       
  1297 			CreateDrawableSourceL(*pData.CreateDrawableSource);
       
  1298 			break;
       
  1299 		default:
       
  1300 			PPanic(EWservPanicOpcode);
       
  1301 			break;
       
  1302 		}
       
  1303 	}
       
  1304 /**	Debug information accessor.
       
  1305  * 	
       
  1306  * 
       
  1307  **/
       
  1308 void CWsClient::DebugInfoL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const
       
  1309 	{
       
  1310 	if (aFunction & EWsDebugClassMask)
       
  1311 		SetReply(DebugInfoClassifiedL(aFunction,aParam,aHasReplyBuf));
       
  1312 	else
       
  1313 		DebugInfoUnclassifiedL(aFunction,aParam,aHasReplyBuf);
       
  1314 	}
       
  1315 
       
  1316 /**	A wide variety of generally unconnected debug enquiries.
       
  1317  * 
       
  1318  * 
       
  1319  **/
       
  1320 void CWsClient::DebugInfoUnclassifiedL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const
       
  1321 	{
       
  1322 	switch(aFunction)
       
  1323 		{
       
  1324 		case EWsDebugInfoHeap:
       
  1325 			if (aHasReplyBuf)
       
  1326 				{
       
  1327 				TWsDebugHeapInfo heapInfo;
       
  1328 				RHeap& heap=User::Heap();
       
  1329 				heapInfo.iCount=heap.AllocSize(heapInfo.iTotal);
       
  1330 				heapInfo.iAvailable=heap.Available(heapInfo.iLargestAvailable);
       
  1331 				ReplyBuf(&heapInfo,sizeof(heapInfo));
       
  1332 				}
       
  1333 			SetReply(KErrArgument);
       
  1334 			break;
       
  1335 		case EWsDebugSetCheckHeapOnDisconnectClient:
       
  1336 			if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::DebugInfo API")))
       
  1337 				{
       
  1338 				User::Leave(KErrPermissionDenied);
       
  1339 				}
       
  1340 			CWsTop::SetCheckHeapOnDisconnectClient(this);
       
  1341 			break;
       
  1342 		case EWsDebugSetCheckHeapOnDisconnectMode:
       
  1343 			if (!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for RWsSession::DebugInfo API")))
       
  1344 				{
       
  1345 				User::Leave(KErrPermissionDenied);
       
  1346 				}
       
  1347 			CWsTop::SetCheckHeapOnDisconnectMode(STATIC_CAST(TWsCheckHeapOnDisconnectMode,aParam));
       
  1348 			break;
       
  1349 		case EWsDebugFetchCheckHeapResult:
       
  1350 			SetReply(CWsTop::FetchCheckHeapResult());
       
  1351 			break;
       
  1352 		case EWsDebugSetEventQueueTest:
       
  1353 			CWsWindowGroup::SetEventQueueTestState(aParam);
       
  1354 			break;
       
  1355 		default:
       
  1356 			SetReply(KErrNotSupported);
       
  1357 			break;
       
  1358 		}
       
  1359 	}
       
  1360 	
       
  1361 /**	Selects a debug function based on the class of debug query.
       
  1362  * 
       
  1363  * 
       
  1364  **/
       
  1365 TInt CWsClient::DebugInfoClassifiedL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const
       
  1366 	{//Duplicating the meanings of Classified... this would be a good place for a security check
       
  1367 	//first part of param is always screen number
       
  1368 	TInt buffSpace=aHasReplyBuf?ReplyBufSpace():0;
       
  1369 	if (buffSpace<0)
       
  1370 		return (buffSpace);
       
  1371 		
       
  1372 	const TInt screenNumber = (aParam&EWsDebugArgScreenMask)>>EWsDebugArgScreenShift;
       
  1373 	const TInt functionClass = (aFunction&EWsDebugClassMask);
       
  1374 	CScreen* screen = NULL;
       
  1375 	if (functionClass<EWsDebugClassNonScreen)
       
  1376 		{
       
  1377 		if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
  1378 			return (KErrArgument);
       
  1379 
       
  1380 		screen = CWsTop::Screen(screenNumber);
       
  1381 		}
       
  1382 	WS_ASSERT_DEBUG(screen, EWsPanicNoScreen);
       
  1383 	switch (aFunction&EWsDebugClassMask)
       
  1384 		{
       
  1385 		case EWsDebugClassScreenUiElement:
       
  1386 			return DebugInfoScreenUiL(aFunction,aParam,buffSpace,*screen);
       
  1387 		case EWsDebugClassScreenElementSet:
       
  1388 			return DebugInfoScreenElementSetL(aFunction, aParam, buffSpace, *screen);
       
  1389 		case EWsDebugClassElementSetWindow:
       
  1390 			return DebugInfoElementSetWindowL(aFunction, aParam, buffSpace, *screen);
       
  1391 		case EWsDebugClassElementSetElement:
       
  1392 			return DebugInfoElementSetElementL(aFunction, aParam, buffSpace, *screen);
       
  1393 
       
  1394 		case EWsDebugClassClientWindow:
       
  1395 		default:
       
  1396 			return (KErrNotSupported);
       
  1397 		}
       
  1398 	}
       
  1399 
       
  1400 /**	Returns debug info about the UIElement entries for a screen.
       
  1401  * 	This describes the general state or size of the element set.
       
  1402  * 	It is indexed via screen num, and optionally element index.
       
  1403  * 	Element index MUST BE 0 when not required.
       
  1404  * 	@return size of buffer required or error code.
       
  1405  **/
       
  1406 TInt CWsClient::DebugInfoScreenUiL(TInt aFunction, TInt /* aParam */, TInt aReplyBufSize, CScreen& aScreen) const
       
  1407 	{
       
  1408 	switch(aFunction)
       
  1409 		{
       
  1410 		case EWsDebugGetFastpathMode:
       
  1411 			{
       
  1412 			// obsolete through preq2669
       
  1413             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1414 			return KErrNotSupported;
       
  1415 			}
       
  1416 			
       
  1417 		case EWsDebugSetFastpathMode:
       
  1418 			{
       
  1419             // obsolete through preq2669
       
  1420             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1421             return KErrNotSupported;
       
  1422 			}
       
  1423 			
       
  1424 		case EWsDebugGetUIElementInfoList:
       
  1425 			{
       
  1426             // obsolete through preq2669
       
  1427             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1428             return KErrNotSupported;
       
  1429 			}
       
  1430 			
       
  1431 		case EWsDebugGetUIElementBase:
       
  1432 			{
       
  1433             // obsolete through preq2669
       
  1434             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1435             return KErrNotSupported;
       
  1436 			}
       
  1437 
       
  1438 		case EWsDebugGetUIElementIds:
       
  1439 			{
       
  1440             // obsolete through preq2669
       
  1441             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1442             return KErrNotSupported;
       
  1443 			}
       
  1444 
       
  1445 		case EWsDebugGetSceneElementIdOrder:
       
  1446 			{
       
  1447             // obsolete through preq2669
       
  1448             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1449             return KErrNotSupported;
       
  1450 			}
       
  1451 		case EWsDebugSetFastpathTestMode:
       
  1452 			{
       
  1453             // obsolete through preq2669
       
  1454             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1455             return KErrNotSupported;
       
  1456 			}
       
  1457 			
       
  1458 		case EWsDebugSetFastpathOomMode:
       
  1459 			{
       
  1460             // obsolete through preq2669
       
  1461             WS_ASSERT_DEBUG(EFalse, EWsPanicDrawCommandsInvalidState);
       
  1462             return KErrNotSupported;
       
  1463 			}
       
  1464 		case EWsDebugGetUIElementConfig:
       
  1465 			{
       
  1466 			return DebugReturnConfig(aReplyBufSize,&aScreen.UiElement(),0);
       
  1467 
       
  1468 			}
       
  1469 		default:
       
  1470 			return (KErrNotSupported);
       
  1471 		}
       
  1472 	}
       
  1473 
       
  1474 /**	Returns debug info about the CWindowElementSet entry for a screen.
       
  1475  * 	This describes the general state or size of the element set
       
  1476  * 	It is indexed via screen num.
       
  1477  * 	@return size of buffer required or error code.
       
  1478  **/
       
  1479 TInt CWsClient::DebugInfoScreenElementSetL(TInt aFunction, TInt /*aParam*/, TInt aReplyBufSize, const CScreen& aScreen) const
       
  1480 	{
       
  1481 	const CWindowElementSet& elementSet = aScreen.WindowElements();
       
  1482 	switch (aFunction)
       
  1483 		{
       
  1484 		case EWsDebugSerialSurfacesUpdated:
       
  1485 			return 0;
       
  1486 
       
  1487 		case EWsDebugSurfaceWindowList:
       
  1488 			{
       
  1489 			TInt outSize = elementSet.Count() * sizeof(TWsDebugWindowId);
       
  1490 			if (outSize<=aReplyBufSize)
       
  1491 				{//can stream, so I shall!
       
  1492 				for (TInt index = 0; index < elementSet.Count(); index++)
       
  1493 					{
       
  1494 					const CWsClientWindow& win = *elementSet.DebugWindowAt(index);
       
  1495 					TWsDebugWindowId id=
       
  1496 						{
       
  1497 						win.ClientHandle(), 0
       
  1498 						};
       
  1499 					if (win.WsOwner()!=this)
       
  1500 						id.iOtherGroupId=win.WinGroup()->Identifier();
       
  1501 					ReplyBuf(&id, sizeof(id));
       
  1502 					}
       
  1503 				}
       
  1504 			return outSize;
       
  1505 			}
       
  1506 		default:
       
  1507 			return (KErrNotSupported);
       
  1508 
       
  1509 		}
       
  1510 	}
       
  1511 
       
  1512 /**	Returns debug info about a CWindowElement entry.
       
  1513  * 	This describes the window or the background element(s)
       
  1514  * 	It is indexed via screen num, and index in elementset.
       
  1515  * 	@return size of buffer required or error code.
       
  1516  **/
       
  1517 TInt CWsClient::DebugInfoElementSetWindowL(TInt aFunction, TInt aParam,
       
  1518 		TInt aReplyBufSize, const CScreen& aScreen) const
       
  1519 	{
       
  1520 	const CWindowElementSet& elementSet = aScreen.WindowElements();
       
  1521 	TUint winIndex = (aParam & EWsDebugArgWindowMask) >> EWsDebugArgWindowShift;
       
  1522 	const TAttributes* winElement = elementSet.DebugBackgroundAt(winIndex);
       
  1523 	if (winElement == NULL)
       
  1524 		{
       
  1525 		return KErrArgument;
       
  1526 		}
       
  1527 
       
  1528 	MWsElement* backElement = winElement->iElement;
       
  1529 	TInt placedCount = elementSet.DebugPlacedCountAt(winIndex);
       
  1530 	switch (aFunction)
       
  1531 		{
       
  1532 		case EWsDebugElementIdList:
       
  1533 			{
       
  1534 			TInt retVal = (placedCount + 1) * sizeof(MWsElement*);
       
  1535 			if (retVal<aReplyBufSize)
       
  1536 				{
       
  1537 				ReplyBuf(&backElement, sizeof(MWsElement*));
       
  1538 				for (TInt index=0; index<placedCount; index++)
       
  1539 					ReplyBuf(&elementSet.DebugPlacedAt(winIndex, index)->iElement, sizeof(MWsElement*));
       
  1540 				}
       
  1541 			return retVal;
       
  1542 			}
       
  1543 		case EWsDebugBackgroundConfig:
       
  1544 			if (backElement == NULL)
       
  1545 				return KErrNotFound;
       
  1546 			else
       
  1547 				return DebugReturnConfig(aReplyBufSize, backElement,
       
  1548 						winElement->DebugFlags());
       
  1549 		case EWsDebugBackgroundBase:
       
  1550 			if (backElement == NULL)
       
  1551 				return KErrNotFound;
       
  1552 			else
       
  1553 				return DebugReturnBase(aReplyBufSize, backElement);
       
  1554 		case EWsDebugBackgroundFlags:
       
  1555 			return DebugReturnFlags(aReplyBufSize, backElement,
       
  1556 					winElement->DebugFlags());
       
  1557 		default:
       
  1558 			return KErrNotSupported;
       
  1559 		//This method can also be extended to return region and state information from the associated window
       
  1560 		}
       
  1561 	}
       
  1562 
       
  1563 /**	Returns debug info about a placed element.
       
  1564  * 	It is indexed via screen num, index in elementset, and index in placed element array.
       
  1565  * 	@return size of buffer required or error code.
       
  1566  **/
       
  1567 TInt CWsClient::DebugInfoElementSetElementL(TInt aFunction, TInt aParam,
       
  1568 		TInt aReplyBufSize, const CScreen& aScreen) const
       
  1569 	{
       
  1570 	const CWindowElementSet& elementSet = aScreen.WindowElements();
       
  1571 	TUint winIndex = (aParam & EWsDebugArgWindowMask) >> EWsDebugArgWindowShift;
       
  1572 	TUint placeIndex = (aParam & EWsDebugArgElementMask) >> EWsDebugArgElementShift;
       
  1573 	const TAttributes* placedElement = elementSet.DebugPlacedAt(winIndex, placeIndex);
       
  1574 	if (placedElement == NULL)
       
  1575 		{
       
  1576 		return KErrArgument;
       
  1577 		}
       
  1578 
       
  1579 	MWsElement* element = placedElement->iElement;
       
  1580 	if (element == NULL)
       
  1581 		{
       
  1582 		return KErrNotFound;
       
  1583 		}
       
  1584 
       
  1585 	switch (aFunction)
       
  1586 		{
       
  1587 		case EWsDebugPlacedConfig:
       
  1588 			return DebugReturnConfig(aReplyBufSize, element,
       
  1589 					placedElement->DebugFlags());
       
  1590 		case EWsDebugPlacedBase:
       
  1591 			return DebugReturnBase(aReplyBufSize, element);
       
  1592 		case EWsDebugPlacedFlags:
       
  1593 			return DebugReturnFlags(aReplyBufSize, element,
       
  1594 					placedElement->DebugFlags());
       
  1595 		default:
       
  1596 			return KErrNotSupported;
       
  1597 		}
       
  1598 	}
       
  1599 
       
  1600 /**	Returns a filled in TSurfaceConfiguration from an MWsElement.
       
  1601  * 	Data is usually copied if the buffer is big enough
       
  1602  * 	@return the size of buffer required, or zero if the buffer is acceptable
       
  1603  **/
       
  1604 TInt CWsClient::DebugReturnConfig(TInt aReplyBufSize, MWsElement* aElement, TInt /*aFlags*/) const
       
  1605 	{
       
  1606 	if (aElement == NULL)
       
  1607 		{
       
  1608 		return KErrNotReady;
       
  1609 		}
       
  1610 
       
  1611 	TSurfaceConfiguration config(aReplyBufSize);
       
  1612 	TInt retVal=config.Size();
       
  1613 	if (aReplyBufSize)
       
  1614 		{
       
  1615 		retVal = CWindowElementSet::GetConfiguration(config, *aElement);
       
  1616 		if (retVal==KErrNone)
       
  1617 			{
       
  1618 			ReplyBuf(&config, config.Size()); //return code is 0 = "just right"
       
  1619 			}
       
  1620 		}
       
  1621 	return retVal;
       
  1622 	}
       
  1623 
       
  1624 /**	Returns the base region of the element.
       
  1625  * 	This region is element relative. There are a number of ways that this does not match the input region:
       
  1626  * 	First, if no region is specified then the extent rectangle is returned
       
  1627  * 	Any region returned has all negative ordinate values clipped. 
       
  1628  * 	Positive values may exceed the extent, but negative values are never returned. 
       
  1629  *  Internally, a region which is only negative is "remembered illegally", but an empty region is returned.
       
  1630  **/
       
  1631 TInt CWsClient::DebugReturnBase(TInt /*aReplyBufSize*/, const MWsElement* /*aElement*/)const
       
  1632 	{
       
  1633 	return KErrNotSupported;
       
  1634 	}
       
  1635 
       
  1636 /**	Returns the flags associated with the given element.
       
  1637  * 	2 words are inserted.
       
  1638  * 	One represents the MWsElement flags, the other represents CWindowElement or UIElement flags
       
  1639  * 	@return length of two words
       
  1640  **/
       
  1641 TInt CWsClient::DebugReturnFlags(TInt aReplyBufSize, const MWsElement* /*aElement*/, TInt aFlags)const
       
  1642 	{
       
  1643 	const TInt KArraySize=2;
       
  1644 	if (aReplyBufSize>KArraySize*sizeof(TInt))
       
  1645 		{
       
  1646 		// First field is for flags from scene element if any
       
  1647 		TInt returns[KArraySize]=
       
  1648 			{
       
  1649 			0, aFlags
       
  1650 			};
       
  1651 		ReplyBuf(returns,KArraySize*sizeof(TInt));
       
  1652 		}
       
  1653 	return KArraySize*sizeof(TInt);
       
  1654 	}
       
  1655 
       
  1656 /**	Packages a region for return ans an array of rectangles.
       
  1657  * 	If the buffer is big enough the data is transferred
       
  1658  * 	@return the buffer size required, or an error code if an empty or null pointer is passed in
       
  1659  **/
       
  1660 TInt CWsClient::DebugReturnRegion(TInt aReplyBufSize, const TRegion* aRegion, TInt aErrCodeIfEmpty)const
       
  1661 	{
       
  1662 	if (aRegion==NULL)
       
  1663 		return KErrNotReady;
       
  1664 	
       
  1665 	const TInt returnSize=aRegion->Count()*sizeof(TRect);
       
  1666 	if (returnSize==0)
       
  1667 		return aErrCodeIfEmpty;
       
  1668 	
       
  1669 	if (returnSize<=aReplyBufSize)
       
  1670 		ReplyBuf(aRegion->RectangleList(),returnSize);
       
  1671 	
       
  1672 	return returnSize;
       
  1673 	}
       
  1674 
       
  1675 void CWsClient::ReplyGroupName(HBufC* aName, TInt aMaxLength)	// static
       
  1676 	{
       
  1677 	if (aName)
       
  1678 		{
       
  1679 		if (aName->Length()>aMaxLength)
       
  1680 			{
       
  1681 			ReplyBuf(aName->Left(aMaxLength));
       
  1682 			SetReply(KErrOverflow);
       
  1683 			}
       
  1684 		else
       
  1685 			ReplyBuf(*aName);
       
  1686 		}
       
  1687 	else
       
  1688 		ReplyBuf(KNullDesC);
       
  1689 	}
       
  1690 
       
  1691 void CWsClient::TriggerRedraw()
       
  1692 	{
       
  1693 	RedrawQueue()->TriggerRedraw();
       
  1694 	}
       
  1695 
       
  1696 void CWsClient::UpdateWindowOrdinalPrioritys()
       
  1697 	{
       
  1698 	for(CWsWindowGroup* win=iScreen->RootWindow()->Child();win;win=win->NextSibling())
       
  1699 		{
       
  1700 		if (win->WsOwner()==this)
       
  1701 			win->UpdateOrdinalPriority(ETrue);
       
  1702 		}
       
  1703 	}
       
  1704 
       
  1705 void CWsClient::DeleteSystemPointerListEntry(TInt aIndex)
       
  1706 	{
       
  1707 	PointerCursor (aIndex)->Close();
       
  1708 	iSystemPointerCursors->Delete(aIndex);
       
  1709 	}
       
  1710 
       
  1711 CWsPointerCursor* CWsClient::SystemPointerCursor(TInt aIndex)
       
  1712 	{
       
  1713 	TInt arrayIndex;
       
  1714 	if (iSystemPointerCursors)
       
  1715 		{
       
  1716 		if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1717 			return PointerCursor(arrayIndex);
       
  1718 
       
  1719 		// Cursor not defined so try for default cursor
       
  1720 		if (FindCursorArrayItem(iSystemPointerCursors, 0, arrayIndex))
       
  1721 			return PointerCursor(arrayIndex);
       
  1722 		}
       
  1723 
       
  1724 	// If that fails simply return NULL for no cursor
       
  1725 	return NULL;
       
  1726 	}
       
  1727 
       
  1728 void CWsClient::SetSystemPointerCursorL(TInt aIndex, CWsPointerCursor* aCursor)
       
  1729 	{
       
  1730 	if (iSystemPointerCursorListOwner!=this)
       
  1731 		PPanic(EWservPanicNotSystemPointerCursorListOwner);
       
  1732 	
       
  1733 	TInt arrayIndex = KErrNotFound;
       
  1734 	if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1735 		{
       
  1736 		PointerCursor(arrayIndex)->Close();
       
  1737 		PointerCursor(arrayIndex) = aCursor;
       
  1738 		}
       
  1739 	else
       
  1740 		{
       
  1741 		TWsCursorArrayItem entry;
       
  1742 		entry.iIndex=aIndex;
       
  1743 		entry.iCursor=aCursor;
       
  1744 		iSystemPointerCursors->InsertIsqL(entry, iCursorKey);
       
  1745 		}
       
  1746 	
       
  1747 	aCursor->Open();
       
  1748 	if (aIndex==iDefaultSystemPointerCursorIndex)
       
  1749 		iDefaultSystemPointerCursor=aCursor;
       
  1750 	TWsPointer::UpdatePointerCursor();
       
  1751 	}
       
  1752 
       
  1753 void CWsClient::ClearSystemPointerCursor(TInt aIndex)
       
  1754 	{
       
  1755 	if (iSystemPointerCursorListOwner!=this)
       
  1756 		PPanic(EWservPanicNotSystemPointerCursorListOwner);
       
  1757 	
       
  1758 	TInt arrayIndex;
       
  1759 	if (FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1760 		{
       
  1761 		DeleteSystemPointerListEntry(arrayIndex);
       
  1762 		if (aIndex==iDefaultSystemPointerCursorIndex)
       
  1763 			iDefaultSystemPointerCursor=NULL;
       
  1764 		}
       
  1765 	}
       
  1766 
       
  1767 void CWsClient::ClaimSystemPointerCursorListL()
       
  1768 	{
       
  1769 	if (iSystemPointerCursorListOwner)
       
  1770 		User::Leave(KErrInUse);
       
  1771 	
       
  1772 	const TInt systemPointerCursorGranularity = 4;
       
  1773 	iSystemPointerCursors = new(ELeave) CArrayFixFlat<TWsCursorArrayItem> (systemPointerCursorGranularity);
       
  1774 	iSystemPointerCursorListOwner=this;
       
  1775 	}
       
  1776 
       
  1777 void CWsClient::FreeSystemPointerCursorList()
       
  1778 	{
       
  1779 	if(iSystemPointerCursorListOwner == this)
       
  1780 		{
       
  1781 		iSystemPointerCursorListOwner = NULL;
       
  1782 		
       
  1783 		while(iSystemPointerCursors->Count()>0)
       
  1784 			DeleteSystemPointerListEntry(0);
       
  1785 		
       
  1786 		iDefaultSystemPointerCursor = NULL;
       
  1787 		iDefaultSystemPointerCursorIndex = 0;
       
  1788 		
       
  1789 		delete iSystemPointerCursors;
       
  1790 		iSystemPointerCursors = NULL;
       
  1791 		}
       
  1792 	}
       
  1793 
       
  1794 void CWsClient::SetDefaultSystemPointerCursor(TInt aIndex)
       
  1795 	{
       
  1796 	TInt arrayIndex;
       
  1797 	if (iSystemPointerCursorListOwner != this)
       
  1798 		PPanic(EWservPanicNotSystemPointerCursorListOwner);
       
  1799 	
       
  1800 	iDefaultSystemPointerCursorIndex = aIndex;
       
  1801 	iDefaultSystemPointerCursor = NULL;
       
  1802 	
       
  1803 	if (aIndex != ENoDefaultSystemPointerCursor &&
       
  1804 		FindCursorArrayItem(iSystemPointerCursors, aIndex, arrayIndex))
       
  1805 		iDefaultSystemPointerCursor = PointerCursor (arrayIndex);
       
  1806 	else
       
  1807 		iDefaultSystemPointerCursor = NULL;
       
  1808 	
       
  1809 	TWsPointer::UpdatePointerCursor();
       
  1810 	}
       
  1811 
       
  1812 TBool CWsClient::FindCursorArrayItem(CArrayFixFlat<TWsCursorArrayItem>* aCursorArray,
       
  1813 									 TInt aIndex,TInt& aPosition)
       
  1814 	{
       
  1815 	if (!aCursorArray)
       
  1816 		return EFalse; // No hit if the array isn't even allocated
       
  1817 
       
  1818 	TWsCursorArrayItem entry;
       
  1819 	entry.iIndex = aIndex;
       
  1820 	return aCursorArray->FindIsq(entry, iCursorKey, aPosition)==KErrNone;
       
  1821 	}
       
  1822 
       
  1823 void CWsClient::SetClientPriority()
       
  1824 	{
       
  1825 	if (iComputeMode!=RWsSession::EPriorityControlDisabled)
       
  1826 		{
       
  1827 		Client().SetProcessPriority(
       
  1828 				iComputeMode==RWsSession::EPriorityControlComputeOn 
       
  1829 			||	CWsTop::FocusWindowGroupOwner()!=this
       
  1830 				?	EPriorityBackground
       
  1831 			  	:	EPriorityForeground);
       
  1832 		}
       
  1833 	}
       
  1834 
       
  1835 void CWsClient::SetComputeMode(RWsSession::TComputeMode aComputeMode)
       
  1836 	{
       
  1837 	if (aComputeMode!=RWsSession::EPriorityControlDisabled 
       
  1838 		&& aComputeMode	!=RWsSession::EPriorityControlComputeOn 
       
  1839 		&& aComputeMode	!=RWsSession::EPriorityControlComputeOff)
       
  1840 		PPanic(EWservPanicSetComputeMode);
       
  1841 	iComputeMode=aComputeMode;
       
  1842 	SetClientPriority();
       
  1843 	}
       
  1844 
       
  1845 void CWsClient::CompleteMessage(const RMessage2& aMessage,TInt aReason)
       
  1846 	{
       
  1847 	WS_ASSERT_DEBUG(!aMessage.IsNull(),EWsPanicPanicFlagError);
       
  1848 	if (iInternalFlags&EPanicClientAsSoonAsPossible)
       
  1849 		{
       
  1850 		aMessage.Panic(KWSERVSessionPanicCategory,iPanicReason);
       
  1851 		iInternalFlags&=~EPanicClientAsSoonAsPossible;
       
  1852 		}
       
  1853 	else
       
  1854 		{
       
  1855 		if(!iResponseHandle)
       
  1856 			aMessage.Complete(aReason);
       
  1857 		else
       
  1858 			{
       
  1859 			aMessage.Complete(*iResponseHandle);
       
  1860 			iResponseHandle=NULL;
       
  1861 			}
       
  1862 		}
       
  1863 	}
       
  1864 
       
  1865 void CWsClient::ServiceError(const RMessage2& /*aMessage*/,TInt aError)
       
  1866 	{
       
  1867 	CompleteMessage(iClientMessage,aError);	// (finish)
       
  1868 	}
       
  1869 
       
  1870 void CWsClient::ServiceL(const RMessage2 &aMessage)	// (step ##1)
       
  1871 //
       
  1872 // Handle messages for the window server server.
       
  1873 //
       
  1874 	{
       
  1875 	iClientMessage=aMessage; // from now on use always the message stored in the session
       
  1876 	if (iInternalFlags&EPanicClientAsSoonAsPossible)
       
  1877 		{
       
  1878 		iClientMessage.Panic(KWSERVSessionPanicCategory,iPanicReason);
       
  1879 		}
       
  1880 	else
       
  1881 		{
       
  1882 		iPanicReason=KErrNone;
       
  1883 		iReply=KErrNone;
       
  1884 		TBool completeRequest=ETrue;
       
  1885 		DoServiceL(iClientMessage, completeRequest);	// (call #2)
       
  1886 		if (completeRequest)
       
  1887 			CompleteMessage(iClientMessage,iReply);	// (finish)
       
  1888 		}
       
  1889 	}
       
  1890 
       
  1891 void CWsClient::SetResponseHandle(RHandleBase* aHandle)
       
  1892 	{
       
  1893 	iResponseHandle = aHandle;
       
  1894 	}
       
  1895 
       
  1896 void CWsClient::DoServiceL(const RMessage2& aMessage, TBool& aCompleteRequest)	// (step #2)
       
  1897 	{
       
  1898 	if (aMessage.IsNull())
       
  1899 		PPanic(EWservPanicNullMessageFromClient);
       
  1900 	
       
  1901 	WS_ASSERT_DEBUG(iInternalFlags&EFinishedProcessingCommands,EWsPanicCommandBufferStillBeingProcessed);
       
  1902 
       
  1903 	const TInt function = aMessage.Function();
       
  1904 	switch (function)
       
  1905 		{
       
  1906 	case EWservMessInit:
       
  1907 		StartInitializationL(iConnectionId++);
       
  1908 		break;
       
  1909 	case EWservMessSyncMsgBuf:
       
  1910 	case EWservMessCommandBuffer:	// Process command buffer containing draw ops
       
  1911 		{
       
  1912 		if (!IsInitialised())			
       
  1913 			PPanic(EWservPanicUninitialisedClient);
       
  1914 			
       
  1915 		const TInt err = aMessage.Read(KBufferMessageSlot, iCmdBuf);
       
  1916 		if (!err)
       
  1917 			{
       
  1918 			iReplyOffset=0;
       
  1919 			iDestObj=NULL;
       
  1920 			iNextCmd=iCmdBuf.Ptr();
       
  1921 			DoServiceCommandBuf();	// (call #3.1)
       
  1922 			}
       
  1923 		else if (err!=KErrDied)
       
  1924 			PPanic(EWservPanicDescriptor);
       
  1925 		
       
  1926 		if(function == EWservMessCommandBuffer && CWsTop::FinishEveryFlush())
       
  1927 			Screen()->DoRedrawNow();
       
  1928 		else
       
  1929 			aCompleteRequest=EFalse;
       
  1930 		}
       
  1931 		break;
       
  1932 	case EWservMessShutdown:
       
  1933 		{
       
  1934 		if(!KSecurityPolicy_PowerMgmt().CheckPolicy(ClientMessage(),__PLATSEC_DIAGNOSTIC_STRING("Capability check failed for EWservMessShutdown message ")))
       
  1935 			PPanic(EWservPanicPermissionDenied);
       
  1936 
       
  1937 		if (aMessage.Int0() == EWservShutdownCheck)
       
  1938 			CWsTop::Exit();
       
  1939 		else
       
  1940 			PPanic(EWservPanicHandle);
       
  1941 		}
       
  1942 		break;
       
  1943 	case EWservMessFinish:
       
  1944 		Screen()->DoRedrawNow();
       
  1945 		break;
       
  1946 	default:
       
  1947 		if (function&EWservMessAsynchronousService)
       
  1948 			{
       
  1949 			TRAPD(err, ExecuteAsyncClientCommandL((function&~EWservMessAsynchronousService), aMessage));	// (call #3.2)
       
  1950 			aCompleteRequest = (err!=KErrNone);
       
  1951 			WS_ASSERT_DEBUG((!(iInternalFlags&EPanicClientAsSoonAsPossible))==(!aCompleteRequest), EWsPanicPanicFlagError);
       
  1952 			}
       
  1953 		else if (function&EWservMessAnimDllAsyncCommand)
       
  1954 			{
       
  1955 			CWsAnimDll* const animDll = static_cast<CWsAnimDll*>(HandleToObj(aMessage.Int0(), WS_HANDLE_ANIM_DLL));
       
  1956 			if (!animDll)
       
  1957 				{
       
  1958 				SessionPanic(EWservPanicHandle);
       
  1959 				break;
       
  1960 				}
       
  1961 				
       
  1962 			// 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
       
  1963 			TRAPD(err, animDll->AnimObjectL(aMessage.Int1())->CommandReply(function&~EWservMessAnimDllAsyncCommand,NULL));
       
  1964 			aCompleteRequest=(err!=KErrNone);
       
  1965 			WS_ASSERT_DEBUG((!(iInternalFlags&EPanicClientAsSoonAsPossible))==(!aCompleteRequest), EWsPanicPanicFlagError);
       
  1966 			}
       
  1967 		else
       
  1968 			SetReply(KErrNotSupported);
       
  1969 		}
       
  1970 	}
       
  1971 void CWsClient::RemoteRead(TDes16& aDes, TInt aOffset)
       
  1972 	{
       
  1973 	if (iClientMessage.Read(KRemoteBufferMessageSlot,aDes,aOffset)!=KErrNone)
       
  1974 		SessionPanic(EWservPanicDescriptor);
       
  1975 	}
       
  1976 
       
  1977 void CWsClient::RemoteRead(TDes8& aDes, TInt aOffset)
       
  1978 	{
       
  1979 	if (iClientMessage.Read(KRemoteBufferMessageSlot,aDes,aOffset)!=KErrNone)
       
  1980 		SessionPanic(EWservPanicDescriptor);
       
  1981 	}
       
  1982 
       
  1983 void CWsClient::RemoteReadL(TDes16& aDes, TInt aOffset)
       
  1984 	{
       
  1985 	iClientMessage.ReadL(KRemoteBufferMessageSlot,aDes,aOffset);
       
  1986 	}
       
  1987 
       
  1988 void CWsClient::RemoteReadL(TDes8& aDes, TInt aOffset)
       
  1989 	{
       
  1990 	iClientMessage.ReadL(KRemoteBufferMessageSlot,aDes,aOffset);
       
  1991 	}
       
  1992 
       
  1993 void CWsClient::InitStaticsL()
       
  1994 	{
       
  1995 	iMoreCommands=CIdle::NewL(EClientBufferPriority);
       
  1996 	}
       
  1997 
       
  1998 void CWsClient::DeleteStatics()
       
  1999 	{
       
  2000 	if (iTextCursorArray)
       
  2001 		{
       
  2002 		const TInt count = iTextCursorArray->Count();
       
  2003 		for (TInt index=0;index<count;index++)
       
  2004 			delete iTextCursorArray->At(index).iCursor;
       
  2005 
       
  2006 		delete iTextCursorArray;
       
  2007 		iTextCursorArray = NULL;
       
  2008 		}
       
  2009 
       
  2010 	delete iMoreCommands;
       
  2011 	iMoreCommands=NULL;
       
  2012 	// coverity[extend_simple_error] 
       
  2013 	}
       
  2014 		
       
  2015 /* CWsClient implementing MWsClient */
       
  2016 
       
  2017 TBool CWsClient::HasCapability(TCapability aCapability) const
       
  2018 	{
       
  2019 	return iClient.HasCapability(aCapability);
       
  2020 	}
       
  2021 
       
  2022 TSecureId CWsClient::SecureId() const
       
  2023 	{
       
  2024 	return iClient.SecureId();
       
  2025 	}
       
  2026 
       
  2027 TVendorId CWsClient::VendorId() const
       
  2028 	{
       
  2029 	return iClient.VendorId();
       
  2030 	}
       
  2031 
       
  2032 /**
       
  2033 Makes a new copy of the aData. so it could be deleted after this call.
       
  2034 */
       
  2035 TInt CWsClient::SendMessage(const CWsGraphicDrawer* aOnBehalfOf,const TDesC8& aData)
       
  2036 	{
       
  2037 	CWsGraphicMessageQueue::CMessage* msg = CWsGraphicMessageQueue::CMessage::New(aData);
       
  2038 	if(msg)
       
  2039 		return SendMessage(aOnBehalfOf, *msg);
       
  2040 	
       
  2041 	return KErrGeneral;
       
  2042 	}
       
  2043 
       
  2044 /** adds a message to the message queue
       
  2045 @return a postive number to uniquely identify the message
       
  2046 */
       
  2047 TInt CWsClient::SendMessage(const CWsGraphicDrawer* aOnBehalfOf,CWsMessageData& aData)
       
  2048 	{
       
  2049 	WS_ASSERT_DEBUG(aData.Data().Size(), EWsPanicWsGraphic);
       
  2050 	const CWsGraphicDrawerObject* obj = DrawerObject(aOnBehalfOf);
       
  2051 	WS_ASSERT_DEBUG(obj, EWsPanicWsGraphic);
       
  2052 	if(obj)
       
  2053 		{
       
  2054 		// assign message id
       
  2055 		if(iMessageIdSeq == KMaxTInt) // Wrap if iMessageIdSeq has reached KMaxTInt
       
  2056 			iMessageIdSeq = 0;
       
  2057 		
       
  2058 		iMessageIdSeq++;
       
  2059 		// correct other handles
       
  2060 		aData.iClientHandle = (obj->ClientHandle() | (EWsGraphMessageTypeUser & 0x03));
       
  2061 		aData.iDrawer = obj->Drawer();
       
  2062 		aData.iId = iMessageIdSeq;
       
  2063 		iGraphicMessageQueue.Queue(&aData);
       
  2064 		return iMessageIdSeq;
       
  2065 		}
       
  2066 
       
  2067 	return KErrGeneral;
       
  2068 	}
       
  2069 
       
  2070 
       
  2071 CWsGraphicDrawerObject* CWsClient::DrawerObject(const CWsGraphicDrawer* aDrawer)
       
  2072 	{
       
  2073 	const TInt count = ObjectIndex()->Length();
       
  2074 	for(TInt i=0; i<count; i++)
       
  2075 		{
       
  2076 		CWsObject* obj = const_cast<CWsObject*>(ObjectIndex()->At(i));
       
  2077 		if(obj && (WS_HANDLE_GRAPHIC_DRAWER == obj->Type()))
       
  2078 			{
       
  2079 			CWsGraphicDrawerObject* candidate = static_cast<CWsGraphicDrawerObject*>(obj);
       
  2080 			if(candidate->Drawer() == aDrawer)
       
  2081 				return candidate;
       
  2082 			}
       
  2083 		}
       
  2084 
       
  2085 	return NULL;
       
  2086 	}
       
  2087 
       
  2088 const CWsGraphicDrawerObject* CWsClient::DrawerObject(const CWsGraphicDrawer* aDrawer) const
       
  2089 	{
       
  2090 	CWsObjectIx* objectIndex = const_cast<CWsClient*>(this)->ObjectIndex();
       
  2091 	const TInt count = objectIndex->Length();
       
  2092 	for(TInt i=0; i<count; i++)
       
  2093 		{
       
  2094 		CWsObject* obj = const_cast<CWsObject*>(objectIndex->At(i));
       
  2095 		if(obj && (WS_HANDLE_GRAPHIC_DRAWER == obj->Type()))
       
  2096 			{
       
  2097 			const CWsGraphicDrawerObject* candidate = static_cast<CWsGraphicDrawerObject*>(obj);
       
  2098 			if(candidate->Drawer() == aDrawer)
       
  2099 				return candidate;
       
  2100 			}
       
  2101 		}
       
  2102 
       
  2103 	return NULL;
       
  2104 	}
       
  2105 
       
  2106 TInt CWsClient::RegisterSurface(const TWsClCmdUnion& pData)
       
  2107 	{
       
  2108 	TInt screenNumber = pData.SurfaceRegister->screenNumber;
       
  2109 	if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
  2110 		{
       
  2111 		PPanic(EWservPanicScreenNumber);
       
  2112 		}
       
  2113 	if (pData.SurfaceRegister->surfaceId.Type() == TSurfaceId::EScreenSurface
       
  2114 			|| pData.SurfaceRegister->surfaceId.IsNull())
       
  2115 		{
       
  2116 		PPanic(EWservPanicInvalidSurface);
       
  2117 		}
       
  2118 
       
  2119 	CRegisteredSurfaceMap* surfaceMap = CWsTop::Screen(screenNumber)->SurfaceMap();
       
  2120 	const TSurfaceId& surfaceId = pData.SurfaceRegister->surfaceId;
       
  2121 	TInt err = surfaceMap->Add(*this,surfaceId);
       
  2122 
       
  2123 	switch(err)
       
  2124 		{
       
  2125 	case KErrNone:
       
  2126 	case KErrNoMemory:
       
  2127 	case KErrInUse:
       
  2128 	case KErrArgument:
       
  2129 		break;
       
  2130 	default:
       
  2131 		PPanic(EWservPanicInvalidSurface);
       
  2132 		}
       
  2133 	return err;
       
  2134 	}
       
  2135 
       
  2136 void CWsClient::UnregisterSurface(const TWsClCmdUnion& pData)
       
  2137 	{
       
  2138 	TInt screenNumber = pData.SurfaceRegister->screenNumber;
       
  2139 	if (screenNumber<0 || screenNumber>=CWsTop::NumberOfScreens())
       
  2140 		{
       
  2141 		PPanic(EWservPanicScreenNumber);
       
  2142 		}
       
  2143 	TInt err = CWsTop::Screen(screenNumber)->SurfaceMap()->Remove(*this,pData.SurfaceRegister->surfaceId);
       
  2144 	WS_ASSERT_DEBUG((err==KErrNone||err==KErrNotFound), EWsPanicSurfaceMapError);
       
  2145 	}
       
  2146 
       
  2147 void CWsClient::CreateDrawableSourceL(const TWsClCmdCreateDrawableSource& aDrawableSourceData)
       
  2148 	{
       
  2149 	CWsDrawableSource* drawableSource = new(ELeave) CWsDrawableSource(this);
       
  2150 	CleanupStack::PushL(drawableSource);
       
  2151 	drawableSource->ConstructL(aDrawableSourceData);
       
  2152 	CleanupStack::Pop();
       
  2153 	}
       
  2154 
       
  2155 //
       
  2156 // class CWsCliObj
       
  2157 //
       
  2158 
       
  2159 CWsCliObj* CWsCliObj::NewL(CWsClient* aOwner)
       
  2160 	{
       
  2161 	CWsCliObj* self = new(ELeave) CWsCliObj(aOwner);
       
  2162 	CleanupStack::PushL(self);
       
  2163 	self->ConstructL();
       
  2164 	CleanupStack::Pop(self);
       
  2165 	return self;
       
  2166 	}
       
  2167 
       
  2168 CWsCliObj::CWsCliObj(CWsClient *aOwner) :
       
  2169 	CWsObject(aOwner, WS_HANDLE_CLIENT)
       
  2170 	{
       
  2171 	}
       
  2172 	
       
  2173 void CWsCliObj::ConstructL()
       
  2174 	{
       
  2175 	NewObjL();	
       
  2176 	}
       
  2177 
       
  2178 void CWsCliObj::CommandL(TInt aOpcode, const TAny* aCmdData)	// (step #5)
       
  2179 	{
       
  2180 	iWsOwner->ExecuteCommandL(aOpcode,aCmdData);	// (call #6)
       
  2181 	}
       
  2182 
       
  2183 CWsObject* CWsClient::HandleToObjUntyped(TInt aHandle)
       
  2184 	{
       
  2185 	return iObjectIndex->HandleToObject(aHandle);
       
  2186 	}
       
  2187 
       
  2188 const CWsObject* CWsClient::HandleToObjUntyped(TInt aHandle) const
       
  2189 	{
       
  2190 	return const_cast<CWsClient*>(this)->HandleToObjUntyped(aHandle);
       
  2191 	}
       
  2192 
       
  2193 CWsObject* CWsClient::HandleToObj(TInt aHandle, WH_HANDLES aType)
       
  2194 	{
       
  2195 	CWsObject* object = HandleToObjUntyped(aHandle);
       
  2196 	return (object && object->Type() == aType) ? object : NULL;
       
  2197 	}
       
  2198 
       
  2199 
       
  2200 const CWsObject* CWsClient::HandleToObj(TInt aHandle, WH_HANDLES aType) const
       
  2201 	{
       
  2202 	return const_cast<CWsClient*>(this)->HandleToObj(aHandle, aType);
       
  2203 	}
       
  2204 
       
  2205 void CWsClient::SetRetryFlag(TEventCode aEventCode)
       
  2206 	{
       
  2207 	switch(aEventCode)
       
  2208 		{
       
  2209 		//To be expanded
       
  2210 		case EEventDisplayChanged:
       
  2211 			{
       
  2212 			iInternalFlags |= ERetryDisplayEvent;
       
  2213 			}
       
  2214 		break;
       
  2215 		
       
  2216 		}
       
  2217 	}
       
  2218 TBool CWsClient::RetryEvent(TEventCode aEventCode)
       
  2219 	{
       
  2220 	switch(aEventCode)
       
  2221 		{//To be expanded
       
  2222 		case EEventDisplayChanged:
       
  2223 			{
       
  2224 			return (iInternalFlags & ERetryDisplayEvent);
       
  2225 			}
       
  2226 		}
       
  2227 	return EFalse;
       
  2228 	}
       
  2229 
       
  2230 void CWsClient::RemoveRetryFlag(TEventCode aEventCode)
       
  2231 	{
       
  2232 	switch(aEventCode)
       
  2233 		{//To be expanded
       
  2234 		case EEventDisplayChanged:
       
  2235 			{
       
  2236 			iInternalFlags &= ~ERetryDisplayEvent;
       
  2237 			}
       
  2238 		break;
       
  2239 		}
       
  2240 	}
       
  2241