windowing/windowserver/tauto/TPANIC.CPP
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/tauto/TPANIC.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,2014 @@
+// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Test various cases of Wserv panicing client apps
+// 
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+#include "TPANIC.H"
+#include "../tlib/testbase.h"
+#include <w32debug.h>
+#define TEST_BITMAP _L("Z:\\WSTEST\\WSAUTOTEST.MBM")
+
+class RWsSessionHacker : public RWsSession
+	{
+public:
+	inline RWsBuffer *WsBuffer() const {return(iBuffer);};
+	inline TInt PanicItSendReceive(TInt aFunction,const TIpcArgs& aArgs) const {return SendReceive(aFunction,aArgs);};
+	inline TInt PanicItSend(TInt aFunction,const TIpcArgs& aArgs) const {return Send(aFunction,aArgs);};
+	inline TInt PanicItSendReceive(TInt aFunction) const {return SendReceive(aFunction);};
+	inline TInt PanicItSend(TInt aFunction) const {return Send(aFunction);};
+	};
+
+class RWsBufferHacker // copy of original data structure to access buffer data
+	{
+public:
+	RWsSession* iSession;
+	CWsGraphic::CManager* iManager;
+	TBool iAutoFlush;
+	TPtr8 iBuf;
+	RWsBuffer* iNext;
+	TInt iPreviousHandle;
+	TInt iBufSize;
+	TInt iMaxBufSize;
+	TInt iDirectAcessCount;
+	RArray<TInt> iBitmapArray;
+	TBool iInvalidBitmapArray;
+	};
+
+CTPanic::CTPanic(CTestStep* aStep):
+	CTWsGraphicsBase(aStep)
+	{
+	}
+	
+CTPanic::~CTPanic()
+	{
+	}
+
+LOCAL_C TInt DoDeletedParentTest(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// point to correct screen
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	switch(aInt)
+		{
+		case 1:
+			RWindow win1(ws);
+			User::LeaveIfError(win1.Construct(group,1));
+			RWindow win2(ws);
+			User::LeaveIfError(win2.Construct(win1,2));
+			win1.Close();
+			win2.SetExtent(TPoint(1,2),TSize(3,4));
+			break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C void ReuseWindow(RWsSession& aWs,RWindowGroup& aGroup,RWindow aCopyWin,RWindow* aPtrWin)
+	{
+	aPtrWin->Close();
+	RWindow win(aWs);
+	User::LeaveIfError(win.Construct(aGroup,17));
+	aCopyWin.SetExtent(TPoint(1,2),TSize(3,4));	
+	}
+
+LOCAL_C void ReuseGroupWindow(RWsSession& aWs,RWindowGroup aCopyWin,RWindowGroup* aPtrWin)
+	{
+	aPtrWin->Close();
+	RWindowGroup group(aWs);
+	User::LeaveIfError(group.Construct(889));
+	group.EnableReceiptOfFocus(EFalse);	
+	aCopyWin.EnableReceiptOfFocus(EFalse);	
+	}
+
+LOCAL_C void ReuseSprite(RWsSession& aWs,RWindow& aWin,RWsSprite aCopySprite,RWsSprite* aPtrSprite)
+	{
+	aPtrSprite->Close();
+	RWsSprite sprite(aWs);
+	sprite.Construct(aWin,TPoint(0,0),0);
+	aCopySprite.SetPosition(TPoint(22,22));	
+	}
+
+LOCAL_C void ReusePointerCursor(RWsSession& aWs,RWsPointerCursor aCopyCursor,RWsPointerCursor* aPtrCursor)
+	{
+	aPtrCursor->Close();
+	RWsPointerCursor cursor(aWs);
+	cursor.Construct(0);
+	aCopyCursor.Activate();	
+	}
+
+LOCAL_C TInt DoHandleReUse(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	CWsScreenDevice *scrdev=new(ELeave) CWsScreenDevice(ws);
+	scrdev->Construct((TInt)aScreenNumber);
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	RWindow win(ws);
+	User::LeaveIfError(win.Construct(group,1));
+	switch(aInt)
+		{
+		case 2:			//WS_HANDLE_WINDOW
+			ReuseWindow(ws,group,win,&win);
+			break;
+		case 3:			//WS_HANDLE_GROUP_WINDOW
+			ReuseGroupWindow(ws,group,&group);
+			break;
+		case 4:			//WS_HANDLE_SPRITE
+			{
+			RWsSprite sprite(ws);
+			sprite.Construct(win,TPoint(0,0),0);
+			ReuseSprite(ws,win,sprite,&sprite);
+			}
+			break;
+		case 5:			//WS_HANDLE_POINTER_CURSOR
+			{
+			RWsPointerCursor cursor(ws);
+			cursor.Construct(0);
+			ReusePointerCursor(ws,cursor,&cursor);
+			}
+			break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoScreenDevicePanicTest(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+
+	CWsScreenDevice *scrdev=new(ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(scrdev->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	RWindow win(ws);
+	User::LeaveIfError(win.Construct(group, 1));
+	win.Activate();
+	CFbsBitmap *bitmap=new(ELeave) CFbsBitmap;
+ 	switch(aInt)
+		{
+		case 1:
+			scrdev->CopyScreenToBitmap(bitmap);
+			break;
+		case 2:
+			scrdev->CopyScreenToBitmap(bitmap,TRect(0,0,10,10));
+			break;
+		default:
+			return(EWsExitReasonFinished);
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoOpcodeTests(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+
+	CWsScreenDevice *scrdev=new(ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(scrdev->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	RWindow win(ws);
+	User::LeaveIfError(win.Construct(group, 1));
+	win.Activate();
+	CWindowGc *gc;
+	scrdev->CreateContext(gc);
+ 	switch(aInt)
+		{
+		case 1:
+			ws.TestWrite(ws.WsHandle(),9999,NULL,0);
+			break;
+		case 2:
+			gc->Activate(win);
+			win.BeginRedraw();
+			ws.TestWrite(gc->WsHandle(),9999,NULL,0);
+			/* This only panics if the command is processed immediately.  If it goes into the redraw
+			store then it will be unable to panic the client untill an additional buffer has been received,
+			hence the double flush.
+			*/
+			win.EndRedraw();
+			ws.Finish();
+			win.BeginRedraw();
+			win.EndRedraw();
+			break;
+		case 3:
+			ws.TestWrite(scrdev->WsHandle(),9999,NULL,0);
+			break;
+		case 4:
+			{
+			CWsBitmap *bitmap=new(ELeave) CWsBitmap(ws);
+			bitmap->Create(TSize(10,10),EGray4);
+			ws.TestWrite(bitmap->WsHandle(),9999,NULL,0);
+			}
+			break;
+		case 5:
+			ws.TestWrite(win.WsHandle(),9999,NULL,0);
+			break;
+		case 6:
+			ws.TestWrite(group.WsHandle(),9999,NULL,0);
+			break;
+		case 7:
+			{
+			RWsSprite sprite(ws);
+			sprite.Construct(win,TPoint(0,0),0);
+			ws.TestWrite(sprite.WsHandle(),9999,NULL,0);
+			}
+			break;
+		default:
+			return(EWsExitReasonFinished);
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+TInt DoGraphicsPanicTest(RWsSession& aWs, RWindow& aRWin, RDrawableWindow* aDrawWin, CWindowGc* aGc, CFbsFont* aFont, TInt aTest, TInt aSubTest, TBool aInRedraw, TBool aNeedsValidating)
+	{
+	if (aInRedraw || aNeedsValidating)
+		{
+		aRWin.BeginRedraw();
+		if (!aInRedraw)
+			{ // TransWin without redraw active needs the begin/end to make the redraw store active
+			aRWin.EndRedraw(); // or else all graphics will simply be ignored and no panics will occur
+			}
+		}
+	aWs.Flush();
+	TRect rect01(0,0,1,1);
+	TPoint point00;
+	switch(aTest)
+		{
+	case 1:
+		aGc->UseFont(aFont);
+		switch(aSubTest)
+			{
+		case 0:
+			{
+			TWsGcCmdBoxText boxText(rect01,0,CGraphicsContext::ELeft,0,0x800000,1);
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawBoxText,&boxText,sizeof(boxText));
+			}
+			break;
+		case 1:
+			{
+			TWsGcCmdDrawText dt(point00,600);
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawText,&dt,sizeof(dt));
+			}
+			break;
+		case 2:
+			{
+			TWsGcCmdBoxTextOptimised1 dt(rect01,0,600);
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawBoxTextOptimised1,&dt,sizeof(dt));
+			}
+			break;
+		case 3:
+			{
+			TWsGcCmdDrawTextVertical dt(point00,600,EFalse);
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawTextVertical,&dt,sizeof(dt));
+			}
+			break;
+		case 4:
+			{
+			TWsGcCmdBoxTextVertical dt(rect01);
+			dt.length=600;
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawBoxTextVertical,&dt,sizeof(dt));
+			}
+			break;
+		case 5:
+			return(EWsExitReasonFinished);
+			}
+		break;
+	case 2:
+		{
+		TInt opcode=0;
+		switch(aSubTest)
+			{
+		case 0:
+			opcode=EWsGcOpGdiBlt2;
+			break;
+		case 1:
+			opcode=EWsGcOpGdiWsBlt2;
+			break;
+		case 2:
+			return(EWsExitReasonFinished);
+			}
+		TWsGcCmdGdiBlt2 gdiBlit(point00,0xBADBAD);
+		aWs.TestWrite(aGc->WsHandle(),opcode,&gdiBlit,sizeof(gdiBlit));
+		if (aInRedraw)
+			{ // Adding two bad bitmaps to redraw store fbs store causes leave as NULL handles of failed bitmaps clash
+			gdiBlit.handle=0xBADBAD2;
+			aWs.TestWrite(aGc->WsHandle(),opcode,&gdiBlit,sizeof(gdiBlit));
+			}
+		}
+		break;
+	case 3:
+		{
+		const TInt KNumBadBmpModes=3;
+		const TInt KNumTestsPerOpcode=KNumBadBmpModes*2;
+		enum {KPanicIndexMasked,KPanicIndexDraw,KPanicIndexAlphaBlend,KPanicIndexMax};
+		TInt opcodeMode=aSubTest/KNumTestsPerOpcode;
+		TInt bmpMode=aSubTest%KNumTestsPerOpcode;
+		TInt bmp1=0xBADBAD;
+		TInt bmp2=0xBADBAD;
+		TInt goodBmp;
+		TInt opcodeBlt;
+		TInt opcodeDraw;
+		if (bmpMode<KNumBadBmpModes)
+			{	// These two use a CFbsBitmap
+			CFbsBitmap* goodBitmap=new(ELeave) CFbsBitmap;
+			goodBitmap->Create(TSize(10,10),EGray4);
+			goodBmp=goodBitmap->Handle();
+			opcodeBlt=EWsGcOpGdiBltMasked;
+			opcodeDraw=EWsGcOpDrawBitmapMasked;
+			}
+		else
+			{	// These two use a CWsBitmap
+			CWsBitmap* goodBitmap=new(ELeave) CWsBitmap(aWs);
+			goodBitmap->Create(TSize(10,10),EGray4);
+			goodBmp=goodBitmap->WsHandle();
+			opcodeBlt=EWsGcOpGdiWsBltMasked;
+			opcodeDraw=EWsGcOpWsDrawBitmapMasked;
+			}
+		switch(bmpMode%KNumBadBmpModes)
+			{
+		case 0:
+			bmp2=goodBmp;
+			break;
+		case 1:
+			bmp1=goodBmp;
+			break;
+		case 2:	// Leave them both bad
+			break;
+			}
+		switch(opcodeMode)
+			{
+		case KPanicIndexMasked:
+			{
+			TWsGcCmdBltMasked gdiBlitMasked(point00,bmp1,rect01,bmp2,EFalse);
+			aWs.TestWrite(aGc->WsHandle(),opcodeBlt,&gdiBlitMasked,sizeof(gdiBlitMasked));
+			}
+			break;
+		case KPanicIndexDraw:
+			{
+			TWsGcCmdDrawBitmapMasked maskedBitmap(rect01,bmp1,rect01,bmp2,EFalse);
+			aWs.TestWrite(aGc->WsHandle(),opcodeDraw,&maskedBitmap,sizeof(maskedBitmap));
+			}
+			break;
+		case KPanicIndexAlphaBlend:
+			{
+			TWsGcCmdAlphaBlendBitmaps alphaBlend(point00,bmp1,rect01,bmp2,point00);
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpGdiAlphaBlendBitmaps,&alphaBlend,sizeof(alphaBlend));
+			}
+			break;
+		case KPanicIndexMax:
+			return(EWsExitReasonFinished);
+			}
+		}
+		break;
+	case 4:
+		switch(aSubTest)
+			{
+		case 0:
+			{
+			TWsClCmdCreateBitmap createBitmap;
+			createBitmap.handle=0xB0D;
+			aWs.TestWrite(aWs.WsHandle(),EWsClOpCreateBitmap,&createBitmap,sizeof(createBitmap));
+			}
+			break;
+		case 1:
+			{
+			TInt badBrush=0xBADB3054;
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpUseBrushPattern,&badBrush,sizeof(badBrush));
+			}
+			break;
+		case 2:
+			{
+			TWsGcCmdDrawBitmap drawBitmap(point00,0xBADBAD);
+			aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawBitmap,&drawBitmap,sizeof(drawBitmap));
+			}
+			break;
+		case 3:
+			return(EWsExitReasonFinished);
+			}
+		break;
+	case 5:
+		// test bad opcodes
+		{
+		TInt opcode=0;
+		switch(aSubTest)
+			{
+		case 0:
+			opcode=9999;
+			break;
+		case 1:
+			return(EWsExitReasonFinished);
+			}
+		aWs.TestWrite(aGc->WsHandle(),opcode,NULL,0);
+		}
+		break;
+	case 6:
+		{// Test EWsGcOpDrawPolygon with invalid parameters
+		 // First two times has slightly more points specified than exist in the data
+		 // Third time time has a massive number of points in the header
+		const TInt KNumTestsPerPolyMode=3;
+		enum TPanicPolyMode {EPanicPolyModePolygon,EPanicPolyModePolyLine,EPanicPolyModeEnd};
+		TInt polyMode=aSubTest/KNumTestsPerPolyMode;
+		if (polyMode==EPanicPolyModeEnd)
+			return(EWsExitReasonFinished);
+		TInt subMode=aSubTest%KNumTestsPerPolyMode;
+		TInt bufPoints=0;
+		TInt headerPoints=1;
+		switch(subMode)
+			{
+		case 0:
+			break;
+		case 1:
+			bufPoints=2;
+			headerPoints=8;
+			break;
+		case 2:
+			bufPoints=2;
+			headerPoints=999999;
+			break;
+			}
+		TInt bufDataLen=bufPoints*sizeof(TPoint);
+		if (polyMode==EPanicPolyModePolyLine)
+			bufDataLen+=sizeof(TWsGcCmdDrawPolyLine);
+		else
+			bufDataLen+=sizeof(TWsGcCmdDrawPolygon);
+		TAny* bufData=User::AllocL(bufDataLen);
+		TPoint* pointPtr;
+		TInt opcode;
+		if (polyMode==EPanicPolyModePolyLine)
+			{
+			TWsGcCmdDrawPolyLine* drawPolyline=static_cast<TWsGcCmdDrawPolyLine*>(bufData);
+			drawPolyline->numPoints=headerPoints;
+			drawPolyline->more=EFalse;
+			drawPolyline->last=point00;
+			pointPtr=reinterpret_cast<TPoint*>(drawPolyline+1);
+			opcode=EWsGcOpDrawPolyLine;
+			}
+		else
+			{
+			TWsGcCmdDrawPolygon* drawPolygon=static_cast<TWsGcCmdDrawPolygon*>(bufData);
+			drawPolygon->numPoints=headerPoints;
+			drawPolygon->fillRule=CGraphicsContext::EAlternate;
+			pointPtr=reinterpret_cast<TPoint*>(drawPolygon+1);
+			opcode=EWsGcOpDrawPolygon;
+			}
+		const TPoint* endPtr=pointPtr+bufPoints;
+		TInt pointPos=0;
+		while(pointPtr<endPtr)
+			*pointPtr++=TPoint(pointPos,pointPos);
+		aWs.TestWrite(aGc->WsHandle(),opcode,bufData,bufDataLen);
+		aWs.Flush();	// Needs flush to make sure EndRedraw() doesn't make buffer bigger and catch out buf len check
+		}
+		break;
+	case 7:
+		{
+		// first sets the index to match the total count
+		// second sets the index negative
+		// fourth sends too much data
+		TWsGcCmdStartSegmentedDrawPolygon startPoly;
+		startPoly.totalNumPoints=8;
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpStartSegmentedDrawPolygon,&startPoly,sizeof(startPoly));
+		TInt bufDataLen=sizeof(TWsGcCmdSegmentedDrawPolygonData)+startPoly.totalNumPoints*sizeof(TPoint);
+		TAny* bufData=User::AllocL(bufDataLen);
+		TWsGcCmdSegmentedDrawPolygonData* polyData=static_cast<TWsGcCmdSegmentedDrawPolygonData*>(bufData);
+		polyData->numPoints=1;
+		polyData->index=0;
+		switch(aSubTest)
+			{
+		case 0:
+			polyData->index=startPoly.totalNumPoints;
+			break;
+		case 1:
+			polyData->index=-123;
+			break;
+		case 2:
+			polyData->numPoints=startPoly.totalNumPoints+1;
+			break;
+		case 3:
+			return(EWsExitReasonFinished);
+			}
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpSegmentedDrawPolygonData,polyData,bufDataLen);
+		TWsGcCmdDrawSegmentedPolygon drawit;
+		drawit.fillRule=CGraphicsContext::EAlternate;
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawSegmentedPolygon,&drawit,sizeof(drawit));
+		}
+		break;
+	case 8:
+		{
+		if (aSubTest==1)
+			return(EWsExitReasonFinished);
+		// This is a test designed to specificially test polylines still work after the previous
+		// polyline/polygon tests. One potential defect is they leave the common redraw store gc
+		// in a bad state still holding part of the poly data and causing a EWservPanicBadPolyData
+		// panic.
+		// This test is designed to make sure the drawpolyline call works ok and we reach the bad
+		// opcode panic instead.
+		TWsGcCmdStartSegmentedDrawPolygon startPoly;
+		startPoly.totalNumPoints=2;
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpStartSegmentedDrawPolygon,&startPoly,sizeof(startPoly));
+		struct
+			{
+			TWsGcCmdSegmentedDrawPolygonData iPolyData;
+			TPoint iPoints[2];
+			} polyParams;
+		polyParams.iPoints[0].iX=1;
+		polyParams.iPoints[0].iY=1;
+		polyParams.iPoints[1].iX=2;
+		polyParams.iPoints[1].iY=2;
+			
+		polyParams.iPolyData.numPoints=2;
+		polyParams.iPolyData.index=0;
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpSegmentedDrawPolygonData,&polyParams.iPolyData,sizeof(polyParams));
+		TWsGcCmdDrawSegmentedPolygon drawit;
+		drawit.fillRule=CGraphicsContext::EAlternate;
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpDrawSegmentedPolygon,&drawit,sizeof(drawit));
+		aWs.TestWrite(aGc->WsHandle(),9999,NULL,0);
+		}
+		break;
+	case 9:
+		if (aSubTest==1)
+			return(EWsExitReasonFinished);
+		aGc->Activate(*aDrawWin);	// Double activate
+		break;
+	case 10:
+		if (aSubTest==1)
+			return(EWsExitReasonFinished);
+		aGc->DrawText(_L("No font"),point00);
+		break;
+	case 11:
+		if (aSubTest==1)
+			return(EWsExitReasonFinished);
+		aGc->SetBrushStyle(CGraphicsContext::EPatternedBrush);
+		aGc->DrawRect(rect01);
+		break;
+	case 12:
+		{
+		if (aSubTest==1)
+			return(EWsExitReasonFinished);
+		aGc->UseFont(aFont);
+		TPtrC bigAndbad(NULL,5000);	// Will go through remote descriptor fetching code
+		aGc->DrawText(bigAndbad,point00);
+		}
+		break;
+	case 13:
+		{
+		if (aSubTest==1)
+			return(EWsExitReasonFinished);
+		TInt badHandle=0xDEADBAD;
+		aWs.TestWrite(aGc->WsHandle(),EWsGcOpUseFont,&badHandle,sizeof(badHandle));
+		aGc->DrawText(_L("BOO!"),point00);
+		}
+		break;
+		}
+	if (aInRedraw)
+		aRWin.EndRedraw();
+	aWs.Finish();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt GraphicsPanicTest(TInt aInt, TAny* aPanicParams)
+	{
+	CTPanic::TPanicParams* panicParams=static_cast<CTPanic::TPanicParams*>(aPanicParams);
+	/*
+	 * Drawing to a transparent window goes via the redraw store. In this
+	 * situation parameters do not get checked during the original processing
+	 * of the incoming graphics commands. They are only caught later when 
+	 * playing back from the redraw store.
+	 */
+	const TBool useTransWin = panicParams->iRedrawMode==EPanicRedrawModeTransRedraw;
+	/*
+	 * We always do redraw drawing unless we are using a BackedUpWindow.
+	 * Redraws can affect the way graphics commands are pre-processed, 
+	 * as with transparent windows they can also cause commands to get
+	 * buffered in the redraw store and played back later.
+	 */
+	const TBool inRedraw =
+		panicParams->iRedrawMode==EPanicRedrawModeNormalRedraw ||
+		panicParams->iRedrawMode==EPanicRedrawModeTransRedraw ||
+		panicParams->iRedrawMode==EPanicRedrawModeInvisRedraw;
+	/*
+	 * Drawing to an invisible window skips some of the code where errors
+	 * are caught. Particularly text drawing commands that skip the actual
+	 * drawing, but still process the update of the justification, this
+	 * has the potential of missing parameter checks made during the actual
+	 * drawing, but being caught out when processing the justification update.
+	 */
+	const TBool invisWin = panicParams->iRedrawMode==EPanicRedrawModeInvisRedraw;
+	
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+
+	CWsScreenDevice* scrdev=new(ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(scrdev->Construct(panicParams->iScreen));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	RDrawableWindow* drawWin;
+	RWindow rwin(ws);
+	RBackedUpWindow bwin(ws);
+	TBool needsValidating=EFalse;
+	if (useTransWin || inRedraw || invisWin)
+		{
+		drawWin=&rwin;
+		needsValidating=ETrue;
+		User::LeaveIfError(rwin.Construct(group,1));
+		if (useTransWin)
+			{
+			rwin.SetTransparencyAlphaChannel();
+			}
+		}
+	else
+		{
+		// EPanicRedrawModeBackedUpWindow case
+		drawWin=&bwin;
+		User::LeaveIfError(bwin.Construct(group, EGray4, 1));
+		}
+	const TSize testWinSize(100,100);
+	User::LeaveIfError(drawWin->SetSizeErr(testWinSize));
+	if (invisWin)
+		drawWin->SetPosition(TPoint(-testWinSize.iWidth,-testWinSize.iHeight));
+	drawWin->Activate();
+	CWindowGc* gc;
+	scrdev->CreateContext(gc);
+	gc->Activate(*drawWin);
+	CFbsFont* font;
+	User::LeaveIfError(scrdev->GetNearestFontToDesignHeightInTwips((CFont*&)font,TFontSpec()));
+	TInt ret=DoGraphicsPanicTest(ws,rwin,drawWin,gc,font,aInt,panicParams->iSubTest,inRedraw,needsValidating);
+	if (ret!=EWsExitReasonFinished && invisWin)
+		{
+		/*
+		 * Some functions are totally skipped on invisible windows, parameter
+		 * errors will be harmlessly ignored in these case. To make the test
+		 * pass we re-do the tests with the window now visible. The purpose
+		 * of the invisible draw tests was not to check the client is always
+		 * panicked doing illegal draws to invisible windows, but to make sure
+		 * they had no harmful side effects.
+		 */
+		drawWin->SetPosition(TPoint(0,0));
+		gc->Reset();
+		ret=DoGraphicsPanicTest(ws,rwin,drawWin,gc,font,aInt,panicParams->iSubTest,inRedraw,needsValidating);
+		}
+	return(ret);
+	}
+LOCAL_C TInt DoMiscPanicTest(TInt aSubTest, TAny* )
+	{
+	const TInt KNumPanicFuncsPerMode=EWsClOpLastEnumValue;
+	const TInt KNumPanicFuncModes=6;
+	const TInt KNumPanicSendTests=KNumPanicFuncsPerMode*KNumPanicFuncModes;
+	const TInt KNumRandGarbageTests=500;
+	if (aSubTest==(KNumPanicSendTests+KNumRandGarbageTests))
+		return(EWsExitReasonFinished);
+	RWsSessionHacker wshacker;
+	User::LeaveIfError(wshacker.Connect());
+	if (aSubTest<KNumPanicSendTests)
+		{
+		TInt messageMode=aSubTest/KNumPanicFuncsPerMode;
+		TInt msgFunc=aSubTest%KNumPanicFuncsPerMode;
+		const TInt EPanicWservMessAsynchronousService=0x010000; //copy of EWservMessAsynchronousService
+		const TInt EPanicWservMessAnimDllAsyncCommand=0x100000; //copy of EWservMessAnimDllAsyncCommand
+		switch(messageMode%3)
+			{
+		case 0:
+			if(msgFunc == EWservMessFinish) //RWsSession::Finish() doesn't panic
+				User::Panic(KWSERV, 0); //simulate a "successful" wserv panic to skip the sub test
+			break;
+		case 1:
+			msgFunc|=EPanicWservMessAsynchronousService;
+			break;
+		case 2:
+			msgFunc|=EPanicWservMessAnimDllAsyncCommand;
+			break;
+			}
+		TInt sendItErr=KErrNone;
+		if (messageMode<3)
+			{
+			if (msgFunc&EPanicWservMessAsynchronousService)
+				{
+				wshacker.PanicItSend(msgFunc);
+				// Async request, probably won't panic, we just want to make sure nothing crashes 'orribly
+				// So do it again without the async bit and let normal handling cause the panic
+				msgFunc&=~EPanicWservMessAsynchronousService;
+				}
+			sendItErr=wshacker.PanicItSendReceive(msgFunc);
+			}
+		else
+			{
+			TPtrC8 badDesc(reinterpret_cast<const TUint8*>(0xDEAD),100);
+			TIpcArgs ipcArgs;
+			ipcArgs.Set(0,&badDesc);
+			if (msgFunc&EPanicWservMessAsynchronousService)
+				{
+				sendItErr=wshacker.PanicItSend(msgFunc,ipcArgs);
+				msgFunc&=~EPanicWservMessAsynchronousService;
+				}
+			sendItErr=wshacker.PanicItSendReceive(msgFunc,ipcArgs);
+			}
+		if (sendItErr==KErrNotSupported)
+			wshacker.PanicItSendReceive(EWservMessCommandBuffer); // Should always panic
+		}
+	else
+		{
+	// Fill Wserv buffer with random garbage
+		RWsBufferHacker* hacker=reinterpret_cast<RWsBufferHacker*>(wshacker.WsBuffer());
+		TInt64 seed=aSubTest;
+		TInt retries=0;
+		const TInt KMaxRandPanicRetrys=1000;
+		do
+			{
+			const TInt maxLen=hacker->iBuf.MaxLength()-1;
+			TInt writeLen=1+Math::Rand(seed)%maxLen;
+			while(writeLen--)
+				{
+				TUint8 randData=static_cast<TUint8>(Math::Rand(seed));
+				hacker->iBuf.Append(randData);
+				}
+			wshacker.Flush();
+			retries++;
+			} while(retries<KMaxRandPanicRetrys);
+		}
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoCMPanicTest(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+
+	switch(aInt)
+		{
+		case 1:
+			ws.ComputeMode((RWsSession::TComputeMode)543);
+			break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+#if defined(_DEBUG) && defined(__WINS__)
+LOCAL_C TInt DoCKPanicTest(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+
+	RWindowGroup group(ws);
+	group.Construct(888);
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	switch(aInt)
+		{
+		case 1:
+			group.CancelCaptureKey(345);
+			break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+#endif
+
+LOCAL_C TInt DoEventPanicTest(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+
+
+	switch(aInt)
+		{
+		case 1:
+			TRequestStatus stat;
+			ws.EventReady(&stat);
+			ws.EventReady(&stat);
+			User::After(15000000);		//15secs
+			break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoTBufPtrTests(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	switch(aInt)
+		{
+		case 1:
+			{
+			TWsClCmdLoadAnimDll dt;
+			dt.length=600;
+			ws.TestWrite(ws.WsHandle(),EWsClOpCreateAnimDll,&dt,sizeof(dt));
+			}
+			break;
+		case 2:
+			{
+			TInt len=600;
+			ws.TestWrite(ws.WsHandle(),EWsClOpLogMessage,&len,sizeof(len));
+			}
+			break;
+		case 3:
+			{
+			RWindowGroup group(ws);
+			group.Construct(888);
+			group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+			TWsWinCmdSetName dt;
+			dt.length=600;
+			dt.ptr=NULL;
+			ws.TestWrite(group.WsHandle(),EWsWinOpSetName,&dt,sizeof(dt));
+			}
+			break;
+		case 4:
+			{
+			RWindowGroup group(ws);
+			group.Construct(888);
+			group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+			TWsWinCmdSetName dt;
+			dt.length=600;
+			dt.ptr=(TDesC *)0x1234;
+			ws.TestWrite(group.WsHandle(),EWsWinOpSetName,&dt,sizeof(dt));
+			}
+			break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+#if defined(_DEBUG) && defined(__WINS__)		
+LOCAL_C TInt DoMismatchedCancelCaptureTest(TInt aInt, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen		
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	RWindow win(ws);
+	User::LeaveIfError(win.Construct(group, 1));
+	win.Activate();
+	TInt capture;
+	
+	switch (aInt)
+		{
+		case CTPanic::ECancelCaptureKey:
+			// Create a capture that is not matched to CancelCaptureKey()
+			capture = group.CaptureLongKey(' ','a',0,0,2,ELongCaptureNormal);
+			ws.Flush();
+			group.CancelCaptureKey(capture);
+			break;
+		case CTPanic::ECancelCaptureKeyUpAndDowns:
+			// Create a capture that is not matched to CancelCaptureKeyUpAndDowns()
+			capture = group.CaptureKey('A',0,0);
+			ws.Flush();
+			group.CancelCaptureKeyUpAndDowns(capture);
+			break;
+		case CTPanic::ECancelCaptureLongKey:
+			// Create a capture that is not matched to CancelCaptureLongKey()
+			capture = group.CaptureKeyUpAndDowns(EStdKeySpace,0,0);
+			ws.Flush();
+			group.CancelCaptureLongKey(capture);
+			break;
+		}
+	
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+#endif // _DEBUG
+
+class ROverrideProtectionInRSessionBase : public RWsSession
+	{
+public:
+	inline TInt SendReceive(TInt aFunction,TAny *aPtr) const {return(RSessionBase::SendReceive(aFunction,TIpcArgs(aPtr)));};
+	};
+
+LOCAL_C TInt DoMultiInitPanicTest(TInt , TAny *aScreenNumber)
+	{
+	ROverrideProtectionInRSessionBase ws;
+	User::LeaveIfError(ws.Connect());
+	
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	group.Construct(888);
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	ws.Flush();
+	ws.SendReceive(EWservMessInit,NULL);
+	
+	return(EWsExitReasonBad);
+	}
+	
+LOCAL_C TInt DoSpritePanicTestL(TInt aTest, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(889));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	RBlankWindow win(ws);
+	User::LeaveIfError(win.Construct(group,898));
+	RWsPointerCursor* cursor=(RWsPointerCursor*)&win;
+	switch (aTest)
+		{
+	case 1:
+		win.SetCustomPointerCursor(*cursor);
+		break;
+	case 2:
+		ws.SetSystemPointerCursor(*cursor,0);
+		break;
+	case 3:
+		{
+		RAnimDll animDll=RAnimDll(ws);
+		User::LeaveIfError(animDll.Load(KAnimDLLName));
+		RTestAnim anim=RTestAnim(animDll);
+		RWsSprite* sprite=(RWsSprite*)&win;
+		User::LeaveIfError(anim.Construct(*sprite,EAnimTypeSprite,TPtrC8()));
+		}
+		break;
+	case 4:
+		{
+		CFbsBitmap* bitmap=new(ELeave) CFbsBitmap;
+		CleanupStack::PushL(bitmap);
+		User::LeaveIfError(bitmap->Load(TEST_BITMAP_NAME,0));
+		win.SetExtent(TPoint(),TSize(150,250));
+		win.SetVisible(ETrue);
+		win.Activate();
+		RWsSprite sprite(ws);
+		User::LeaveIfError(sprite.Construct(win,TPoint(),0));
+		TSpriteMember member;
+		member.iMaskBitmap=NULL;
+		member.iInvertMask=EFalse;
+		member.iDrawMode=CGraphicsContext::EDrawModePEN;
+		member.iOffset=TPoint();
+		member.iInterval=TTimeIntervalMicroSeconds32(0);
+		member.iBitmap=bitmap;
+		User::LeaveIfError(sprite.AppendMember(member));
+		User::LeaveIfError(sprite.Activate());
+		User::After(1000000); //1 sec
+		User::LeaveIfError(bitmap->Resize(bitmap->SizeInPixels() + TSize(200,200)));
+		User::After(1000000); //1 sec
+		CleanupStack::Pop(bitmap);
+		break;
+		}
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+#ifdef __WINS__
+LOCAL_C TInt DoDoubleConstructionTestL(TInt aTest, TAny *aScreenNumber)
+	{		
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new(ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(890, EFalse));
+	RBlankWindow bwin(ws);
+	User::LeaveIfError(bwin.Construct(group,900));
+	
+	switch (aTest)
+		{
+	case 1:
+		{
+		RWsSprite sprite = RWsSprite(ws);
+		User::LeaveIfError(sprite.Construct(bwin,TPoint(),0));
+		sprite.Construct(bwin,TPoint(),0); //should panic
+		sprite.Close();
+		}
+		break;
+	case 2:
+		{
+		RWsPointerCursor cursor(ws);
+		User::LeaveIfError(cursor.Construct(0));
+		cursor.Construct(0); //should panic
+		cursor.Close();
+		}
+		break;
+	case 3:
+		{
+		RSoundPlugIn click(ws);
+		User::LeaveIfError(click.Construct());
+		click.Construct(); //should panic
+		click.Close();
+		}
+		break;
+	case 4:
+		{
+		RWindowGroup windowgroup(ws);
+		User::LeaveIfError(windowgroup.Construct(901));
+		windowgroup.Construct(902); //should panic
+		windowgroup.Close();
+		}
+		break;
+	case 5:
+		{
+		RWindow win(ws);
+		User::LeaveIfError(win.Construct(group,902));
+		win.Construct(group,903); //should panic
+		win.Close(); 
+		}
+		break;
+	case 6:
+		{
+		RBlankWindow win(ws);
+		User::LeaveIfError(win.Construct(group,902));
+		win.Construct(group,903); //should panic
+		win.Close(); 
+		}
+		break;
+	case 7:
+		{
+		RBackedUpWindow win(ws);
+		User::LeaveIfError(win.Construct(group,EGray4,902));
+		win.Construct(group,EGray4,903); //should panic
+		win.Close(); 
+		}
+		break;
+	case 8:
+		{
+		RAnimDll animDll=RAnimDll(ws);
+		User::LeaveIfError(animDll.Load(KAnimDLLName));
+		animDll.Load(KAnimDLLName); //should panic
+		animDll.Close();
+		}
+		break;
+	case 9:
+		{
+		CWindowGc *gc = new(ELeave) CWindowGc(screen);
+		User::LeaveIfError(gc->Construct());
+		gc->Construct(); //should panic
+		delete gc;
+		}
+		break;
+	case 10:
+		{
+		CWsScreenDevice* screendevice = new (ELeave) CWsScreenDevice(ws);
+		User::LeaveIfError(screendevice->Construct());
+		screendevice->Construct(); //should panic
+		delete screendevice;
+		}
+		break;
+	default:
+		break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+#endif
+
+/** Checks that activating a sprite without members will panic.
+*/
+LOCAL_C TInt DoTestSpriteActivatePanicL(TInt aTest, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	CWsScreenDevice* screen = new(ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(891, EFalse, screen));
+	RBlankWindow bwin(ws);
+	User::LeaveIfError(bwin.Construct(group,892));
+	
+	switch(aTest)
+		{
+	case 1:
+		{
+		RWsSprite sprite = RWsSprite(ws);
+		User::LeaveIfError(sprite.Construct(group,TPoint(),0));
+		sprite.Activate();	//should panic here
+		sprite.Close();
+		}
+		break;
+	case 2:
+		{
+		RWsSprite sprite = RWsSprite(ws);
+		User::LeaveIfError(sprite.Construct(bwin,TPoint(),0));
+		sprite.Activate();	//should panic here
+		sprite.Close();
+		}
+		break;
+		}
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoMoveToGroupPanicTestL(TInt aTest, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// use correct screen
+	//
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(887));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	TInt id=group.Identifier();
+	switch (aTest)
+		{
+	case 1:
+		{
+		RWindowTreeNode* win=&group;
+		((RWindowBase*)win)->MoveToGroup(id);
+		}
+		break;
+	case 2:
+		{
+		RBlankWindow win1(ws);
+		User::LeaveIfError(win1.Construct(group,878));
+		RBlankWindow win2(ws);
+		User::LeaveIfError(win2.Construct(win1,788));
+		win2.MoveToGroup(id);
+		}
+		break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoGetEventPanicTestL(TInt aTest, TAny *aScreenNumber)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	switch(aTest)
+		{
+	case 1:
+		{
+		TPckgBuf<TWsEvent> event;
+		ws.TestWrite(ws.WsHandle(),EWsClOpGetEvent,&event,0);
+		}
+		break;
+	case 2:
+		{
+		CWsScreenDevice* screen=new(ELeave) CWsScreenDevice(ws);
+		User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+		RWindowGroup group(ws);
+		User::LeaveIfError(group.Construct(555));	// trigger a focus changed event
+		TRequestStatus stat;
+		ws.EventReady(&stat);
+		User::WaitForRequest(stat);
+		TPtrC8 badDesc(reinterpret_cast<const TUint8*>(0xDEAD),100);
+		ws.TestWrite(ws.WsHandle(),EWsClOpGetEvent,&badDesc,0);
+		}
+		break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+LOCAL_C TInt DoWinHandlePanicTestL(TInt aTest, TAny *)
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	RWindowGroup group1(ws);
+	RWindowGroup group2(ws);
+	RWindow win1(ws);
+	RWindow win2(ws);
+	switch(aTest)
+		{
+	case 1:
+		User::LeaveIfError(group1.Construct(888));
+		User::LeaveIfError(group2.Construct(888));
+		break;
+	case 2:
+		User::LeaveIfError(group1.Construct(777));
+		User::LeaveIfError(win1.Construct(group1,888));
+		User::LeaveIfError(win2.Construct(group1,888));
+		break;
+	case 3:
+		User::LeaveIfError(group1.Construct(777));
+		User::LeaveIfError(win1.Construct(group1,777));
+		break;
+	case 4:
+		User::LeaveIfError(group1.Construct(777));
+		User::LeaveIfError(win1.Construct(group1,0));
+		break;
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+
+#ifdef __WINS__
+LOCAL_C TInt DoDeleteScreenPanicTestL(TInt aTest, TAny *aScreenNumber)
+/**
+ * Test examples of use of the 'screen device deleted' panic for group windows.
+ * This is issued to panic the client, if they make API calls to RWindowGroup after having deleted
+ * the CWsScreenDevice with which that window group is associated.
+ */
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	// point to correct screen
+	CWsScreenDevice* screen = new (ELeave) CWsScreenDevice(ws);
+	User::LeaveIfError(screen->Construct((TInt)aScreenNumber));
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(888));
+	group.EnableReceiptOfFocus(EFalse);	// Stop auto group switching on close
+	switch(aTest)
+		{
+		// Test 1: deleting screen then modifying screen change events is illegal
+		case 1:
+			{
+			delete screen, screen=NULL;
+			group.EnableScreenChangeEvents();
+			break;
+			}
+		// Test 2: deleting screen then setting window group name is illegal
+		case 2:
+			{
+			delete screen, screen=NULL;
+			_LIT(KPanicTest, "PanicTest");
+			group.SetName(KPanicTest);
+			break;
+			}
+		}
+	ws.Flush();
+	return(EWsExitReasonBad);
+	}
+#endif
+
+LOCAL_C TInt DoUnInitPanicTest(TInt , TAny *)
+	{
+	// Creating a client session outside the test harness for panicking
+	//  before initialisation as the test harness initialises the one it creates.
+	TVersion version(0,0,0);
+	_LIT(KServerName, "!Windowserver");
+	
+	RUnInitalisedConnect myUnInit;
+
+	User::LeaveIfError(myUnInit.Connect(KServerName(), version));
+	myUnInit.Send(EWservMessCommandBuffer);
+	
+	return(EWsExitReasonBad);
+	}
+
+void CTPanic::TestScreenDevicePanicsL()
+	{
+	TEST(iTest->TestWsPanicL(&DoScreenDevicePanicTest,EWservPanicBitmap,1,(TAny*)iTest->iScreenNumber));
+	
+	TEST(iTest->TestWsPanicL(&DoScreenDevicePanicTest,EWservPanicBitmap,2,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestMiscPanicsL()
+	{
+	TBool finished=EFalse;
+	TInt index=0;
+	while(!finished)
+		{
+		const TBool result = iTest->TestWsPanicL(&DoMiscPanicTest, EWservNoPanic, index, NULL, &finished);
+		if(!result)
+			{
+			INFO_PRINTF2(_L("TestMiscPanicsL %d failed"), index);
+			TEST(result);
+			}
+		index++;
+		}
+	}
+
+void CTPanic::LogHeapInfo()
+	{
+	_LIT(KInfoHeapSummary," WsHeap - Count=%d,Total=%d,Free=%d,Max free=%d");
+	TPckgBuf<TWsDebugHeapInfo> heapInfo;
+	TheClient->iWs.DebugInfo(EWsDebugInfoHeap,heapInfo);
+	TBuf<256> infoBuf;
+	infoBuf.Format(KInfoHeapSummary,heapInfo().iCount,heapInfo().iTotal,heapInfo().iAvailable,heapInfo().iLargestAvailable);
+	INFO_PRINTF1(infoBuf);
+	}
+
+void CTPanic::TestGraphicsPanicsL(TClientPanic aExitReason, TInt aIndex, CTPanic::TPanicParams* aPanicParams)
+	{
+	TBool finished=EFalse;
+	aPanicParams->iSubTest=0;
+
+	// uncomment to show which test is being run
+	INFO_PRINTF3(_L("GraphicsPanicTest %d, mode=%d"),aIndex,aPanicParams->iRedrawMode);
+    RDebug::Print(_L("GraphicsPanicTest %d, mode=%d"),aIndex,aPanicParams->iRedrawMode);
+	do
+		{
+		// uncomment for detailed view of which sub-test failed
+		LogHeapInfo();
+		INFO_PRINTF4(_L("GraphicsPanicTest %d/%d, mode=%d"),aIndex,aPanicParams->iSubTest,aPanicParams->iRedrawMode);
+		RDebug::Print(_L("GraphicsPanicTest %d/%d, mode=%d"),aIndex,aPanicParams->iSubTest,aPanicParams->iRedrawMode);
+		TEST(iTest->TestWsPanicL(&GraphicsPanicTest,aExitReason,aIndex,aPanicParams,&finished));
+		aPanicParams->iSubTest++;
+		} while(!finished);
+	iTest->CloseAllPanicWindows();
+	}
+
+void CTPanic::TestGraphicsPanicsL(TPanicRedrawMode aRedrawMode)
+	{
+	CTPanic::TPanicParams pp;
+	pp.iScreen=iTest->iScreenNumber;
+	pp.iRedrawMode=aRedrawMode;
+	static TClientPanic expectedPanics[]=
+		{
+		EWservPanicBufferPtr,
+		EWservPanicBitmap,
+		EWservPanicBitmap,
+		EWservPanicBitmap,
+		EWservPanicOpcode,
+		EWservPanicBadPolyData,
+		EWservPanicBadPolyData,
+		EWservPanicOpcode,
+		EWservPanicGcActive,
+		EWservPanicNoFont,
+		EWservPanicNoBrush,
+		EWservPanicDescriptor,
+		EWservPanicFont,
+		EWservNoPanic,	// Marks the end of the list
+		};
+	TInt panicIndex=0;
+	TClientPanic expectedPanic;
+	while((expectedPanic=expectedPanics[panicIndex++])!=EWservNoPanic)
+		{
+		TestGraphicsPanicsL(expectedPanic,panicIndex,&pp);
+		}
+	}
+
+void CTPanic::TestGraphicsPanicsL()
+	{
+	TestGraphicsPanicsL(EPanicRedrawModeBackedUpWindow);
+	TestGraphicsPanicsL(EPanicRedrawModeNormalRedraw);
+	if (TransparencySupportedL()==KErrNone)
+		{
+		TestGraphicsPanicsL(EPanicRedrawModeTransRedraw);
+		}
+	TestGraphicsPanicsL(EPanicRedrawModeInvisRedraw);
+	}
+
+void CTPanic::TestDeletedParentPanicsL()
+	{
+	TEST(iTest->TestWsPanicL(&DoDeletedParentTest,EWservPanicParentDeleted,1,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestHandleReUseL()
+	{
+	for (TInt ii=2;ii<6;++ii)
+		{
+		TEST(iTest->TestWsPanicL(&DoHandleReUse,EWservPanicHandle,ii,(TAny*)iTest->iScreenNumber));
+		}
+	}
+
+void CTPanic::TestComputeModePanicsL()
+	{
+	TEST(iTest->TestWsPanicL(&DoCMPanicTest,EWservPanicSetComputeMode,1,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestCaptureKeyPanicsL()
+	{
+// Run this test in debug on emulator only.
+// On a debug ROM the release version of the wserv.exe is included so the test can't be run as no panic happens. 
+#if defined(_DEBUG) && defined(__WINS__)
+	TEST(iTest->TestWsPanicL(&DoCKPanicTest,EWservPanicDestroy,1,(TAny*)iTest->iScreenNumber));
+#endif
+	}
+
+void CTPanic::TestEventPanicsL()
+	{
+	TEST(iTest->TestWsPanicL(&DoEventPanicTest,EWservPanicReadOutstanding,1,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestTPtrPanicsL()
+	{
+	TEST(iTest->TestWsPanicL(&DoTBufPtrTests,EWservPanicBufferPtr,1,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestOpcodePanicsL()
+	{
+	TInt param=1;
+	TBool finishTest = EFalse;
+	while(!finishTest)
+		{
+		TEST(iTest->TestWsPanicL(&DoOpcodeTests,EWservPanicOpcode,param,(TAny*)iTest->iScreenNumber,&finishTest));
+		param++;
+		}
+	}
+
+void CTPanic::TestMultiInitPanicL()
+	{
+	TEST(iTest->TestWsPanicL(&DoMultiInitPanicTest,EWservPanicReInitialise,0,(TAny*)iTest->iScreenNumber));
+	}
+
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0472
+
+@SYMDEF             DEF118618
+
+@SYMTestCaseDesc    Test defect fixes to system panics 
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that various defect fixes to system panics are correct.
+					Also verify that reconstructing a closed object will succeed.
+
+@SYMTestExpectedResults Panics respond correctly
+*/
+void CTPanic::TestDoubleConstructionL()
+	{
+#ifdef __WINS__
+	for(TInt test=1;test<11;test++)
+		{
+		TEST(iTest->TestW32PanicL(&DoDoubleConstructionTestL,EW32PanicGraphicDoubleConstruction,test,NULL));
+		}
+	TestDoubleConstructionNoPanic();
+#endif
+	}
+	
+/** Verifies the following scenario	is valid:
+	1. Create some wserv client-side objects.
+	2. Call Close on them.
+	3. Reconstruct them and they shouldn't panic this time. */
+void CTPanic::TestDoubleConstructionNoPanic()
+	{
+	RWsSession ws;
+	User::LeaveIfError(ws.Connect());
+	
+	RWindowGroup group(ws);
+	User::LeaveIfError(group.Construct(890, EFalse));
+	RBlankWindow bwin(ws);
+	User::LeaveIfError(bwin.Construct(group,900));
+	
+	//RWsSprite
+	RWsSprite sprite(ws);
+	TEST(KErrNone == sprite.Construct(bwin,TPoint(0,0),0));
+	sprite.Close();
+	TEST(KErrNone == sprite.Construct(bwin,TPoint(0,0),0));
+	sprite.Close();
+	
+	//RWsPointerCursor
+	RWsPointerCursor cursor(ws);
+	TEST(KErrNone == cursor.Construct(0));
+	cursor.Close();
+	TEST(KErrNone == cursor.Construct(0));
+	cursor.Close();
+	
+	//RSoundPlugIn
+	RSoundPlugIn click(ws);
+	TEST(KErrNone == click.Construct());
+	click.Close();
+	TEST(KErrNone == click.Construct());
+	click.Close();
+	
+	//RWindowGroup
+	RWindowGroup windowgroup(ws);
+	TEST(KErrNone ==windowgroup.Construct(901));
+	windowgroup.Close();
+	TEST(KErrNone ==windowgroup.Construct(901));
+	windowgroup.Close();
+	
+	//RWindow
+	RWindow win1(ws);
+	TEST(KErrNone == win1.Construct(group,902));
+	win1.Close(); 
+	TEST(KErrNone == win1.Construct(group,902));
+	win1.Close(); 
+	
+	//RBlankWindow
+	RBlankWindow win2(ws);
+	TEST(KErrNone == win2.Construct(group,902));
+	win2.Close(); 
+	TEST(KErrNone == win2.Construct(group,902));
+	win2.Close();
+	
+	//RBackedUpWindow
+	RBackedUpWindow win3(ws);
+	TEST(KErrNone == win3.Construct(group,EGray4,902));
+	win3.Close();
+	TEST(KErrNone == win3.Construct(group,EGray4,902));
+	win3.Close(); 
+	
+	//RAnimDll
+	RAnimDll animDll=RAnimDll(ws);
+	TEST(KErrNone == animDll.Load(KAnimDLLName));
+	animDll.Close();
+	TEST(KErrNone == animDll.Load(KAnimDLLName));
+	animDll.Close();
+	
+	group.Close();
+	bwin.Close();
+	ws.Close();
+	}
+
+void CTPanic::TestSpritePanicsL()
+	{
+	for(TInt test=1;test<4;test++)
+		{
+		TEST(iTest->TestWsPanicL(&DoSpritePanicTestL,EWservPanicSprite,test,(TAny*)iTest->iScreenNumber));
+		}
+	}
+
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0475
+
+@SYMDEF             DEF118616
+
+@SYMTestCaseDesc    Test defect fixes to system panics 
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that various defect fixes to system panics are correct.
+
+@SYMTestExpectedResults Panics respond correctly
+*/
+void CTPanic::TestSpriteActivatePanicL()
+	{
+	for(TInt test=1;test<3;test++)
+		{
+		TEST(iTest->TestWsPanicL(&DoTestSpriteActivatePanicL,EWservPanicNoSpriteMember,test,NULL));
+		}
+	}
+
+void CTPanic::TestMoveToGroupPanicsL()
+	{
+	TEST(iTest->TestWsPanicL(&DoMoveToGroupPanicTestL,EWservPanicOpcode,1,(TAny*)iTest->iScreenNumber));
+	TEST(iTest->TestWsPanicL(&DoMoveToGroupPanicTestL,EWservPanicNotTopClient,2,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestDeleteScreenPanicL()
+	{
+#ifdef __WINS__
+	TEST(iTest->TestWsPanicL(&DoDeleteScreenPanicTestL,EWservPanicGroupWinScreenDeviceDeleted,1,(TAny*)iTest->iScreenNumber));
+	TEST(iTest->TestWsPanicL(&DoDeleteScreenPanicTestL,EWservPanicGroupWinScreenDeviceDeleted,2,(TAny*)iTest->iScreenNumber));
+#endif
+	}
+
+void CTPanic::TestWinHandleErrors()
+	{
+#ifdef __WINS__
+	TEST(iTest->TestWsPanicL(&DoWinHandlePanicTestL,EWservPanicDuplicateHandle,1));
+	TEST(iTest->TestWsPanicL(&DoWinHandlePanicTestL,EWservPanicDuplicateHandle,2));
+	TEST(iTest->TestWsPanicL(&DoWinHandlePanicTestL,EWservPanicDuplicateHandle,3));
+#endif
+	TEST(iTest->TestWsPanicL(&DoWinHandlePanicTestL,EWservPanicNullHandle,4));
+	}
+
+void CTPanic::TestGetEventErrors()
+	{
+	TEST(iTest->TestWsPanicL(&DoGetEventPanicTestL,EWservPanicUnsignalledEventData,1,(TAny*)iTest->iScreenNumber));
+	TEST(iTest->TestWsPanicL(&DoGetEventPanicTestL,EWservPanicDescriptor,2,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::TestUnInitPanicL()
+	{
+	TEST(iTest->TestWsPanicL(&DoUnInitPanicTest,EWservPanicUninitialisedClient,0,(TAny*)iTest->iScreenNumber));
+	}
+
+void CTPanic::ConstructL()
+	{
+	TheGc->Activate(*BaseWin->Win());
+	TheGc->Clear();
+	TheGc->SetBrushColor(TRgb::Gray16(12));
+	TheGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+	TheGc->SetPenStyle(CGraphicsContext::ENullPen);
+	TheGc->DrawRect(TRect(BaseWin->Win()->Size()));
+	TheGc->Deactivate();
+	TheGc->Activate(*TestWin->Win());
+	TheGc->Clear();
+	TheGc->SetBrushColor(TRgb::Gray16(4));
+	TheGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+	TheGc->SetPenStyle(CGraphicsContext::ENullPen);
+	TheGc->DrawRect(TRect(TestWin->Win()->Size()));
+	TheGc->Deactivate();
+//
+	_LIT(KReportFullRom,"Warning full ROM, EikSrv present, panic dialogs may interfere with tests");
+	_LIT(KReportGoodRom,"ROM OK, No EikSrv present");
+	if (iTest->IsFullRomL())
+		{
+		INFO_PRINTF1(KReportFullRom);
+		}
+	else
+		{
+		INFO_PRINTF1(KReportGoodRom);
+		}
+	}
+
+void CTPanic::TestAlphaBlendingPanicL()
+	{
+	INFO_PRINTF1(_L("Masked transparency support has been removed."));
+	}
+	
+void CTPanic::TestMismatchedCaptureCancelPanicL()
+	{		
+// Run this test in debug on emulator only.
+// On a debug ROM the release version of the wserv.exe is included so the test can't be run as no panic happens. 
+#if defined(_DEBUG) && defined(__WINS__)		
+	TEST(iTest->TestWsPanicL(DoMismatchedCancelCaptureTest,EWservPanicDestroy,ECancelCaptureKey,(TAny*)iTest->iScreenNumber));
+	TEST(iTest->TestWsPanicL(DoMismatchedCancelCaptureTest,EWservPanicDestroy,ECancelCaptureKeyUpAndDowns,(TAny*)iTest->iScreenNumber));
+	TEST(iTest->TestWsPanicL(DoMismatchedCancelCaptureTest,EWservPanicDestroy,ECancelCaptureLongKey,(TAny*)iTest->iScreenNumber));
+#endif
+	}
+
+void CTPanic::RunTestCaseL(TInt /*aCurTestCase*/)
+	{
+	((CTPanicStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
+	switch(++iTest->iState)
+		{
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0259
+
+@SYMDEF             DEF081259
+
+@SYMTestCaseDesc    Test various system panics 
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that various system panics respond correctly 
+
+@SYMTestExpectedResults Panics respond correctly
+*/
+		case 1:
+			{
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0259"));
+			iTest->LogSubTest(_L("TestCaptureKeyPanicsL"));
+			TestCaptureKeyPanicsL();
+			}
+			break;
+		case 2:
+		    {
+			iTest->LogSubTest(_L("TestEventPanicsL"));
+			TestEventPanicsL();
+		    }
+		    break;
+		case 3:
+		    {
+			iTest->LogSubTest(_L("TestComputeModePanicsL"));
+			TestComputeModePanicsL();
+		    }
+		    break;
+		case 4:
+		    {
+#ifdef __WINS__
+//  Only running this under WINS as the tests are a bit excessive, firing off all sorts of illegal
+// opcode/flag combinations, as well as buffers of random data.
+// Currently on ARM builds they're failing with KErrOutOfMemory, probably running out of handles
+// somewhere in the OS.
+			iTest->LogSubTest(_L("TestMiscPanicsL"));
+			TestMiscPanicsL();
+#endif
+		    }
+		    break;
+		case 5:
+		    {
+			iTest->LogSubTest(_L("TestGraphicsPanicsL"));
+			TestGraphicsPanicsL();
+		    }
+		    break;
+		case 6:
+		    {
+			iTest->LogSubTest(_L("TestTPtrPanicsL"));
+			TestTPtrPanicsL();
+		    }
+		    break;
+		case 7:
+		    {
+			iTest->LogSubTest(_L("TestOpcodePanicsL"));
+			TestOpcodePanicsL();
+		    }
+		    break;
+		case 8:
+		    {
+			iTest->LogSubTest(_L("TestScreenDevicePanicsL"));
+			TestScreenDevicePanicsL();
+		    }
+		    break;
+		case 9:
+		    {
+			iTest->LogSubTest(_L("TestMultiInitPanicL"));
+			TestMultiInitPanicL();
+			}
+			break;
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0260
+
+@SYMDEF             DEF081259
+
+@SYMTestCaseDesc    Test various system panics 
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that various system panics respond correctly 
+
+@SYMTestExpectedResults Panics respond correctly
+*/
+		case 10:
+			{
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0260"));
+			iTest->LogSubTest(_L("Panic 2"));
+			TestSpritePanicsL();
+			TestMoveToGroupPanicsL();
+			}
+			break;
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0261
+
+@SYMDEF             DEF081259
+
+@SYMTestCaseDesc    Test defect fixes to system panics 
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that various defect fixes to system panics are correct 
+
+@SYMTestExpectedResults Panics respond correctly
+*/			
+		case 11:
+			{
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0261"));
+			_LIT(KPanicTest,"Defect Fixes (Pan.3)");
+			iTest->LogSubTest(KPanicTest);
+			TestDeletedParentPanicsL();
+			TestHandleReUseL();
+			TestDeleteScreenPanicL(); // DEF069809
+			}
+			break;
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-097969-0001
+
+@SYMDEF             DEF097969
+
+@SYMTestCaseDesc    Test defect fixes to system panics 
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that various defect fixes to system panics are correct 
+
+@SYMTestExpectedResults Panics respond correctly
+*/			
+		case 12:
+			{
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-097969-0001"));
+			_LIT(KPanicTest,"Server panic defect Fix (Pan.4)");
+			iTest->LogSubTest(KPanicTest);
+			TestUnInitPanicL();	// DEF097969
+			}
+			break;
+		
+		case 13:
+			{
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0501
+*/
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0501"));
+			_LIT(KPanicTest,"AlphaBlending Bitmap panic defect Fix (Pan.5)");
+			iTest->LogSubTest(KPanicTest);
+			TestAlphaBlendingPanicL();	// DEF112916
+			}
+			break;
+		case 14:
+			{		
+            ((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0472"));
+			_LIT(KPanicTest,"Double construction panic test");
+			iTest->LogSubTest(KPanicTest);
+			TestDoubleConstructionL();	// DEF118618
+			}
+			break;
+		case 15:
+			{
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0475"));
+			_LIT(KPanicTest, "RWsSprite Activate() without members panic test");
+			iTest->LogSubTest(KPanicTest);
+			TestSpriteActivatePanicL(); //DEF118616				
+			}
+			break;
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0497
+
+@SYMDEF             DEF133776
+
+@SYMTestCaseDesc     Test that a debug only panic occurs when an attempt
+ is made to cancel a key capture using the wrong cancel capture API.
+
+@SYMTestPriority    High
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Check that calling the each RWindowGroup::CancelCapture***() API
+ using the handle returned from a mismatched RWindowGroup::Capture***() call causes
+ a debug only panic. Tests each of the three RWindowGroup::CancelCapture***() APIs.
+
+@SYMTestExpectedResults Panics respond correctly in debug only.
+*/			
+		case 16:
+			{
+			((CTPanicStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0497"));
+			_LIT(KPanicTest,"TestMismatchedCaptureCancelPanicL");
+			iTest->LogSubTest(KPanicTest);
+			TestMismatchedCaptureCancelPanicL();				
+			}
+			break;			
+#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
+		case 17:
+			{
+			_LIT(KPanicTest, "Non-Redraw Drawing inside Redrawer Panic Test");
+			iTest->LogSubTest(KPanicTest);
+			TestNonRedrawRedrawerL();
+			}			
+#endif			
+		default:
+            		((CTPanicStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
+			((CTPanicStep*)iStep)->CloseTMSGraphicsStep();
+			TestComplete();
+			break;
+		}
+	((CTPanicStep*)iStep)->RecordTestResultL();
+	}
+
+#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
+LOCAL_C TInt DoTestNonRedrawRedrawerL(TInt /* aInt */, TAny * /* aPtr */)
+	{
+	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+	
+	RWsSession session;
+	User::LeaveIfError(session.Connect());
+	
+	CWsScreenDevice *screenDevice = new (ELeave)CWsScreenDevice(session);
+	User::LeaveIfError(screenDevice->Construct ());
+	CWindowGc *gc;
+	User::LeaveIfError(screenDevice->CreateContext(gc));
+	
+	CNonRedrawWin *nonRedrawWin=CNonRedrawWin::NewL(session, gc);	
+	nonRedrawWin->Invalidate(); 
+	CActiveScheduler::Start();
+	User::After(2000000); // so the Redrawer has a chance to run 
+	CActiveScheduler::Stop();
+	delete gc;
+	delete screenDevice;
+	session.Close();
+	CleanupStack::PopAndDestroy(scheduler);
+	return(EWsExitReasonBad);
+	}
+
+/**
+@SYMTestCaseID		GRAPHICS-WSERV-0121808
+@SYMDEF             DEF121808: No more Non-Redraw drawing for NGA (test added during DEF134308) 
+@SYMTestCaseDesc    Test defect fixes to system panics 
+@SYMTestPriority    High
+@SYMTestStatus      Implemented
+@SYMTestActions     Check that WServ panics a client which uses Non-Redraw drawing in the Redrawer.
+@SYMTestExpectedResults Panics respond correctly
+*/
+void CTPanic::TestNonRedrawRedrawerL()
+	{
+	TEST(iTest->TestWsPanicL(&DoTestNonRedrawRedrawerL,EWservPanicWindowBeginRedrawNotCalled,NULL,NULL));
+	}
+
+CNonRedrawWin::CRedrawer::CRedrawer(CNonRedrawWin* aWd) :
+	CActive(CActive::EPriorityStandard), iWd(aWd){
+	CActiveScheduler::Add(this);
+	HandleRedrawEvent();	
+}
+
+CNonRedrawWin::CRedrawer::~CRedrawer(){
+	Cancel();
+}
+
+void CNonRedrawWin::CRedrawer::HandleRedrawEvent(){
+	iWd->GetSession().RedrawReady(&iStatus);
+	SetActive();
+}
+
+void CNonRedrawWin::CRedrawer::RunL(){
+	TWsRedrawEvent redrawEvent;
+	iWd->GetSession().GetRedraw(redrawEvent);	
+	iWd->Redraw();
+	HandleRedrawEvent();
+}
+
+void CNonRedrawWin::CRedrawer::DoCancel(){
+	iWd->GetSession().RedrawReadyCancel();
+}
+
+CNonRedrawWin* CNonRedrawWin::NewL(RWsSession &aSession, CWindowGc *aGc){
+	CNonRedrawWin* self=new(ELeave)CNonRedrawWin(aSession, aGc);
+	CleanupStack::PushL(self);
+	self->ConstrucL();
+	CleanupStack::Pop(self);
+	return self;
+}
+
+CNonRedrawWin::CNonRedrawWin(RWsSession &aSession, CWindowGc *aGc):
+	iSession(aSession), iGc(aGc){}
+
+CNonRedrawWin::~CNonRedrawWin(){
+	delete iRedrawer;
+	iWd.Close();
+	iWdGrp.Close();	
+}
+
+void CNonRedrawWin::Redraw(){
+	// This is a Non-Redraw Drawing Redrawer; BeginRedraw()/EndRedraw()
+	// have been intentionally omitted.
+	iGc->Activate(iWd);	
+	iGc->SetBrushColor(TRgb(255,0,0));
+	iGc->SetPenColor(KRgbBlue);
+	iGc->SetPenSize(TSize(10,20));
+	iGc->DrawRect(TRect(TPoint(10,10),TPoint(50,50)));	
+	iGc->Deactivate();
+	iSession.Finish();			
+}
+
+RWsSession &CNonRedrawWin::GetSession(){return iSession;}
+
+void CNonRedrawWin::Invalidate(){iWd.Invalidate();}
+
+void CNonRedrawWin::ConstrucL(){
+	iWdGrp=RWindowGroup(iSession);	
+	iWdGrp.Construct((TUint32)this,ETrue);
+	_LIT(KWndGrpName,"NonRedrawWndGrp");
+	iWdGrp.SetName(KWndGrpName);	
+	iWd=RWindow(iSession);	
+	iWd.Construct(iWdGrp, 0x101);	
+	User::LeaveIfError(iWd.SetExtentErr(TPoint(0,0),TSize(150,150)));
+	iWd.SetBackgroundColor(KRgbWhite);
+	iWd.SetOrdinalPosition(0);	
+	iWd.Activate();	
+	iRedrawer=new(ELeave) CRedrawer(this);
+}
+#endif
+
+TInt RUnInitalisedConnect::Connect(const TDesC &aName, const TVersion &aVersion)
+	{
+	return CreateSession(aName, aVersion, 255);
+	}
+
+TInt RUnInitalisedConnect::Send(const TInt aMsg)
+	{
+	return SendReceive(aMsg);
+	}
+
+__WS_CONSTRUCT_STEP__(Panic)
+#pragma warning( disable : 4505 )