--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/tauto/tmultiptrevent.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,4846 @@
+// Copyright (c) 2008-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:
+// Multi pointer and Z-coordinate test code
+//
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+#ifndef __INIPARSER_H__
+#define __INIPARSER_H__
+#endif // __INIPARSER_H__
+
+#include "PARSEINIDATA.H"
+#include "tmultiptrevent.h"
+#include <e32cmn.h>
+#include <hal.h>
+
+//#define FAILLOG 1 // Uncomment this code to get detailed log
+#define TESTMULTIPOINTER 1 // Comment this line to get detailed log without testing
+
+_LIT(KMultiPtrPluginDll, "multiptrclick.dll");
+
+const TInt KErrDescSize = 128;
+const TInt KMaxQueueSize = 32; // Queue size of wserv. In any test we cannot test more than MaxQueueSize events.
+
+LOCAL_C void DestroyAnim(TAny* aAnim)
+ {
+ (static_cast<RMultiPointerAnim*>(aAnim))->Destroy();
+ }
+
+
+//CTMultiPtrEventBuffer
+CTMultiPtrEventBuffer::CTMultiPtrEventBuffer(RWsSession *aWs, CTMultiPtrEventTest *aTest, CTMultiPtrEventClient* aClient)
+ : CTEvent(aWs), iTest(aTest), iClient(aClient)
+ {
+ }
+
+void CTMultiPtrEventBuffer::ConstructL()
+ {
+ CTEventBase::Construct();
+ iEventBuffer.SetLengthL(EEventBufferSize);
+ iMovePtsBuffer.SetLengthL(EMovePtsBuffer);
+ }
+
+void CTMultiPtrEventBuffer::AddExpectedEvent(TWsEvent &aEvent)
+ {
+ iEventBuffer.Add(&aEvent);
+ }
+
+void CTMultiPtrEventBuffer::AddExpectedMovePtEvent(TPoint &aMovePt)
+ {
+ iMovePtsBuffer.Add(&aMovePt);
+ }
+
+TInt CTMultiPtrEventBuffer::EventsRemaining()
+ {
+ return iEventBuffer.Count();
+ }
+
+void CTMultiPtrEventBuffer::GetMoveBufferAndCompareL()
+ {
+ TBuf8<EMovePtsBuffer*sizeof(TPoint)> buf;
+ iClient->ParentWin()->BaseWin()->RetrievePointerMoveBuffer(buf);
+
+ TUint bufferSize = buf.Length();
+ TUint numLoop = bufferSize/sizeof(TPoint);
+
+ if (iMovePtsBuffer.Count() != numLoop)
+ {
+#if defined(FAILLOG)
+ TLogMessageText logText;
+ _LIT(KPointerNumber, "Actual number of move/drag buffer points from Wserv = %d Expected number of move/drag buffer points = %d ");
+ logText.Format(KPointerNumber, numLoop, iMovePtsBuffer.Count());
+ iTest->LOG_MESSAGE(logText);
+#endif
+ TestL(EFalse);
+ }
+
+ TPoint wsPoint;
+ TPoint expPoint;
+ TUint8* BasePtr = const_cast<TUint8*>(buf.Ptr());
+ for (TUint count = 0; count < numLoop; count++)
+ {
+ wsPoint = *(reinterpret_cast<TPoint*>(BasePtr));
+ iMovePtsBuffer.Remove(&expPoint);
+ if (wsPoint != expPoint)
+ {
+#if defined(FAILLOG)
+ TLogMessageText logText;
+ _LIT(KMoveBufferPoint, "Actual move/drag buffer point from Wserv = ([%d], [%d]) Expected move/drag buffer point = ([%d], [%d])");
+ logText.Format(KMoveBufferPoint, wsPoint.iX, wsPoint.iY, expPoint.iX, expPoint.iY);
+ iTest->LOG_MESSAGE(logText);
+#endif
+ TestL(EFalse);
+ }
+ BasePtr = BasePtr + sizeof(TPoint);
+ }
+ }
+
+
+#define TESTXL(expr1, oper, expr2, event, expected) \
+ TestL(expr1 oper expr2, expr1, expr2, #oper, #expr1 ## #oper ## #expr2, \
+ event, expected, __FILE__, __LINE__);
+
+// Main function which gets the event, checks with the event in buffer
+// Then calls function NextSetOfEventsL for running other tests of a particualar test case
+void CTMultiPtrEventBuffer::doRunL()
+ {
+ // Get the event from wserv
+ TWsEvent wsEvent;
+ iWs->GetEvent(wsEvent);
+
+ TWsEvent expectedEvent;
+ TInt wsType=wsEvent.Type();
+ if (wsEvent.Type()==EEventNull)
+ {
+ TESTXL(wsEvent.Handle(), ==, 0, &wsEvent, NULL);
+ goto End;
+ }
+ // This code is for running successive anim test code
+ if (wsEvent.Type()==EEventPointer && wsEvent.Pointer()->iType == TPointerEvent::ESwitchOn)
+ {
+ goto End;
+ }
+
+ // if this is called accidentally
+ TInt count=iEventBuffer.Count();
+ if (count==0 && wsType==EEventFocusGained)
+ {
+ goto End;
+ }
+
+ iEventBuffer.Remove(&expectedEvent);
+
+ iEventCount++;
+
+ if (wsEvent.Type() == EEventPointerBufferReady)
+ {
+ GetMoveBufferAndCompareL();
+#if defined(FAILLOG)
+ TLogMessageText logText;
+ _LIT(KEventHandle, "Actual Window Handle from Wserv = %d Expected Window Handle = %d ");
+ logText.Format(KEventHandle, wsEvent.Handle(), expectedEvent.Handle());
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(wsEvent.Handle(), ==, expectedEvent.Handle(), &wsEvent, &expectedEvent);
+#endif
+ goto End;
+ }
+
+ // Test wsEvent and expected event have same handle, position and type.
+#if defined(FAILLOG)
+ TLogMessageText logText;
+ _LIT(KEventCountCheck, "Checking event number = %d");
+ logText.Format(KEventCountCheck, iEventCount);
+ iTest->LOG_MESSAGE(logText);
+ _LIT(KEventType, "Actual Event type from Wserv = %d Expected Event Type = %d ");
+ logText.Format(KEventType, wsEvent.Type(), expectedEvent.Type());
+ iTest->LOG_MESSAGE(logText);
+#endif
+
+#if defined(TESTMULTIPOINTER)
+ TESTXL(wsEvent.Type(), ==, expectedEvent.Type(), &wsEvent, &expectedEvent);
+#endif
+ // Test pointer number for Enter/Exit events
+ if (wsType == EEventPointerEnter || wsType == EEventPointerExit)
+ {
+#if defined(FAILLOG)
+ _LIT(KPointerNumber, "Actual PointerNumber for Enter/Exit event from Wserv = %d Expected PointerNumber for Enter/Exit event = %d ");
+ logText.Format(KPointerNumber, *wsEvent.Int(), *expectedEvent.Int());
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(*wsEvent.Int(), ==, *expectedEvent.Int(), &wsEvent, &expectedEvent);
+#endif
+ }
+
+ TAdvancedPointerEvent *expectedPointerEvent = expectedEvent.Pointer();
+ TAdvancedPointerEvent *actualPointerEvent = wsEvent.Pointer();
+
+ // Test only if it is a Pointer event
+ if (wsType == EEventPointer)
+ {
+#if defined(FAILLOG)
+ _LIT(KEventHandle, "Actual Window Handle from Wserv = %d Expected Window Handle = %d ");
+ logText.Format(KEventHandle, wsEvent.Handle(), expectedEvent.Handle());
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(wsEvent.Handle(), ==, expectedEvent.Handle(), &wsEvent, &expectedEvent);
+#endif
+#if defined(FAILLOG)
+ _LIT(KPointerType, "Actual PointerType from Wserv = %d Expected PointerType = %d ");
+ logText.Format(KPointerType, actualPointerEvent->iType, expectedPointerEvent->iType);
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(actualPointerEvent->iType, ==, expectedPointerEvent->iType, &wsEvent, &expectedEvent);
+#endif
+#if defined(FAILLOG)
+ _LIT(KPointerPosition, "Actual PointerPosition from Wserv = (%d, %d) Expected PointerPosition = (%d, %d) ");
+ logText.Format(KPointerPosition, actualPointerEvent->iPosition.iX, actualPointerEvent->iPosition.iY, expectedPointerEvent->iPosition.iX, expectedPointerEvent->iPosition.iY);
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(actualPointerEvent->iPosition, ==, expectedPointerEvent->iPosition, &wsEvent, &expectedEvent);
+#endif
+#if defined(FAILLOG)
+ _LIT(KPointerNumber, "Actual PointerNumber from Wserv = %d Expected PointerNumber = %d ");
+ logText.Format(KPointerNumber, actualPointerEvent->PointerNumber(), expectedPointerEvent->PointerNumber());
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(actualPointerEvent->PointerNumber(), ==, expectedPointerEvent->PointerNumber(), &wsEvent, &expectedEvent);
+#endif
+#if defined(FAILLOG)
+ _LIT(KPointerProximity, "Actual PointerProximity from Wserv = %d Expected PointerProximity = %d ");
+ logText.Format(KPointerProximity, actualPointerEvent->Proximity(), expectedPointerEvent->Proximity());
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(actualPointerEvent->Proximity(), ==, expectedPointerEvent->Proximity(), &wsEvent, &expectedEvent);
+#endif
+#if defined(FAILLOG)
+ _LIT(KPointerPressure, "Actual PointerPressure from Wserv = %d Expected PointerPressure = %d ");
+ logText.Format(KPointerPressure, actualPointerEvent->Pressure(), expectedPointerEvent->Pressure());
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL(actualPointerEvent->Pressure(), ==, expectedPointerEvent->Pressure(), &wsEvent, &expectedEvent);
+#endif
+#if defined(FAILLOG)
+ _LIT(KPointerModifier, "Actual Modifier value from Wserv = 0x%08x Expected Modfier value = 0x%08x ");
+ logText.Format(KPointerModifier, actualPointerEvent->iModifiers, expectedPointerEvent->iModifiers);
+ iTest->LOG_MESSAGE(logText);
+#endif
+#if defined(TESTMULTIPOINTER)
+ TESTXL((actualPointerEvent->iModifiers&expectedPointerEvent->iModifiers), ==, expectedPointerEvent->iModifiers, &wsEvent, &expectedEvent);
+#endif
+ }
+End:
+ // Call NextSetOfEvents() only for primary client
+ if (iEventBuffer.Count()==0 && !iClient->IsSecondaryClient())
+ {
+ iTest->NextSetOfEventsL(); // Cannot Leave
+ }
+
+ // If this is for secondary client and active scheduler(nested loop) has started, this code stops that scheduler
+ if (iEventBuffer.Count()==0 && iClient->IsSecondaryClient() && iNestedLoopStarted)
+ {
+ iNestedLoopStarted = EFalse;
+ CActiveScheduler::Stop();
+ }
+ }
+
+void CTMultiPtrEventBuffer::TestL(TInt aTest)
+ {
+ if (!aTest)
+ {
+ iTest->Failed();
+ User::Leave(ETestFailed);
+ }
+ }
+
+static void DumpEvent(const char *aName, const TWsEvent *aEvent)
+ {
+ // aEvent may be NULL - if it isn't NULL, we print it's data.
+ if (aEvent)
+ {
+ RDebug::Printf("%s:", aName);
+ RDebug::Printf("handle = %u", aEvent->Handle());
+ RDebug::Printf("type() = %d", aEvent->Type());
+ if (aEvent->Type() == EEventPointer)
+ {
+ TAdvancedPointerEvent *pointer = aEvent->Pointer();
+ RDebug::Printf("pointer type = %d, position = (%d, %d)",
+ pointer->iType, pointer->iPosition.iX, pointer->iPosition.iY);
+ RDebug::Printf("PointerNumber() = %d, proximity=%d, pressure=%d",
+ pointer->PointerNumber(), pointer->Proximity(), pointer->Pressure());
+ RDebug::Printf("modifiers = 0x%08x", pointer->iModifiers);
+ }
+ else
+ {
+ RDebug::Printf("Not a pointer event, event type");
+ }
+ }
+ else
+ {
+ // aEvent is NULL, just let us know it is.
+ RDebug::Printf("%s: is NULL which means not applicapable");
+ }
+ }
+
+void CTMultiPtrEventBuffer::TestL(TInt aTest, TInt aVal1, TInt aVal2, const char *aOper, const char *aTestStr,
+ const TWsEvent *aEvent, const TWsEvent *aExpected, const char *aFile, TUint aLine)
+ {
+ if (!aTest)
+ {
+ RDebug::Printf("Expression %d %s %d [%s] (=%d) failed [call from %s:%d]", aVal1, aOper, aVal2, aTestStr, aTest, aFile, aLine);
+ DumpEvent("actual", aEvent);
+ DumpEvent("expected", aExpected);
+ iTest->Failed();
+ User::Leave(ETestFailed);
+ }
+ }
+
+
+void CTMultiPtrEventBuffer::TestL(TInt aTest, TPoint aVal1, TPoint aVal2, const char *oper, const char *aTestStr,
+ const TWsEvent *aEvent, const TWsEvent *aExpected, const char *aFile, TUint aLine)
+ {
+ if (!aTest)
+ {
+ RDebug::Printf("Expression (%d, %d) %s (%d, %d) [%s] (=%d) failed [call from %s:%d]",
+ aVal1.iX, aVal1.iY, oper, aVal2.iX, aVal2.iY, aTestStr, aTest, aFile, aLine);
+ DumpEvent("actual", aEvent);
+ DumpEvent("expected", aExpected);
+ iTest->Failed();
+ User::Leave(ETestFailed);
+ }
+ }
+
+//CTMultiPtrEventClient
+CTMultiPtrEventClient::CTMultiPtrEventClient(CTMultiPtrEventTest *aTest, TBool aSecondaryClient)
+ : iTest(aTest), iSecondaryClient(aSecondaryClient)
+ {
+ }
+
+CTMultiPtrEventClient::~CTMultiPtrEventClient()
+ {
+ if (iWinAutoFocus1 || iWinAutoFocus2 || iGroupWinAutoFocus2 || iGroupWinAutoFocus1)
+ {
+ DeleteGroupBlankWin();
+ }
+ delete iChildWin;
+ delete iParentWin;
+ }
+
+void CTMultiPtrEventClient::ConstructL()
+ {
+ CTClient::ConstructL();
+
+ // Create a group window and assign it iGroup
+ iGroup = new(ELeave) CTWindowGroup(this);
+ iGroup->ConstructL();
+
+ iParentWinSize = iScreen->SizeInPixels();
+ iParentWinPos = TPoint();
+
+ // Change the parent window size and position for secondary client
+ if (iSecondaryClient)
+ {
+ iParentWinSize.iWidth /= 2;
+ iParentWinPos.iX = iParentWinSize.iWidth;
+ }
+
+ // Create window/s for this client so that events can come to this client
+ iParentWin=new(ELeave) CTBlankWindow();
+ iParentWin->ConstructL(*iGroup);
+ iParentWin->SetExt(iParentWinPos, iParentWinSize);
+ iParentWin->SetColor(KRgbRed);
+ if (iTest->TestBase()->iState != 12)
+ {
+ iParentWin->BaseWin()->EnableAdvancedPointers();
+ }
+ iParentWin->Activate();
+
+ // Don't create child window for secodary client
+ if (!iSecondaryClient)
+ {
+ iChildWinSize = TSize(iParentWinSize.iWidth/2, iParentWinSize.iHeight);
+ iChildWinPos = TPoint(iParentWinSize.iWidth/2,0);
+
+ iChildWin=new(ELeave) CTBlankWindow();
+ iChildWin->ConstructL(*iGroup);
+ iChildWin->SetExt(iChildWinPos, iChildWinSize);
+ iChildWin->SetColor(KRgbRed);
+ iChildWin->BaseWin()->EnableAdvancedPointers();
+ iChildWin->Activate();
+ }
+ }
+
+void CTMultiPtrEventClient::CalculatePtrPosAndSet3Ddata(TWsEvent& aEvent, TPointerEvent::TType aType, TPoint aPos, TUint aModifiers, TInt aZ, TUint8 aPointerNumber, TUint aHandle)
+ {
+ // If in future you need to change parent position then put this in corresponding if statements
+ aEvent.Pointer()->iParentPosition = aPos;
+
+ // This is for Auto foreground test
+ if (iTest->TestBase()->iState == 11)
+ {
+ if (TRect(iWinPosAutoFocus1, iWinSizeAutoFocus1).Contains(aPos))
+ {
+ aPos -= iWinPosAutoFocus1;
+ aEvent.SetHandle((TUint)iWinAutoFocus1);
+ }
+ else if (TRect(iWinPosAutoFocus2, iWinSizeAutoFocus2).Contains(aPos))
+ {
+ aPos -= iWinPosAutoFocus2;
+ aEvent.SetHandle((TUint)iWinAutoFocus2);
+ }
+ goto SETOTHERDATA;
+ }
+
+ // Here simulated pointer position is w.r.t to 0,0
+ // Actual pointer position is w.r.t windowPosition
+ if (iSecondaryClient)
+ {
+ if (TRect(iParentWinPos, TSize(iParentWinSize.iWidth, iParentWinSize.iHeight)).Contains(aPos))
+ {
+ // Since for secondary client parent window is at half of screensize
+ aPos -= iParentWinPos;
+ aEvent.SetHandle((aHandle == 0) ? (TUint)iParentWin : aHandle);
+ }
+ }
+ else
+ {
+ // If sent position is on blankWindow then
+ if (TRect(iParentWinPos, TSize(iParentWinSize.iWidth/2, iParentWinSize.iHeight)).Contains(aPos))
+ {
+ aEvent.SetHandle((aHandle == 0) ? (TUint)iParentWin : aHandle);
+ }
+ else // else the pointer event occured on child window
+ {
+ // if aPos < 0 then position has been generated in test code and should not be adjusted
+ if (aPos.iX >= 0)
+ {
+ aPos -= iChildWinPos;
+ }
+ aEvent.SetHandle((aHandle == 0) ? (TUint)iChildWin : aHandle);
+ }
+ }
+
+SETOTHERDATA:
+ aEvent.Pointer()->iType = aType;
+ aEvent.Pointer()->iPosition = aPos;
+ if(iExpectNonAdvancedPointerEvents)
+ {
+ aEvent.Pointer()->iModifiers = aModifiers;
+ }
+ else
+ {
+ aEvent.Pointer()->iModifiers = aModifiers|EModifierAdvancedPointerEvent;
+ aEvent.SetPointerNumber(aPointerNumber);
+ aEvent.SetPointerZ(aZ);
+ }
+ }
+
+void CTMultiPtrEventClient::AddExpectedPointerEvent(TPointerEvent::TType aType, TPoint aPos, TUint8 aPointerNumber, TUint aHandle)
+ {
+ AddExpectedPointerEvent(aType, aPos, 0, 0, aPointerNumber, aHandle);
+ }
+
+void CTMultiPtrEventClient::AddExpectedPointerEvent(TPointerEvent::TType aType, TPoint aPos, TInt aZ, TUint aModifier, TUint8 aPointerNumber, TUint aHandle)
+ {
+ TWsEvent ptrEvent;
+ ptrEvent.SetType(EEventPointer);
+ if (aType != TPointerEvent::ESwitchOn)
+ {
+ CalculatePtrPosAndSet3Ddata(ptrEvent, aType, aPos, aModifier, aZ, aPointerNumber, aHandle);
+ }
+ static_cast<CTMultiPtrEventBuffer*>(iEventHandler)->AddExpectedEvent(ptrEvent);
+ }
+
+void CTMultiPtrEventClient::AddExpectedWsEvent(TEventCode aType, TInt aPointerNumber, TUint aHandle)
+ {
+ TWsEvent ptrEvent;
+ ptrEvent.SetType(aType);
+ if (aType == EEventPointerEnter || aType == EEventPointerExit)
+ {
+ *ptrEvent.Int() = aPointerNumber;
+ }
+ if (aType == EEventPointerBufferReady)
+ {
+ ptrEvent.SetHandle(aHandle);
+ }
+ static_cast<CTMultiPtrEventBuffer*>(iEventHandler)->AddExpectedEvent(ptrEvent);
+ }
+
+void CTMultiPtrEventClient::AddExpectedMovePoint(TPoint aPos)
+ {
+ static_cast<CTMultiPtrEventBuffer*>(iEventHandler)->AddExpectedMovePtEvent(aPos);
+ }
+
+// Create and store CTMultiPtrEventBuffer in iEventHandler
+void CTMultiPtrEventClient::ConstructEventHandlerL()
+ {
+ CTMultiPtrEventBuffer* eventBufferAndHandler = new(ELeave) CTMultiPtrEventBuffer(&iWs, iTest, this);
+ eventBufferAndHandler->ConstructL();
+ iEventHandler = eventBufferAndHandler;
+ }
+
+// Create groupwindow and blank window for AutoFocus tests
+void CTMultiPtrEventClient::ConstructGroupBlankWinL()
+ {
+ iWinPosAutoFocus1 = TPoint(10,10);
+ iWinSizeAutoFocus1 = TSize(40,40);
+
+ iWinPosAutoFocus2 = TPoint(50,50);
+ iWinSizeAutoFocus2 = TSize(80,80);
+
+ iGroupWinAutoFocus1 = new(ELeave) CTWindowGroup(this);
+ iGroupWinAutoFocus1->ConstructL();
+ iGroupWinAutoFocus1->GroupWin()->AutoForeground(ETrue);
+ iGroupWinAutoFocus1->GroupWin()->EnableFocusChangeEvents();
+
+ iGroupWinAutoFocus2 = new(ELeave) CTWindowGroup(this);
+ iGroupWinAutoFocus2->ConstructL();
+ iGroupWinAutoFocus2->GroupWin()->AutoForeground(ETrue);
+ iGroupWinAutoFocus2->GroupWin()->EnableFocusChangeEvents();
+
+ iWinAutoFocus1=new(ELeave) CTBlankWindow();
+ iWinAutoFocus1->ConstructL(*iGroupWinAutoFocus1);
+ iWinAutoFocus1->SetExt(iWinPosAutoFocus1, iWinSizeAutoFocus1);
+ iWinAutoFocus1->SetColor(KRgbDarkYellow);
+ iWinAutoFocus1->BaseWin()->EnableAdvancedPointers();
+ iWinAutoFocus1->Activate();
+
+ iWinAutoFocus2=new(ELeave) CTBlankWindow();
+ iWinAutoFocus2->ConstructL(*iGroupWinAutoFocus2);
+ iWinAutoFocus2->SetExt(iWinPosAutoFocus2, iWinSizeAutoFocus2);
+ iWinAutoFocus2->SetColor(KRgbDarkCyan);
+ iWinAutoFocus2->BaseWin()->EnableAdvancedPointers();
+ iWinAutoFocus2->Activate();
+ }
+
+void CTMultiPtrEventClient::DeleteGroupBlankWin()
+ {
+ delete iWinAutoFocus2;
+ iWinAutoFocus2 = NULL;
+ delete iGroupWinAutoFocus2;
+ iGroupWinAutoFocus2 = NULL;
+ delete iWinAutoFocus1;
+ iWinAutoFocus1 = NULL;
+ delete iGroupWinAutoFocus1;
+ iGroupWinAutoFocus1 = NULL;
+ }
+
+TBool CTMultiPtrEventClient::CheckOrdinalPosition(TInt aAutoFocusWin)
+ {
+ if (aAutoFocusWin == 1)
+ {
+ return iWinAutoFocus1->BaseWin()->OrdinalPosition() == 0;
+ }
+ else
+ {
+ return iWinAutoFocus2->BaseWin()->OrdinalPosition() == 0;
+ }
+ }
+
+//CTMultiPtrEventTest
+CTMultiPtrEventTest::CTMultiPtrEventTest(CTestStep* aStep)
+ : CTWsGraphicsBase(aStep)
+ {
+ }
+
+CTMultiPtrEventTest::~CTMultiPtrEventTest()
+ {
+ ((CTMultiPtrEventTestStep*)iStep)->CloseTMSGraphicsStep();
+ delete iMultiPtrEventClient;
+ DestroyAnimDllAndAnim();
+ if (iPtrPluginLoaded)
+ {
+ iClick.Unload();
+ }
+ iClick.Close();
+ if (iHeap)
+ {
+ iHeap->Close();
+ iChunk.Close();
+ }
+ DeleteGroupWin();
+ }
+
+void CTMultiPtrEventTest::ConstructL()
+ {
+ // Here check if the HAL configuration are correct if not then finish the test case
+ TInt ret = HAL::Get(HALData::EPointerMaxPointers, iMaxDevPointers);
+ if (ret != KErrNone || iMaxDevPointers < 2 || iMaxDevPointers > 8)
+ {
+ TLogMessageText logText1;
+ _LIT(KWrongHALConfig, "HAL configuration are incorrect. \n");
+ logText1.Append(KWrongHALConfig);
+ LOG_MESSAGE(logText1);
+ TEST(EFalse);
+ User::Leave(ret);
+ }
+
+ // Get the data by using HAL api
+ User::LeaveIfError(HAL::Get(HALData::EPointerMaxPointers,iMaxDevPointers));
+ User::LeaveIfError(HAL::Get(HALData::EPointerNumberOfPointers,iMaxUiPointers));
+ User::LeaveIfError(HAL::Get(HALData::EPointer3DMaxPressure, iMaxPressure));
+ User::LeaveIfError(HAL::Get(HALData::EPointer3DPressureStep, iPressureStep));
+ User::LeaveIfError(HAL::Get(HALData::EPointer3DMaxProximity, iMaxProximity));
+ User::LeaveIfError(HAL::Get(HALData::EPointer3DProximityStep, iProximityStep));
+
+ _LIT(KWsIniFile, "z:\\system\\data\\wsini.ini");
+ CIniData* iniData = CIniData::NewL(KWsIniFile, ' ');
+ _LIT( KWsiniYShifting, "YSHIFTING");
+ iniData->FindVar(KWsiniYShifting, iYOffset);
+ delete iniData;
+ TheClient->iScreen->SetAppScreenMode(0);
+ TheClient->iScreen->SetScreenMode(0);
+ iPhysicalScreenSize = TheClient->iScreen->SizeInPixels();
+
+ TheGc->Activate(*BaseWin->Win());
+ 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->SetBrushColor(TRgb::Gray16(4));
+ TheGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ TheGc->SetPenStyle(CGraphicsContext::ENullPen);
+ TheGc->DrawRect(TRect(TestWin->Win()->Size()));
+ TheGc->Deactivate();
+
+ TheClient->iWs.Flush();
+ }
+
+// Create raw event setting type, X, Y, Z and pointernumber for rawevent
+// use UserSvr for simulating the event
+void CTMultiPtrEventTest::SimulatePointerEvent(TRawEvent::TType aType, TInt aX, TInt aY, TUint8 aPointerNumber)
+ {
+ TRawEvent rawEvent;
+ rawEvent.Set(aType, aX, aY+iYOffset, aPointerNumber);
+ UserSvr::AddEvent(rawEvent);
+ }
+
+void CTMultiPtrEventTest::SimulatePointerEvent(TRawEvent::TType aType, TInt aX, TInt aY, TInt aZ, TUint8 aPointerNumber)
+ {
+ TRawEvent rawEvent;
+ rawEvent.Set(aType, aX, aY+iYOffset, aZ, aPointerNumber);
+ UserSvr::AddEvent(rawEvent);
+ }
+
+// Simulate multipointer down and up event
+void CTMultiPtrEventTest::SimulatePointerDownUp(TInt aX, TInt aY, TInt aZ, TUint8 aPointerNumber)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, aX, aY, aZ, aPointerNumber);
+ SimulatePointerEvent(TRawEvent::EButton1Up, aX, aY, aZ, aPointerNumber);
+ }
+
+void CTMultiPtrEventTest::AddExpectedKey(TInt aEventCode, TInt aScanCode, TInt aCode/*=0*/, TInt aRepeats/*=0*/, TUint aModifiers/*=0*/)
+ {
+ TPckgBuf<TWsEvent> evtPkg;
+ TWsEvent& event=evtPkg();
+ if (aEventCode==EEventKey && aCode==0)
+ aCode=aScanCode;
+ event.SetType(aEventCode);
+ event.SetHandle((TUint)iMultiPtrEventClient->iGroup);
+ event.Key()->iCode=aCode;
+ event.Key()->iScanCode=aScanCode;
+ event.Key()->iModifiers=aModifiers;
+ event.Key()->iRepeats=aRepeats;
+ iMultiPtrEventClient->EventBuffer()->AddExpectedEvent(event);
+ }
+
+void CTMultiPtrEventTest::AddExpectedKeyDownUp(TInt aScanCode, TInt aCode/*=0*/, TInt aRepeats/*=0*/, TUint aModifiers/*=0*/)
+ {
+ __ASSERT_DEBUG(aScanCode<'a' || aScanCode>'z',AutoPanic(EAutoPanicScanCapital));
+ AddExpectedKey(EEventKeyDown,aScanCode,0,aRepeats,aModifiers);
+ AddExpectedKey(EEventKey,aScanCode,aCode,aRepeats,aModifiers);
+ AddExpectedKey(EEventKeyUp,aScanCode,0,aRepeats,aModifiers);
+ }
+
+void CTMultiPtrEventTest::AddExpectedPointerEvent(TPointerEvent::TType aType, TPoint aPos, TUint8 aPointerNumber, TUint aHandle)
+ {
+ AddExpectedPointerEvent(aType, aPos, 0, 0, aPointerNumber, aHandle);
+ }
+
+void CTMultiPtrEventTest::AddExpectedPointerEvent(TPointerEvent::TType aType, TPoint aPos, TInt aZ, TUint aModifier, TUint8 aPointerNumber, TUint aHandle, TBool aSecondaryClient)
+ {
+ if (aSecondaryClient)
+ {
+ iSecMultiPtrEventClient->AddExpectedPointerEvent(aType, aPos, aZ, aModifier, aPointerNumber, aHandle);
+ }
+ else
+ {
+ iMultiPtrEventClient->AddExpectedPointerEvent(aType, aPos, aZ, aModifier, aPointerNumber, aHandle);
+ }
+ }
+
+void CTMultiPtrEventTest::SetExpectNonAdvancedPointerEvents(TBool aSecondaryClient)
+ {
+ if (aSecondaryClient)
+ {
+ iSecMultiPtrEventClient->SetExpectNonAdvancedPointerEvents();
+ }
+ else
+ {
+ iMultiPtrEventClient->SetExpectNonAdvancedPointerEvents();
+ }
+ }
+
+void CTMultiPtrEventTest::ClearExpectNonAdvancedPointerEvents(TBool aSecondaryClient)
+ {
+ if (aSecondaryClient)
+ {
+ iSecMultiPtrEventClient->ClearExpectNonAdvancedPointerEvents();
+ }
+ else
+ {
+ iMultiPtrEventClient->ClearExpectNonAdvancedPointerEvents();
+ }
+ }
+
+void CTMultiPtrEventTest::AddExpectedPointerDownUp(TPoint aPos, TInt aZ, TUint8 aPointerNumber)
+ {
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, aPos, aZ, 0, aPointerNumber);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, aPos, aZ, 0, aPointerNumber);
+ }
+
+void CTMultiPtrEventTest::AddExpectedWsEvent(TEventCode aType, TBool aSecondaryClient, TInt aPointerNumber, TUint aHandle)
+ {
+ if (aSecondaryClient)
+ {
+ iSecMultiPtrEventClient->AddExpectedWsEvent(aType);
+ }
+ else
+ {
+ iMultiPtrEventClient->AddExpectedWsEvent(aType, aPointerNumber, aHandle);
+ }
+ }
+
+void CTMultiPtrEventTest::TestDragForMultiPointer(TPoint aPtrPos, TInt aPrValue, TUint8 aPointerNumber)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, aPtrPos.iX, aPtrPos.iY, aPrValue, aPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointerMove, aPtrPos.iX+2, aPtrPos.iY+1, aPrValue, aPointerNumber);
+ SimulatePointerEvent(TRawEvent::EButton1Up, aPtrPos.iX+2, aPtrPos.iY+1, 0, aPointerNumber);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, aPtrPos, aPrValue, 0, aPointerNumber);
+ aPtrPos.iX += 2; aPtrPos.iY += 1;
+ AddExpectedPointerEvent(TPointerEvent::EDrag, aPtrPos, aPrValue, 0, aPointerNumber);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, aPtrPos, 0, 0, aPointerNumber);
+ }
+
+void CTMultiPtrEventTest::SimulateAndAddLoneUpEvents(TInt aNumSimulation, TInt aNumAddition, TPoint aPos)
+ {
+ for (TInt count = 0; count < aNumSimulation; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, aPos.iX, aPos.iY, 0, 0);
+ }
+ for (TInt count = 0; count < aNumAddition; count++)
+ {
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, aPos, 0, 0, 0);
+ }
+ }
+
+void CTMultiPtrEventTest::TestFilteringForMultiPointer(TBool aFiltering)
+ {
+ TPoint ptrPos;
+ TInt ptrNum;
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ if(!aFiltering)
+ {
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, ptrNum);
+ }
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+
+ ptrPos.SetXY(0,0);
+ TPoint interPt = ptrPos;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX+2, interPt.iY+1, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX+4, interPt.iY+2, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX+6, interPt.iY+3, 0, ptrNum);
+ if(!aFiltering)
+ {
+ interPt.iX += 6; interPt.iY += 3;
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, ptrNum);
+ }
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+
+ ptrPos.SetXY(0,0);
+ interPt = ptrPos;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ interPt.iX += 6;
+ interPt.iY += 3;
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+ }
+
+void CTMultiPtrEventTest::TestGrabbingForMultiPointer(TBool aGrabbing)
+ {
+ TPoint ptrPos;
+ TInt ptrNum;
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, ptrNum);
+ ptrPos.iX += xInc/3; // Ensure all Button1Down events are on iParentWin
+ ptrPos.iY += yInc/3;
+ }
+
+ ptrPos.SetXY(0,0);
+ ptrPos.iX += iPhysicalScreenSize.iWidth/2; // Ensure all Drag and Button1Up events are on iChildWin
+ ptrPos.iY += iPhysicalScreenSize.iHeight/2;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ if(aGrabbing)
+ {
+ // CalculatePtrPosAndSet3Ddata will subtract iChildWinPos from ptrPos if pointer event occured on child window. Thus we add iChildWinPos here.
+ AddExpectedPointerEvent(TPointerEvent::EDrag, ptrPos+iMultiPtrEventClient->ChildWin()->Position(), ptrNum, (TUint)iMultiPtrEventClient->ParentWin());
+ }
+ else
+ {
+ AddExpectedPointerEvent(TPointerEvent::EDrag, ptrPos, ptrNum);
+ }
+ ptrPos.iX += xInc/3;
+ ptrPos.iY += yInc/3;
+ }
+
+ ptrPos.SetXY(0,0);
+ ptrPos.iX += iPhysicalScreenSize.iWidth/2;
+ ptrPos.iY += iPhysicalScreenSize.iHeight/2;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ if(aGrabbing)
+ {
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos+iMultiPtrEventClient->ChildWin()->Position(), ptrNum, (TUint)iMultiPtrEventClient->ParentWin());
+ }
+ else
+ {
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, ptrNum);
+ }
+ ptrPos.iX += xInc/3;
+ ptrPos.iY += yInc/3;
+ }
+ }
+
+void CTMultiPtrEventTest::TestCapturingForMultiPointer(TBool aAllWinGroups)
+ {
+ TPoint ptrPos;
+ TInt ptrNum = 0;
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+
+ // These are some typical values which are used only for testing purposes.
+ // 20mm to screen
+ // 50mm to screen
+ // 4N of pressure
+ // 2N of pressure
+ SetThresholdValues(-20,-50,4000,2000);
+
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerMoveEvents, 0);
+
+ if(!aAllWinGroups)
+ {
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, -30, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), -30, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, -10, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterCloseProximity, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), -10, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), 0, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX+=2, ptrPos.iY+=2, 5000, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), 5000, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX-=2, ptrPos.iY-=2, 1000, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitHighPressure, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), 1000, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX+=2, ptrPos.iY+=2, 1000, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), 1000, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), 0, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX-=2, ptrPos.iY-=2, -60, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos-iMultiPtrEventClient->ChildWin()->Position(), -60, 0, ptrNum, (TInt)iMultiPtrEventClient->ChildWin());
+ ptrPos.iX += xInc/3; // Ensure all Pointer events are on iParentWin
+ ptrPos.iY += yInc/3;
+ }
+ }
+ else
+ {
+ ptrPos.iX = iPhysicalScreenSize.iWidth/2 + xInc/3;
+ ptrPos.iY = 0;
+
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, -10, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterCloseProximity, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), -10, 0, ptrNum, (TInt)iWinForCapturing);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), 0, 0, ptrNum, (TInt)iWinForCapturing);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX+=2, ptrPos.iY+=2, 5000, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), 5000, 0, ptrNum, (TInt)iWinForCapturing);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX-=2, ptrPos.iY-=2, 1000, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitHighPressure, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), 1000, 0, ptrNum, (TInt)iWinForCapturing);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX+=2, ptrPos.iY+=2, 1000, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), 1000, 0, ptrNum, (TInt)iWinForCapturing);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), 0, 0, ptrNum, (TInt)iWinForCapturing);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, TPoint(ptrPos.iX+iPhysicalScreenSize.iWidth/2, ptrPos.iY), 0, 0, ptrNum, (TInt)iWinForCapturing);
+ ptrPos.iX += xInc/3;
+ ptrPos.iY += yInc/3;
+ }
+ }
+ }
+
+void CTMultiPtrEventTest::SetAutoFlush()
+ {
+ iTheClientFlush = TheClient->iWs.SetAutoFlush(ETrue);
+ iClientFlush = iMultiPtrEventClient->iWs.SetAutoFlush(ETrue);
+ }
+
+void CTMultiPtrEventTest::ResetFlushStopAS()
+ {
+ if (iActiveSchedulerStarted)
+ {
+ iActiveSchedulerStarted = EFalse;
+ CActiveScheduler::Stop();
+ }
+ TheClient->iWs.SetAutoFlush(iTheClientFlush);
+ iMultiPtrEventClient->iWs.SetAutoFlush(iClientFlush);
+ }
+
+// Common function for all test cases
+void CTMultiPtrEventTest::RunTestsL()
+ {
+ // Create CTMultiPtrEventClient for each test case and call NextSetOfEventsL()
+ iMultiPtrEventClient = new(ELeave) CTMultiPtrEventClient(this);
+ iMultiPtrEventClient->SetScreenNumber(iTest->iScreenNumber);
+ iMultiPtrEventClient->ConstructL();
+
+ iEventSet=0;
+
+ // Create secondary client for test case number 3
+ if (iTest->iState == 3)
+ {
+ iSecMultiPtrEventClient = new(ELeave) CTMultiPtrEventClient(this, 1);
+ iSecMultiPtrEventClient->SetScreenNumber(iTest->iScreenNumber);
+ iSecMultiPtrEventClient->ConstructL();
+ }
+
+ TRAPD(err, NextSetOfEventsL());
+ if (err != KErrNone)
+ {
+ iFailed = ETrue;
+ }
+
+ // Start nested activescheduler if it is not failed for the first attempt
+ if (!iFailed)
+ {
+ iActiveSchedulerStarted = ETrue;
+ CActiveScheduler::Start();
+ }
+
+ //
+ TInt eventsRem = iMultiPtrEventClient->EventBuffer()->EventsRemaining();
+ if (eventsRem > 0)
+ {
+ iFailed=ETrue;
+ }
+
+ // Delete secondary client for test case number 3
+ if (iTest->iState == 3)
+ {
+ delete iSecMultiPtrEventClient;
+ iSecMultiPtrEventClient = NULL;
+ }
+
+ delete iMultiPtrEventClient;
+ iMultiPtrEventClient = NULL;
+ }
+
+// Common function for all tests
+// Important point to remember is that this function should not leave when running tests
+void CTMultiPtrEventTest::NextSetOfEventsL()
+ {
+ // For each test case calls its respective tests
+
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
+ switch (iTest->iState)
+ {
+ case 0:
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0036
+*/
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0036"));
+ MultiPointerEvents();
+ break;
+ case 1:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0014"));
+ PurgingMultiPointerEvents();
+ break;
+ case 2:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0013"));
+ MultiPointerEventsForAnimsL();
+ break;
+ case 3:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0011"));
+ GetRemainingEventsFromSecondaryClient(); // Does nothing for first time
+ MultiClientMultiPointerEvents();
+ break;
+ case 4:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0027"));
+ MultiPointerEventsForPointerClickL();
+ break;
+ case 5:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0028"));
+ MultiPointerEventsInDiffScreenModes();
+ break;
+ case 6:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0025"));
+ FilteringMultiPointerEvents();
+ break;
+ case 7:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0021"));
+ GrabbingMultiPointerEvents();
+ break;
+ case 8:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0031"));
+ VirtualKeyBoardForMultiplePointers();
+ break;
+ case 9:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0032"));
+ DoubleClickForMultiplePointers();
+ break;
+ case 10:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0015"));
+ MultiPointerOutOfRangeEvents();
+ break;
+ case 11:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0026"));
+ AutoForeGroundForMultiplePointersL();
+ break;
+ case 12:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0029"));
+ EmulationRulesForMultiplePointers();
+ break;
+ case 13:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0034"));
+ CloseProximityAndHighPressureEventsL();
+ break;
+ case 14:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0017"));
+ OutOfBoundValueTesting();
+ break;
+ case 15:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0019"));
+ CapturingMultiPointerEvents();
+ break;
+ case 16:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0035"));
+ NegativeTestsForProximityPressureEventsL();
+ break;
+ case 17:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-ADVANCEDPOINTER-0034"));
+ PointerRepeatEventForMultiplePointers();
+ break;
+ // Any new test case should be added here.
+ // because some of the above tests use testcase number for certain checks
+ default:
+ ((CTMultiPtrEventTestStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
+ AutoPanic(EAutoPanicWrongTest);
+ }
+ ((CTMultiPtrEventTestStep*)iStep)->RecordTestResultL();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0033
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677
+@SYMTestPriority High
+@SYMTestCaseDesc To check Wserv sends Pointer Repeat Events for all pointers.
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate events being passed to the client by implementing each discrete test
+ over 4 seperate test cases.
+ In the first test case simulate EButton1Down and add event to a TWsEvent buffer.
+ In the second test case call RequestPointerRepeatEvent on the base window passing
+ in a time interval, a rectangle (the 'hitbox') and pointer number.
+ Add EButtonRepeat to TWsEvent buffer.
+ In the third test case simulate EPointerMove event within the hitbox, then simulate
+ an elapsed period of time longer that specified interval. Add only a EButtonRepeat
+ to TWsEvent buffer.
+ In the final test case simulate EButton1Up and add event to TWsEvent buffer.
+
+ Repeat steps for the second discrete test, however, in the third test case simulate
+ EPointerMove event outside the hitbox. In addition add EDrag to TWsEvent buffer
+ instead of EButtonRepeat.
+
+ A third discrete test will be executed over two test cases and will test
+ CancelPointerRepeatEventRequest API.
+
+@SYMTestExpectedResults The received events must match the events added to the buffer except where EPointerMove
+ events should be filtered out. In addition, EButtonRepeat will be generated by wserv
+ after calling RequestPointerRepeatEvent and time interval specified has elapsed.
+
+*/
+void CTMultiPtrEventTest::PointerRepeatEventForMultiplePointers()
+ {
+ // Test PointerRepeatEvent for Multiple Pointers
+ TLogMessageText logText;
+ _LIT(KSet, "PointerRepeatEventForMultiplePointers SetOfEvents: %d of 10");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos;
+ TInt ptrNum;
+ // Ensure all pointers are on iParentWin
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers/3;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers/3;
+
+ switch(iEventSet++)
+ {
+ // Test cases 0 - 3 represent first discrete test for PointerRepeatEvents
+ case 0:
+ // Simulate EButton1Down events only. This is in order to simulate the event being passed to the client.
+ // If the event remained in the window queue the PointerRepeatEvent request would be cancelled when PointerRepeatPurgeCheck is performed.
+ INFO_PRINTF1(_L("Simulate EButton1Down event for all pointers."));
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ case 1:
+ // Simulate client calling RequestPointerRepeatEvent in response to EButton1Down event being within a 'hitbox'.
+ INFO_PRINTF1(_L("Simulate PointerRepeatEvent request for all pointers."));
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iMultiPtrEventClient->ParentWin()->BaseWin()->RequestPointerRepeatEvent(TTimeIntervalMicroSeconds32(100000),TRect(TPoint(0,0), TSize(iPhysicalScreenSize.iWidth/2,iPhysicalScreenSize.iHeight)),ptrNum);
+ User::After(200000);
+ AddExpectedPointerEvent(TPointerEvent::EButtonRepeat, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ case 2:
+ // Simulate client calling RequestPointerRepeatEvent in response to EButtonRepeat and pointer remaining within the 'hitbox'.
+ INFO_PRINTF1(_L("Simulate additional PointerRepeatEvent request for all pointers."));
+ // New coordinates will be used for a simulated EPointerMove. This event will be filtered out, however, EButtonRepeat will occur at new coordinates
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iMultiPtrEventClient->ParentWin()->BaseWin()->RequestPointerRepeatEvent(TTimeIntervalMicroSeconds32(100000),TRect(TPoint(0,0), TSize(iPhysicalScreenSize.iWidth/2,iPhysicalScreenSize.iHeight)),ptrNum);
+ // EPointerMove event is filtered out by TWsPointer::PointerRepeatPurgeCheck
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ User::After(200000);
+ AddExpectedPointerEvent(TPointerEvent::EButtonRepeat, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ case 3:
+ INFO_PRINTF1(_L("Simulate EButton1Up for all pointers."));
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ // Test cases 4 - 7 represent second second discrete test for PointerRepeatEvents
+ case 4:
+ // Simulate EButton1Down events only. This is in order to simulate the event being passed to the client.
+ // If the event remained in the window queue the PointerRepeatEvent request would be cancelled when PointerRepeatPurgeCheck is performed.
+ INFO_PRINTF1(_L("Simulate EButton1Down event for all pointers."));
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ case 5:
+ // Simulate client calling RequestPointerRepeatEvent in response to EButton1Down event being within a 'hitbox'.
+ INFO_PRINTF1(_L("Call RequestPointerRepeatEvent for all pointers."));
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iMultiPtrEventClient->ParentWin()->BaseWin()->RequestPointerRepeatEvent(TTimeIntervalMicroSeconds32(100000),TRect(TPoint(0,0), TSize(iPhysicalScreenSize.iWidth/3,iPhysicalScreenSize.iHeight)),ptrNum); // hitbox size reduced
+ User::After(200000);
+ AddExpectedPointerEvent(TPointerEvent::EButtonRepeat, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ case 6:
+ // Simulate client calling RequestPointerRepeatEvent in response to EButtonRepeat and event remaining within the 'hitbox' rect.
+ // EPointerMove will take pointer out of the hitbox so should not be filtered. PointerRepeatEvent should be cancelled.
+ INFO_PRINTF1(_L("Simulate a PointerMove event for all pointers to a coordinate outside the hitbox."));
+ // New coordinates will be used for a simulated EPointerMove outisde the hitbox.
+ ptrPos.iX = iPhysicalScreenSize.iWidth/3 + xInc;
+ ptrPos.iY = 0;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iMultiPtrEventClient->ParentWin()->BaseWin()->RequestPointerRepeatEvent(TTimeIntervalMicroSeconds32(100000),TRect(TPoint(0,0), TSize(iPhysicalScreenSize.iWidth/3,iPhysicalScreenSize.iHeight)),ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ User::After(200000);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, ptrPos, ptrNum);
+ }
+ break;
+ case 7:
+ INFO_PRINTF1(_L("Simulate EButton1Up for all pointers."));
+ ptrNum = 0;
+ ptrPos.iX = iPhysicalScreenSize.iWidth/3 + xInc;
+ ptrPos.iY = 0;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, ptrNum);
+ }
+ break;
+ // Test cases 8 and 9 represent third discrete test for PointerRepeatEvents
+ case 8:
+ // Simulate EButton1Down events only. This is in order to simulate the event being passed to the client.
+ // If the event remained in the window queue the PointerRepeatEvent request would be cancelled when PointerRepeatPurgeCheck is performed.
+ INFO_PRINTF1(_L("Simulate EButton1Down event for all pointers."));
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ case 9:
+ // No simulated events. This test case is to explicity call RWindowBase::CancelPointerRepeatEventRequest(const TUint8 aPointerNumber)
+ INFO_PRINTF1(_L("Call RequestPointerRepeatEvent and CancelPointerRepeatEventRequest for all pointers."));
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iMultiPtrEventClient->ParentWin()->BaseWin()->RequestPointerRepeatEvent(TTimeIntervalMicroSeconds32(100000),TRect(TPoint(0,0), TSize(iPhysicalScreenSize.iWidth/3,iPhysicalScreenSize.iHeight)),ptrNum);
+ iMultiPtrEventClient->ParentWin()->BaseWin()->CancelPointerRepeatEventRequest(ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ INFO_PRINTF1(_L("Simulate EButton1Up for all pointers."));
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, ptrNum);
+ ptrPos.iX+=xInc;
+ ptrPos.iY+=yInc;
+ }
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+void CTMultiPtrEventTest::TestErrorCodeL(TInt aExpErrCode, TInt aActualErrCode)
+ {
+ if (aExpErrCode != aActualErrCode)
+ {
+ TLogMessageText logText;
+ _LIT(KError, "Expected Error code = %d Actual Actual Error code %d");
+ logText.AppendFormat(KError, aExpErrCode, aActualErrCode);
+ LOG_MESSAGE(logText);
+ User::Leave(ETestFailed);
+ }
+ }
+
+void CTMultiPtrEventTest::NegativeTestingOfProximityPressureAPIsL()
+ {
+ // First send -10 for EnterCloseProximity and -5 for ExitCLoseProximity, it should return KErrArgument
+ // Then send 20 and 10 which should return KErrNone
+ // Then sent 10 and 20 which should return KErrArgument
+ TInt retVal;
+ retVal = iMultiPtrEventClient->iWs.SetCloseProximityThresholds(-10, -5);
+ TestErrorCodeL(KErrArgument, retVal);
+
+ retVal = iMultiPtrEventClient->iWs.SetCloseProximityThresholds(20, 10);
+ TestErrorCodeL(KErrNone, retVal);
+
+ retVal = iMultiPtrEventClient->iWs.SetCloseProximityThresholds(10, 20);
+ TestErrorCodeL(KErrArgument, retVal);
+
+ // Repeat the above for EnterHighPressure and ExitHighPressure with these values
+ // -10 and -5 it should return KErrArgument
+ // -5 and -10 it should return KErrNone
+ retVal = iMultiPtrEventClient->iWs.SetHighPressureThresholds(-10, -5);
+ TestErrorCodeL(KErrArgument, retVal);
+
+ retVal = iMultiPtrEventClient->iWs.SetHighPressureThresholds(-5, -10);
+ TestErrorCodeL(KErrNone, retVal);
+ }
+
+void CTMultiPtrEventTest::SimulateProximityAndPressureEvents(TInt aCloseProxEnterValue, TInt aCloseProxExitValue, TInt aHighPresEnterValue, TInt aHighPresExitValue)
+ {
+ TPoint ptrPos(10,10);
+ // Simulate EPointerMove with proximity value > EnterCloseProximity threshold
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, aCloseProxEnterValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterCloseProximity, ptrPos, aCloseProxEnterValue, 0, ptrNum);
+ }
+
+ // Simulate EPointerMove with proximity value < ExitCloseProximity threshold
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, aCloseProxExitValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos, aCloseProxExitValue, 0, ptrNum);
+ }
+
+ // Simulate EBUtton1Down with presure value > EnterHighPressure threshold
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, aHighPresEnterValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, aHighPresEnterValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, ptrPos, aHighPresEnterValue, 0, ptrNum);
+ }
+
+ // Simulate EPointerMove with presure value < ExitHighPressure threshold
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, aHighPresExitValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitHighPressure, ptrPos, aHighPresExitValue, 0, ptrNum);
+ }
+
+ // Finally simulate Ebutton1Up with proximity value < ExitCloseProximity
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, aCloseProxExitValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, aCloseProxExitValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos, aCloseProxExitValue, 0, ptrNum);
+ }
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0035
+@SYMPREQ PREQ1226
+@SYMREQ REQ10887, REQ10886
+@SYMTestPriority High
+@SYMTestCaseDesc Negative tests for close Proximity and high Pressure events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Set CloseProximity and HighPressure thresholds with positive and negative values.
+ Simulate Enter/ExitCloseProximity and Enter/ExitHighPressure events.
+@SYMTestExpectedResults The received events must match the simulated pointer events
+*/
+void CTMultiPtrEventTest::NegativeTestsForProximityPressureEventsL()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "Negative tests for pressure and proximity events: %d of 3");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ NegativeTestingOfProximityPressureAPIsL();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ switch(iEventSet++)
+ {
+ case 0:
+ // This is to check close proximity threshold API can be given +ve values
+ // and high pressure threshold API can begiven -ve values
+ iMultiPtrEventClient->iWs.SetCloseProximityThresholds(50, 20);
+ iMultiPtrEventClient->iWs.SetHighPressureThresholds(-20, -50);
+ SimulateProximityAndPressureEvents(60, 10, -10, -60);
+ break;
+ case 1:
+ // Repeat the above with +ve values
+ iMultiPtrEventClient->iWs.SetCloseProximityThresholds(50, 20);
+ iMultiPtrEventClient->iWs.SetHighPressureThresholds(50, 20);
+ SimulateProximityAndPressureEvents(60, 10, 60, 10);
+ break;
+ case 2:
+ // Repeat the above -ve values
+ iMultiPtrEventClient->iWs.SetCloseProximityThresholds(-20, -50);
+ iMultiPtrEventClient->iWs.SetHighPressureThresholds(-20, -50);
+ SimulateProximityAndPressureEvents(-10, -60, -10, -60);
+ break;
+ default:
+ SetThresholdValues(KMaxTInt, KMinTInt, KMaxTInt, KMinTInt);
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+
+void CTMultiPtrEventTest::CreateGroupWinForCapturingL()
+ {
+ iGroupWinForCapturing = new(ELeave) CTWindowGroup(iMultiPtrEventClient);
+ iGroupWinForCapturing->ConstructL();
+ iGroupWinForCapturing->GroupWin()->AutoForeground(ETrue);
+ iGroupWinForCapturing->GroupWin()->EnableFocusChangeEvents();
+
+ iWinForCapturing = new(ELeave) CTBlankWindow();
+ iWinForCapturing->ConstructL(*iGroupWinForCapturing);
+ iWinForCapturing->SetExt(TPoint(), TSize(iPhysicalScreenSize.iWidth/2, iPhysicalScreenSize.iHeight));
+ iWinForCapturing->SetColor(KRgbBlue);
+ iWinForCapturing->BaseWin()->EnableAdvancedPointers();
+ iWinForCapturing->Activate();
+ }
+
+void CTMultiPtrEventTest::DeleteGroupWinForCapturing()
+ {
+ if (iWinForCapturing)
+ {
+ delete iWinForCapturing;
+ iWinForCapturing = NULL;
+ }
+ if (iGroupWinForCapturing)
+ {
+ delete iGroupWinForCapturing;
+ iGroupWinForCapturing = NULL;
+ }
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0019
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677,REQ9683,
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports Capturing in case of multi pointer events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Create a window with group window as its parent.
+ Create another window with same parent and partially overlapping the first one.
+ SetPointerCapture for second window with TCaptureEnabled flag.
+ Simulate TRawEvent::EButton1Down from each pointer the device supports
+
+ Repeat the above with TCaptureFlagAllGroups flag for SetPointerCapture
+ and creating windows from different window group
+
+@SYMTestExpectedResults Even if events were simulated on first window events are delivered to
+ second window as it is capturing.
+ With TCaptureFlagAllGroups flag set events are delivered to window which is
+ capturing even if events were simulated on a window from different group
+
+*/
+void CTMultiPtrEventTest::CapturingMultiPointerEvents()
+ {
+ // Test Capturing of multi pointer events
+ // 1. Test Wserv supports Capturing in case of multi-pointer events
+ // 2. Test pointer events are delivered correctly when Capturing is disabled.
+ TLogMessageText logText;
+ _LIT(KSet, "CapturingMultiPtrEvents SetOfEvents: %d of 3");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos;
+ TInt ptrNum;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ INFO_PRINTF1(_L("Ensure pointer state is Out of Range"));
+ AddExpectedWsEvent(EEventFocusGained);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, ptrNum);
+ }
+ break;
+ case 1:
+ INFO_PRINTF1(_L("Check Wserv supports Capturing in case of multi-pointer events, within window group"));
+ iMultiPtrEventClient->ChildWin()->BaseWin()->SetPointerCapture(RWindowBase::TCaptureEnabled);
+ TestCapturingForMultiPointer(EFalse);
+ break;
+ case 2:
+ INFO_PRINTF1(_L("Check Wserv supports Capturing in case of multi-pointer events, from different window groups"));
+ TRAPD(err, CreateGroupWinForCapturingL()); // it cannot leave so trap and fail
+ if (err != KErrNone)
+ {
+ Failed();
+ }
+ AddExpectedWsEvent(EEventFocusLost); // First group window losing focus because of second group creation
+ AddExpectedWsEvent(EEventFocusGained); // Second group window creation
+
+ iWinForCapturing->BaseWin()->SetPointerCapture(RWindowBase::TCaptureEnabled|RWindowBase::TCaptureFlagAllGroups);
+ TestCapturingForMultiPointer(ETrue);
+ break;
+ default:
+ DeleteGroupWinForCapturing();
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0017
+@SYMPREQ PREQ1226
+@SYMREQ Negative Testing
+@SYMTestPriority High
+@SYMTestCaseDesc Out of bound value testing
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate raw events of TRawEvent with pointer number greater than EPointerMaxPointers
+
+@SYMTestExpectedResults The received events must match the events added to the buffer and check that out of bound events are ignored.
+
+*/
+void CTMultiPtrEventTest::OutOfBoundValueTesting()
+ {
+ // Test Wserv ignores pointer events which have a pointer number greater than EPointerMaxPointers.
+ TLogMessageText logText;
+ _LIT(KSet, "OutOfBoundValueTesting SetOfEvents: %d of 1");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos;
+ TInt ptrNum;
+ TInt ptrNumOutOfBounds;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ INFO_PRINTF1(_L("Checks Wserv ignores pointer events which have a pointer number greater than EPointerMaxPointers."));
+ ptrPos.SetXY(0,0);
+ ptrNum = iMaxDevPointers-1; // Max value for ptrNum
+ ptrNumOutOfBounds = iMaxDevPointers; // Invalid ptrNum as pointer numbers are zero indexed
+
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNumOutOfBounds);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX+10, ptrPos.iY+10, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX+10, ptrPos.iY+10, 0, ptrNumOutOfBounds);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX+10, ptrPos.iY+10, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX+10, ptrPos.iY+10, 0, ptrNumOutOfBounds);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, ptrNum);
+ ptrPos.iX += 10; ptrPos.iY += 10;
+ AddExpectedPointerEvent(TPointerEvent::EDrag, ptrPos, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, ptrNum);
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+void CTMultiPtrEventTest::SetThresholdValues(TInt aEnterCloseProx, TInt aExitCloseProx, TInt aEnterHighPres, TInt aExitHighPres)
+ {
+ iEnterCloseProximityThreshold = aEnterCloseProx;
+ iExitCloseProximityThreshold = aExitCloseProx;
+ iEnterHighPressureThreshold = aEnterHighPres;
+ iExitHighPressureThreshold = aExitHighPres;
+
+ iMultiPtrEventClient->iWs.SetCloseProximityThresholds(iEnterCloseProximityThreshold,iExitCloseProximityThreshold);
+ iMultiPtrEventClient->iWs.SetHighPressureThresholds(iEnterHighPressureThreshold,iExitHighPressureThreshold);
+ }
+
+void CTMultiPtrEventTest::TestCloseProximityHighPressureAPIsL()
+ {
+ // These are some typical values which are used only for testing purposes.
+ // 20mm to screen
+ // 50mm to screen
+ // 4N of pressure
+ // 2N of pressure
+ SetThresholdValues(-20,-50,4000,2000);
+
+ if (iMultiPtrEventClient->iWs.GetEnterCloseProximityThreshold() != iEnterCloseProximityThreshold)
+ {
+ TLogMessageText logText;
+ _LIT(KError, "Expected EnterCloseProximityThreshold = %d Actual EnterCloseProximityThreshold %d");
+ logText.AppendFormat(KError, iEnterCloseProximityThreshold, iMultiPtrEventClient->iWs.GetEnterCloseProximityThreshold());
+ LOG_MESSAGE(logText);
+ User::Leave(ETestFailed);
+ }
+
+ if (iMultiPtrEventClient->iWs.GetExitCloseProximityThreshold() != iExitCloseProximityThreshold)
+ {
+ TLogMessageText logText;
+ _LIT(KError, "Expected ExitCloseProximityThreshold = %d Actual ExitCloseProximityThreshold %d");
+ logText.AppendFormat(KError, iExitCloseProximityThreshold, iMultiPtrEventClient->iWs.GetExitCloseProximityThreshold());
+ LOG_MESSAGE(logText);
+ User::Leave(ETestFailed);
+ }
+
+ if (iMultiPtrEventClient->iWs.GetEnterHighPressureThreshold() != iEnterHighPressureThreshold)
+ {
+ TLogMessageText logText;
+ _LIT(KError, "Expected EnterHighPressureThreshold = %d Actual EnterHighPressureThreshold %d");
+ logText.AppendFormat(KError, iEnterHighPressureThreshold, iMultiPtrEventClient->iWs.GetEnterHighPressureThreshold());
+ LOG_MESSAGE(logText);
+ User::Leave(ETestFailed);
+ }
+
+ if (iMultiPtrEventClient->iWs.GetExitHighPressureThreshold() != iExitHighPressureThreshold)
+ {
+ TLogMessageText logText;
+ _LIT(KError, "Expected ExitHighPressureThreshold = %d Actual ExitHighPressureThreshold %d");
+ logText.AppendFormat(KError, iExitHighPressureThreshold, iMultiPtrEventClient->iWs.GetExitHighPressureThreshold());
+ LOG_MESSAGE(logText);
+ User::Leave(ETestFailed);
+ }
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0034
+@SYMPREQ PREQ1226
+@SYMREQ REQ10887,REQ10886
+@SYMTestPriority High
+@SYMTestCaseDesc Tests close Proximity and high Pressure event types.
+@SYMTestStatus Implemented
+
+@SYMTestActions Set CloseProximity and HighPressure thresholds and simulate events with different Z values
+@SYMTestExpectedResults The received events must match the simulated pointer events
+*/
+void CTMultiPtrEventTest::CloseProximityAndHighPressureEventsL()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "Close Proximity and High Pressure events: %d of 11");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ TestCloseProximityHighPressureAPIsL();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos(10,10);
+ TInt proxValue;
+ TInt prValue;
+ TInt tempCount;
+ switch(iEventSet++)
+ {
+ case 0:
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ // One whole cycle of events
+ // Simulate out-of-range from all pointers and don't expect out-of-range events
+ // since all the pointers are already in same state
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ }
+
+ // Simulate moves with proximity value < EEnterCloseProximity
+ proxValue = -30;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate moves with proximity value > EEnterCloseProximity
+ proxValue = -10;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterCloseProximity, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Down with pressure value < EEnterHighPressure
+ prValue = 1000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate moves with pressure value > EEnterHighPressure
+ prValue = 5000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate moves with pressure value < EExitHighPressure
+ prValue = 1000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitHighPressure, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value > EEnterCloseProximity
+ proxValue = -10;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate moves with proximity value < EExitCloseProximity
+ proxValue = -60;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ case 1:
+ // Simulate events to meet all scenarios
+ // Simulate EButton1Down with pressure value < EEnterHighPressure
+ prValue = 1000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value < EExitCloseProximity
+ proxValue = -60;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Down with pressure value > EEnterHighPressure
+ prValue = 5000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value < EExitCloseProximity
+ proxValue = -60;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ case 2:
+ // Simulate moves with proximity value > EEnterCloseProximity
+ proxValue = -10;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterCloseProximity, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Down with pressure value > EEnterHighPressure
+ prValue = 5000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value > EExitCloseProximity
+ proxValue = -40; // When you coming up, EEnterCloseProximity is of no use
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate out-of-range events
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ case 3:
+ // From out-of-range state to EButton1Down
+ // Simulate EButton1Down with pressure value < EEnterHighPressure
+ prValue = 1000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value > EExitCloseProximity
+ proxValue = -40;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate out-of-range events
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Down with pressure value > EEnterHighPressure
+ prValue = 5000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EEnterHighPressure, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value > EExitCloseProximity
+ proxValue = -40;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate out-of-range events
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ case 4:
+ // Simulate EButton1Dowm with pressure value < EEnterHighPressure
+ prValue = 1000;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, ptrNum);
+ }
+
+ // Simulate EButton1Up with proximity value < EExitCloseProximity
+ proxValue = -60;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EExitCloseProximity, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ // Simulate out-of-range from Up/OutOfCloseProximity
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ case 5:
+ // Purging of proximity and pressure events
+ // Simulate EnterCloseProximity and ExitCloseProximity events which will be purged
+ // when you send Button1Up events for KMaxQueueSize
+ proxValue = -10;
+ for (TInt ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 4); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ }
+ proxValue = -60;
+ for (TInt ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 4); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ }
+ for (TInt count = 0; count < KMaxQueueSize; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, 0);
+ }
+ break;
+ case 6:
+ // Simulate EnterCloseProximity for 4 pointers.
+ // As we cannot create lone ExitCloseProximity events, so create just moves from next 4 pointers
+ // Simulate out-of-range for these events on thier respective pointers
+ // Then simulate EButton1Up events which will purge EnterCloseProximity and move events
+ // which checks that lone EnterCloseProximity and lone move events will be purged
+ proxValue = -10;
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ proxValue = -60;
+ for (TInt ptrNum = iMaxDevPointers/2; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ for (TInt count = 0; count < KMaxQueueSize-iMaxDevPointers; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, 0);
+ }
+ break;
+ case 7:
+ // Bring all other pointers to Up state, becasue of previous test
+ // Then simulate out-of-range twice for all the pointers
+ // Then simulate Button1Up which will cause purging of successive out-of-range events
+ proxValue = -60;
+ tempCount = 0;
+ for (TInt ptrNum = 1; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ tempCount++;
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, ptrNum);
+ }
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ tempCount++;
+ // Wserv does nothing if current state is outofrange and if receives again EOutOfRange event which is practically not possible
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ for (TInt count = 0; count < KMaxQueueSize-tempCount; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, proxValue, 0, 0);
+ }
+ break;
+ case 8:
+ // Simulate EButton1Down with pressure value > EnterHIghPressure threshold
+ // which will cause EButton1Down and EnterHighPressure to be filled in queue
+ // Simulate ExitHighPressure and EButton1Up events for 2 pointers
+ // Then simulate EButton1Up events from pointer0 so that all of the above events are purged
+ prValue = 5000;
+ for (TInt ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 2); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ }
+ prValue = 1000;
+ for (TInt ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 2); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ // Here these events are purged becasue their correpsonding down event would have been purged
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ }
+ // All the above events get purged by this
+ for (TInt count = 0; count < KMaxQueueSize; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, 0);
+ }
+ break;
+ case 9:
+ // Simulate EButton1Down for 2 pointers, which will generate Button1Down and EnterHighPressure
+ // Simulate Ebutton1Up events for MaxQueueSize from last pointer so that all the above events are purged
+ prValue = 5000;
+ for (TInt ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrNum < 2); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ }
+
+ // This will cause above down and enterhighpressure events to be purged
+ // When pointer is in outofrange state and when EButton1Up event is sent Wserv sends EnterCloseProximity
+ // EnterCloseProximity cannot be purged unless the next event is EExitCloseProximity or EOutOfRange
+ for (TInt count = 0; count < KMaxQueueSize; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, iMaxDevPointers-1);
+ AddExpectedPointerEvent((count ? TPointerEvent::EButton1Up : TPointerEvent::EEnterCloseProximity), ptrPos, 0, 0, iMaxDevPointers-1);
+ }
+
+ // As the first 2 pointers are in down state, and if we send the move events with prValue = 1000
+ // This will generate the exithigh pressure events, which will be ignored
+ // This will also generate the Ebutton1Up event which will also be ignored
+ prValue = 1000;
+ for (TInt ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrNum < 2); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ }
+ break;
+ case 10:
+ // This is to just bring all the pointers to out-of-range state
+ // to make all pointers in valid state for other test to run
+ // Wserv processes EOutOfRange events only when its current state is not in outofrange.
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers && ptrNum < 2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, ptrNum);
+ }
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, iMaxDevPointers-1);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, iMaxDevPointers-1);
+ break;
+ default:
+ SetThresholdValues(KMaxTInt, KMinTInt, KMaxTInt, KMinTInt);
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+void CTMultiPtrEventTest::CreateAnimDllAndAnimL()
+ {
+ iAnimDll = new(ELeave) RAnimDll(iMultiPtrEventClient->iWs);
+ User::LeaveIfError(iAnimDll->Load(KAnimDLLName));
+ iAnim = RMultiPointerAnim::NewL(iMultiPtrEventClient->ParentWin()->BaseWin(), iAnimDll);
+ }
+
+void CTMultiPtrEventTest::DestroyAnimDllAndAnim()
+ {
+ if (iAnim)
+ {
+ iAnim->Destroy();
+ iAnim = NULL;
+ }
+ if (iAnimDll)
+ {
+ iAnimDll->Destroy();
+ iAnimDll = NULL;
+ }
+ }
+
+void CTMultiPtrEventTest::CreateGroupWinL()
+ {
+ iGroupWinForEmul = new(ELeave) CTWindowGroup(iMultiPtrEventClient);
+ iGroupWinForEmul->ConstructL();
+ iGroupWinForEmul->GroupWin()->AutoForeground(ETrue);
+ iGroupWinForEmul->GroupWin()->EnableFocusChangeEvents();
+
+ iWinForEmul = new(ELeave) CTBlankWindow();
+ iWinForEmul->ConstructL(*iGroupWinForEmul);
+ iWinForEmul->SetExt(TPoint(50,50), TSize(80,80));
+ iWinForEmul->SetColor(KRgbDarkYellow);
+ iWinForEmul->Activate();
+ }
+
+void CTMultiPtrEventTest::DeleteGroupWin()
+ {
+ if (iWinForEmul)
+ {
+ delete iWinForEmul;
+ iWinForEmul = NULL;
+ }
+ if (iGroupWinForEmul)
+ {
+ delete iGroupWinForEmul;
+ iGroupWinForEmul = NULL;
+ }
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0029
+@SYMPREQ PREQ1226
+@SYMREQ REQ9688
+@SYMTestPriority High
+@SYMTestCaseDesc Tests the emulation rules for Apps, Anims, Autofocus and Buffered delivery
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate event to make a pointer primary. EnableAdvancedPointers API is not called. And then simulate events from other pointers
+@SYMTestExpectedResults The events from other pointer are not received
+*/
+void CTMultiPtrEventTest::EmulationRulesForMultiplePointers()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "Emulation rules set of events: %d of 15");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetExpectNonAdvancedPointerEvents();
+ SetAutoFlush();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos(10,10);
+ TInt proxValue = -iProximityStep;
+ TInt prValue = iPressureStep;
+ TInt ptrNum = 0;
+ switch(iEventSet++)
+ {
+ case 0:
+ // This event is for simulated/primary pointer
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Parent window has not called EnableAdvancedPointers API
+ // So even if we simulate moves and out-of-range these are not delivered to client
+ for (ptrNum = 1; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ }
+ break;
+ case 1:
+ // Since the primary pointer is 0, simulate EButton1Down for making pointer 1 as primary
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Simulate move or Ebutton1Down from pointer0 they are NOT sent back to client
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 2:
+ // Simulate EButton1Down from pointer0 to make it primary
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, 0);
+
+ // Move from pointer1
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+
+ // Take the zero pointer out-of-range, this will not result in Pointer 1 becoming primary
+ // and out-of-range event is sent to client
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, 0);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, 0);
+
+ // Send moves from pointer1, but these are not sent to the Client.
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 3:
+ // Simulate EButton1Down from pointer0 to make it primary
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Simulate EButton1Down from pointer1, which is not sent to client
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Drag events are not sent becasue pointer1 has NOT become primary
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ // Simulate up from pointer1, still not primary, so event is not sent
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ // Simulate out-of-range from pointer1, still not primary, so event is not sent
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ // Now moves from out-of-range to move state
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 4:
+ // pointer0 sends move (becomes primary)
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // pointer0 sends down
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // pointer1 sends down, doesn't become primary
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ // pointer0 sends up, stays primary
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // pointer2, pointer3 and pointer4 sends move with proximity -5, -10, -15
+ for (ptrNum = 2; ptrNum < iMaxDevPointers; ptrNum++, proxValue -= iProximityStep)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ }
+
+ // pointer0 sends out-of-range, loses primary pointer, But NO events are sent
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Send moves for pointer2, pointer3 and pointer4.
+ // None of the evnst are sent
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 2; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ ptrPos.iX += 10;
+ ptrPos.iY += 5;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ }
+
+ // Drag from pointer1, NOT sent, since it is not primary
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, 1);
+
+ // Send out-of-range from all pointers
+ for (ptrNum = 2; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ }
+
+ // As the pointer1 is down, this will not become primary even if EButton1Up is called
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ // And now sending out-of-range will also not send the event to client as it is not primary
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+ break;
+ case 5:
+ // Test cases 5 - 7 represent one discrete test for PointerRepeatEvents
+ // Case 5 simulates EButton1Down events only. This is to ensure the event is delivered to the client.
+ // If the event remained in the window queue the PointerRepeatEvent request would be cancelled when PointerRepeatPurgeCheck is performed.
+ ptrPos.SetXY(0,0);
+
+ // pointer0 sends down (become primary)
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // pointer1 sends down, doesn't become primary
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ // pointer4 sends down
+ if (4 < iMaxDevPointers)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 4);
+ }
+ break;
+ case 6:
+ ptrPos.SetXY(0,0);
+ // Simulate client calling RequestPointerRepeatEvent in response to EButton1Down event being within a 'hitbox'.
+ // Legacy API called which does not specify a pointer number. EButtonRepeat should be generated for primary pointer only.
+ iMultiPtrEventClient->ParentWin()->BaseWin()->RequestPointerRepeatEvent(TTimeIntervalMicroSeconds32(100000),TRect(TPoint(0,0), TSize(20,20)));
+ User::After(200000);
+ AddExpectedPointerEvent(TPointerEvent::EButtonRepeat, ptrPos, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 7:
+ // pointer0 sends up
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // pointer2 sends out-of-range
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Send up and out-of-range for pointer1 and 4
+ SimulatePointerEvent(TRawEvent::EButton1Up, 0, 0, 0, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ if (4 < iMaxDevPointers)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, 0, 0, 0, 4);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 4);
+ }
+ break;
+ case 8:
+ // Autofocus does not work for other than primary pointers
+ // Create group window which will send focus lost and gained
+ TRAPD(err, CreateGroupWinL()); // it cannot leave so trap and fail
+ if (err != KErrNone)
+ {
+ Failed();
+ }
+ AddExpectedWsEvent(EEventFocusLost);
+ AddExpectedWsEvent(EEventFocusGained);
+
+ // Simulate Epointer down which will send focuslost, focusgained and focusgroupchanged events
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedWsEvent(EEventFocusLost);
+ AddExpectedWsEvent(EEventFocusGained);
+ AddExpectedWsEvent(EEventFocusGroupChanged);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Now simulate EButton1Down from first or second pointer on second group
+ // This should not reflect the autofocus
+ ptrPos.iX = 60;
+ ptrPos.iY = 60;
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+ if (2 < iMaxDevPointers)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 2);
+ }
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+ if (2 < iMaxDevPointers)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 2);
+ }
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 9:
+ // First thing to do in this case is to delete the group window created
+ DeleteGroupWin();
+
+ TRAP(err, CreateAnimDllAndAnimL()); // it cannot leave so trap and fail
+ if (err != KErrNone)
+ {
+ Failed();
+ }
+
+ // This is the first event which makes first pointer as primary
+ // When the last argument is EFalse, it means that the event is not consumed by Anim
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EPointerMove, ptrPos, 0, 0, 0, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+
+ // Now simulate moves from other pointers and these events are not sent to anim
+ for (ptrNum = 1; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ }
+
+ // This is to reset the primary pointer
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EPointer3DOutOfRange, ptrPos, 0, 0, 0, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+
+ // Now simulate EButton1Down, which will make it as primary
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Down, ptrPos, 0, 0, 1, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ // Simulate move or Ebutton1Down from any other prointer they are not sent back to client
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Up, ptrPos, 0, 0, 1, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EPointer3DOutOfRange, ptrPos, 0, 0, 1, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ // Set the primary pointer to Zero
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Down, ptrPos, 0, 0, 0, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+
+ // Move from second pointer
+ // As EnableMultiPointer is not called and this is not a primary pointer so this event
+ // will cause the pointer 1 into move state
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+
+ // Take the zero pointer out-of-range
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Up, ptrPos, 0, 0, 0, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EPointer3DOutOfRange, ptrPos, 0, 0, 0, EFalse);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+
+ // These moves will not be sent
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ TestAndDisplayAnimError();
+
+ _LIT(KEventsChecked, "Events checked at server side = %d");
+ logText.Format(KEventsChecked, 10);
+ LOG_MESSAGE(logText);
+ break;
+ case 10:
+ DestroyAnimDllAndAnim();
+
+ // Test for PointerMove buffers
+ // AllocPointerMoveBuffer, EnablePointerMoveBuffer and then simulate few moves
+ // Add these moves to another points buffer for testing
+ // Simulate moves from other pointers, these should not be delivered to clients.
+ iMultiPtrEventClient->ParentWin()->BaseWin()->AllocPointerMoveBuffer(10, 0);
+ iMultiPtrEventClient->ParentWin()->BaseWin()->EnablePointerMoveBuffer();
+
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedWsEvent(EEventPointerBufferReady, EFalse, TAdvancedPointerEvent::EDefaultPointerNumber, (TUint)iMultiPtrEventClient->ParentWin());
+ iMultiPtrEventClient->AddExpectedMovePoint(ptrPos); // If this position is above some other window then we need to consider its window postion also
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ iMultiPtrEventClient->AddExpectedMovePoint(ptrPos);
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ iMultiPtrEventClient->AddExpectedMovePoint(ptrPos);
+
+ // These events should not be added to buffer
+ for (ptrNum = 1; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ }
+ break;
+ case 11:
+ // Repeat the above for drag events
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedWsEvent(EEventPointerBufferReady, EFalse, TAdvancedPointerEvent::EDefaultPointerNumber, (TUint)iMultiPtrEventClient->ParentWin());
+ iMultiPtrEventClient->AddExpectedMovePoint(ptrPos);
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ iMultiPtrEventClient->AddExpectedMovePoint(ptrPos);
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, 0);
+ iMultiPtrEventClient->AddExpectedMovePoint(ptrPos);
+
+ // These events should not be added to buffer
+ for (ptrNum = 1; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += 10;
+ ptrPos.iY += 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ }
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 12:
+ iMultiPtrEventClient->ParentWin()->BaseWin()->FreePointerMoveBuffer();
+ iMultiPtrEventClient->ParentWin()->BaseWin()->DisablePointerMoveBuffer();
+
+ // Pointer Cursor Position test
+ // This event is for simulating primary pointer
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ // Here I am not adding the event because this event is deleted by another move of same pointer
+ if (ptrPos != iMultiPtrEventClient->iWs.PointerCursorPosition())
+ {
+ TEST(EFalse);
+ Failed();
+ }
+
+ iMultiPtrEventClient->iWs.SetPointerCursorPosition(TPoint(20,20));
+ if (TPoint(20,20) != iMultiPtrEventClient->iWs.PointerCursorPosition())
+ {
+ TEST(EFalse);
+ Failed();
+ }
+
+ // Now simulate moves from other pointer, this should not have any effect on pointer cursor position
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+
+ // Now move the primary pointer, and check the pointer cursor position which should be same as position used for move
+ ptrPos.iX = 30;
+ ptrPos.iY = 30;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ if (ptrPos != iMultiPtrEventClient->iWs.PointerCursorPosition())
+ {
+ TEST(EFalse);
+ Failed();
+ }
+
+ // Send out-of-range event which will not lead to pointer 1 becoming primary
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Now check the pointer cursor position, which should be same
+ // as primary even if there is other pointer in up state, but that is not primary
+ if (ptrPos != iMultiPtrEventClient->iWs.PointerCursorPosition())
+ {
+ TEST(EFalse);
+ Failed();
+ }
+
+ // This is to bring the pointer1 to out-of-range state
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ // then send move event and then again check the pointer cursor position
+ ptrPos.iX = 20;
+ ptrPos.iY = 20;
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ if (ptrPos != iMultiPtrEventClient->iWs.PointerCursorPosition())
+ {
+ TEST(EFalse);
+ Failed();
+ }
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ break;
+ case 13:
+ {
+ // Pointer Cursor Area test-1
+ iOrigPtrCursorArea = iMultiPtrEventClient->iWs.PointerCursorArea();
+ TRect ptrCurArea(0,0,40,40);
+ iMultiPtrEventClient->iWs.SetPointerCursorArea(ptrCurArea);
+
+ // Simulate move from pointer0 in PointerCursorArea
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Simulate move from other pointer, This should have no effect
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Repeat the above with moves outside pointer cursor area
+ ptrPos.iX = 50;
+ ptrPos.iY = 50;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 0);
+ TPoint pointInCurArea(39, 39);
+ AddExpectedPointerEvent(TPointerEvent::EMove, pointInCurArea, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Simulate move from other pointer, This should have no effect
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, pointInCurArea, proxValue, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ }
+ break;
+ case 14:
+ {
+ // Pointer Cursor Area test-2
+ // repeat the above test with button1 down
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Simulate move from other pointer, This should have no effect
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Repeat the above with moves outside pointer cursor area
+ ptrPos.iX = 50;
+ ptrPos.iY = 50;
+ TPoint pointInCurArea(39, 39);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, pointInCurArea, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ // Simulate move from other pointer, This should have no effect
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, 1);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 1);
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 1);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, pointInCurArea, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, pointInCurArea, 0, 0, TAdvancedPointerEvent::EDefaultPointerNumber);
+ }
+ break;
+ default:
+ ClearExpectNonAdvancedPointerEvents();
+ iMultiPtrEventClient->iWs.SetPointerCursorArea(iOrigPtrCursorArea);
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0026
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677, REQ9683
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports Autofocus for multiple pointers
+@SYMTestStatus Implemented
+
+@SYMTestActions Create 2 group window and respective client windows for it. And simulate EButton1Down on each window consecutively
+@SYMTestExpectedResults The received events must match the simulated pointer events
+*/
+void CTMultiPtrEventTest::AutoForeGroundForMultiplePointersL()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "Multiple pointer Auto foreground events: %d of 2");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ AddExpectedWsEvent(EEventFocusGained); // This if for the main groupwindow
+ iMultiPtrEventClient->ConstructGroupBlankWinL();
+
+ // These are for child group window creation
+ AddExpectedWsEvent(EEventFocusLost); // This if for the main groupwindow losing focus
+ AddExpectedWsEvent(EEventFocusGained); // First group window of this test creation
+
+ AddExpectedWsEvent(EEventFocusLost); // First group window losing focus because of second group creation
+ AddExpectedWsEvent(EEventFocusGained); // Second group window creation
+ AddExpectedWsEvent(EEventFocusGroupChanged); // First group window's Enable Focus changed flag is set
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint win1PtrPos(20,20);
+ TPoint win2PtrPos(60,60);
+ TPoint ptrPos;
+ TInt autoFocusWin;
+ switch(iEventSet++)
+ {
+ case 0:
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ if ((ptrNum & 1) == 0)
+ {
+ ptrPos = win1PtrPos;
+ autoFocusWin = 1;
+ }
+ else
+ {
+ ptrPos = win2PtrPos;
+ autoFocusWin = 0;
+ }
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedWsEvent(EEventFocusLost); // Second group window losing focus
+ AddExpectedWsEvent(EEventFocusGained); // First group window gaining focus
+ if (ptrNum == 0)
+ { // First group window has already received EEventFocusGroupChanged
+ AddExpectedWsEvent(EEventFocusGroupChanged); // Second group window's Enable Focus changed flag is set
+ }
+ // In the queue only once EEventFocusGroupChanged is sent
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+
+ // These events are to clear out the pointer state
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, ptrNum);
+
+ if (!iMultiPtrEventClient->CheckOrdinalPosition(autoFocusWin))
+ {
+ TEST(EFalse);
+ Failed();
+ }
+ }
+ break;
+ case 1:
+ for (TInt ptrNum = iMaxDevPointers/2; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ if ((ptrNum & 1) == 0)
+ {
+ ptrPos = win1PtrPos;
+ autoFocusWin = 1;
+ }
+ else
+ {
+ ptrPos = win2PtrPos;
+ autoFocusWin = 0;
+ }
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedWsEvent(EEventFocusLost); // Second group window losing focus
+ AddExpectedWsEvent(EEventFocusGained); // First group window gaining focus
+ if (ptrNum == iMaxDevPointers/2) // first loop
+ {
+ // When ever a group window changes focus, For all the group/client windows which have
+ // registered for receiving group window changes recive EEventFocusGroupChanged
+ // EEventFocusGroupChanged is sent only once in one queue
+ AddExpectedWsEvent(EEventFocusGroupChanged);
+ AddExpectedWsEvent(EEventFocusGroupChanged);
+ }
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+
+ // These events are to clear out the pointer state
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, 0, 0, ptrNum);
+ if (!iMultiPtrEventClient->CheckOrdinalPosition(autoFocusWin))
+ {
+ TEST(EFalse);
+ Failed();
+ }
+ }
+ break;
+ default:
+ iMultiPtrEventClient->DeleteGroupBlankWin();
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0015
+@SYMPREQ PREQ1226
+@SYMREQ REQ9684
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports out-of-range and pointer Enter/Exit events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate moves and EPointer3DOutOfRange from different pointers
+@SYMTestExpectedResults The received events must match the simulated pointer events
+*/
+void CTMultiPtrEventTest::MultiPointerOutOfRangeEvents()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "OutOfRange & Enter/Exit events: %d of 4");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos(10,10);
+ TInt proxValue = -iProximityStep;
+ switch(iEventSet++)
+ {
+ case 0:
+ // Simulate moves and EPointer3DOutOfRange from all pointers
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ // Here I am not enabling the enter/exit events filter so not getting those
+ }
+ break;
+ case 1:
+ // Repeat the above by enabling the enter/exit events
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterEnterExit, 0);
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum = ptrNum+2)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedWsEvent(EEventPointerEnter, EFalse, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedWsEvent(EEventPointerExit, EFalse, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ case 2:
+ // Check the moves from one window to other
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum = ptrNum+2)
+ {
+ ptrPos.iX = 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedWsEvent(EEventPointerEnter, EFalse, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+
+ ptrPos.iX = (iMultiPtrEventClient->ParentWin()->Size().iWidth)/2 + 10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedWsEvent(EEventPointerExit, EFalse, ptrNum); // move and enter of child window is filtered out
+ }
+ break;
+ case 3:
+ // Since all the pointers are now on child and when we change the pointer filter
+ // wserv sends enter event to all pointers
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerFilterEnterExit, 0);
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum = ptrNum+2)
+ {
+ AddExpectedWsEvent(EEventPointerEnter, EFalse, ptrNum);
+ }
+ for (TInt ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum = ptrNum+2)
+ {
+ ptrPos.iX = ptrPos.iY =10;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedWsEvent(EEventPointerExit, EFalse, ptrNum);
+ AddExpectedWsEvent(EEventPointerEnter, EFalse, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, 0, 0, 0, ptrNum);
+ AddExpectedWsEvent(EEventPointerExit, EFalse, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EOutOfRange, ptrPos, proxValue, 0, ptrNum);
+ }
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0032
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports Double click events for multi pointer events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate double click events from different pointers
+@SYMTestExpectedResults The received events must match the simulated pointer events
+*/
+void CTMultiPtrEventTest::DoubleClickForMultiplePointers()
+ {
+ // Logic involved, double click settings are global no need to test them
+ // Check that double click events are sent by wserv for all pointers
+ TLogMessageText logText;
+ _LIT(KSet, "Double click settings and events: %d of 1");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos(10,10);
+ switch(iEventSet++)
+ {
+ case 0:
+ for (TInt ptrNum = 0; ptrNum < Min(iMaxDevPointers, 7); ptrNum++)
+ {
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, EModifierDoubleClick, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+ }
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0031
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports Virtual keyboard for multi pointer events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Create virtual keyboard by AddKeyRect() to a window and simulate pointer events from all pointers
+@SYMTestExpectedResults The received events must match the simulated Key events
+*/
+void CTMultiPtrEventTest::VirtualKeyBoardForMultiplePointers()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "VirtualKeyboard SetOfEvents: %d of 8");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ // Create virtual keyboard for 8 keys on parent window
+ // give a 5 pixel spacing at start/end and in between keys
+ const TInt noVirtualKeys = iMaxDevPointers;
+ const TInt keySpacing = 5;
+ const TInt keyWidth = ((iPhysicalScreenSize.iWidth/2) - ((noVirtualKeys+1)*keySpacing))/noVirtualKeys;
+ const TInt keyHeight = keyWidth/2;
+ TInt startX = keySpacing;
+ const TInt baseChar ='A';
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ for (TInt count=0; count < noVirtualKeys; count++)
+ {
+ iMultiPtrEventClient->ParentWin()->BaseWin()->AddKeyRect(TRect(startX, keySpacing, startX+keyWidth, keySpacing+keyHeight), baseChar+count,EFalse);
+ startX+=(keyWidth+keySpacing);
+ }
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ TPoint ptrPos(keySpacing+(keyWidth/2), keySpacing+(keyHeight/2));
+
+ TInt count = 0;
+ if (iEventSet < iMaxDevPointers)
+ {
+ for (; ptrPos.iX < (iPhysicalScreenSize.iWidth/2)-5; ptrPos.iX += (keySpacing+keyWidth), count++)
+ {
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, iEventSet);
+ AddExpectedKeyDownUp(baseChar+count);
+ }
+ }
+ else
+ {
+ ResetFlushStopAS();
+ }
+ iEventSet++;
+
+ LogEventsAdded();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0021
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677,REQ9683,
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports Grabbing in case of multi pointer events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate EButton1Down events on iParentWin. Simulate Drag and Button1Up events on iChildWin.
+ SetPointerGrab is called on iParentWin for first test and disabled for the second.
+@SYMTestExpectedResults The Drag and Button1Up events contain a handle to iParentWin when Grabbing active.
+ The Drag and Button1Up events contain a handle to iChildWin when Grabbing disabled.
+*/
+void CTMultiPtrEventTest::GrabbingMultiPointerEvents()
+ {
+ // Test Grabbing of multi pointer events
+ // 1. Test Wserv supports Grabbing in case of multi-pointer events
+ // 2. Test pointer events are delivered correctly when Grabbing is disabled.
+ TLogMessageText logText;
+ _LIT(KSet, "GrabbingMultiPtrEvents SetOfEvents: %d of 2");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ }
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ INFO_PRINTF1(_L("Check Wserv supports Grabbing in case of multi-pointer events"));
+ // Check pointer events are delivered to the window where the EButton1Down event occured,
+ // even if subsequent events are simulated outside this window.
+ AddExpectedWsEvent(EEventFocusGained);
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag, 0);
+ iMultiPtrEventClient->ParentWin()->BaseWin()->SetPointerGrab(ETrue);
+ TestGrabbingForMultiPointer(ETrue);
+ break;
+ case 1:
+ INFO_PRINTF1(_L("Check pointer events are delivered correctly when Grabbing is disabled."));
+ // Check pointer events are delivered to the window on which they occured.
+ iMultiPtrEventClient->ParentWin()->BaseWin()->SetPointerGrab(EFalse);
+ TestGrabbingForMultiPointer(EFalse);
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0025
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677,REQ9683,
+@SYMTestPriority High
+@SYMTestCaseDesc Checks Wserv supports Filtering in case of multi pointer events.
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate Move and Drag events. Add only Button1Up and Button1Down to TWsEvent buffer.
+ Disable Filtering and repeat test with the addition of Move and Drag events to TWsEvent buffer.
+@SYMTestExpectedResults The received events must match the expected simulated raw events
+ The received events must match the simulated raw events
+*/
+void CTMultiPtrEventTest::FilteringMultiPointerEvents()
+ {
+ // Test Filtering of multi pointer events
+ // 1. Test pointer move and drag events are filtered correctly by Wserv
+ // 2. Test pointer events are delivered correctly when Filtered is disabled.
+ TLogMessageText logText;
+ _LIT(KSet, "FilteringMultiPtrEvents SetOfEvents: %d of 2");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ }
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ INFO_PRINTF1(_L("Check pointer move and drag events are filtered with multi-pointer events"));
+ // Check pointer move and drag events are filtered by Wserv
+ AddExpectedWsEvent(EEventFocusGained);
+
+ // Ensure default values are set i.e. Drag and Move events are filtered out and not delivered to the client.
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag|EPointerFilterMove,
+ EPointerFilterDrag|EPointerFilterMove);
+ TestFilteringForMultiPointer(ETrue);
+ break;
+ case 1:
+ INFO_PRINTF1(_L("Check pointer move and drag events are not filtered, with multi-pointer events, when filtering is disabled"));
+ // Check move and drag events are not filtered by Wserv when filtering is disabled
+
+ // Enable Drag and Move events
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag|EPointerFilterMove, 0);
+ TestFilteringForMultiPointer(EFalse);
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+void CTMultiPtrEventTest::SetDefaultScreenMode()
+ {
+ iMultiPtrEventClient->iScreen->SetAppScreenMode(0);
+ TheClient->iScreen->SetAppScreenMode(0);
+ iMultiPtrEventClient->iScreen->SetScreenMode(0);
+ iMultiPtrEventClient->iScreen->SetCurrentRotations(0, CFbsBitGc::EGraphicsOrientationNormal);
+ }
+
+TPoint PhysicalToLogical(TPoint aPhysicalPt, TPoint aOrigin, TSize aSize)
+ {
+ return PhysicalToLogical(aPhysicalPt-aOrigin, aSize);
+ }
+
+TPoint CTMultiPtrEventTest::GetPointerPostionOnRotatedMode(TPoint aPointerPos, CFbsBitGc::TGraphicsOrientation aRotation)
+ {
+ if (aRotation == CFbsBitGc::EGraphicsOrientationNormal)
+ {
+ return aPointerPos;
+ }
+ else if (aRotation == CFbsBitGc::EGraphicsOrientationRotated90)
+ {
+ // here width is actually height in rotated mode
+ return TPoint(iPhysicalScreenSize.iWidth - aPointerPos.iY - 1, aPointerPos.iX);
+ }
+ else if (aRotation == CFbsBitGc::EGraphicsOrientationRotated180)
+ {
+ return TPoint(iPhysicalScreenSize.iWidth - aPointerPos.iX - 1, iPhysicalScreenSize.iHeight - aPointerPos.iY - 1);
+ }
+ else if (aRotation == CFbsBitGc::EGraphicsOrientationRotated270)
+ {
+ // here width is actually height in rotated mode
+ return TPoint(aPointerPos.iY, iPhysicalScreenSize.iHeight - aPointerPos.iX -1);
+ }
+ return TPoint(0,0);
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0028
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677, REQ9683
+@SYMTestPriority High
+@SYMTestCaseDesc To check Wserv sends multi pointer events in Different screen modes
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate multi pointer events in Different screenmodes
+@SYMTestExpectedResults The received events must match the simulated raw events
+*/
+void CTMultiPtrEventTest::MultiPointerEventsInDiffScreenModes()
+ {
+ // Logic inloved, For a particular screen mode check pointer down/up, moves and drags
+ // for different pointers and for different co-ordinates.
+ // For each screen mode check these events on diffferent rotation that screen mode supports
+ // During the last switch case increment the screenmode
+ TLogMessageText logText;
+ _LIT(KSet, "Multi pointer events in screenmode(%d): %d of 2");
+ logText.AppendFormat(KSet, iCurrentScreenMode+1, iEventSet);
+ LOG_MESSAGE(logText);
+
+ TInt numScrMode = iMultiPtrEventClient->iScreen->NumScreenModes();
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ if (!iEventSet && !iChangeScreenMode)
+ {
+ SetAutoFlush();
+ iChangeScreenMode = ETrue;
+ AddExpectedWsEvent(EEventFocusGained);
+ }
+ else
+ {
+ if (iChangeScreenMode)
+ {
+ if (iCurrentScreenMode >= numScrMode)
+ {
+EndFun:
+ SetDefaultScreenMode();
+ ResetFlushStopAS();
+ return;
+ }
+ }
+ }
+
+ if (iChangeScreenMode)
+ {
+ iMultiPtrEventClient->iScreen->SetAppScreenMode(iCurrentScreenMode);
+ TheClient->iScreen->SetAppScreenMode(iCurrentScreenMode);
+ iMultiPtrEventClient->iScreen->SetScreenMode(iCurrentScreenMode);
+ iChangeScreenMode = EFalse;
+ }
+
+ CArrayFixFlat<TInt>* rotations = NULL;
+ TRAPD(err,
+ rotations = new(ELeave) CArrayFixFlat<TInt>(1);
+ iMultiPtrEventClient->iScreen->GetRotationsList(iCurrentScreenMode, rotations));
+ if (err != KErrNone)
+ {
+ if (iEventSet)
+ {
+ goto EndFun;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+#if !defined(__WINS__)
+ TPoint ptrRotatedPos;
+ TPoint ptrNormalPos;
+#else
+ TPoint ptrPhyPos;
+#endif
+ TPoint ptrLogPos;
+
+ TInt ptrNum = 0;
+ TInt proxValue = 0;
+ // Since screenmode positioning and screenmode scaling is not supported in NGA wserv2
+ // but it is supported in Non NGA. But for NGA it will return (0,0) as origin and (1,1) as scale.
+ TPoint screenOrigin(iMultiPtrEventClient->iScreen->GetDefaultScreenModeOrigin());
+ TPoint scaledScreenOrigin(iMultiPtrEventClient->iScreen->GetCurrentScreenModeScaledOrigin());
+ TSize scale(iMultiPtrEventClient->iScreen->GetCurrentScreenModeScale());
+
+ switch(iEventSet++)
+ {
+ case 0:
+ // Simulate Pointer down/up for different rotations of a screenmode
+ for (TInt rotCou = 0; rotCou < rotations->Count(); rotCou++)
+ {
+ CFbsBitGc::TGraphicsOrientation newOrientation = static_cast<CFbsBitGc::TGraphicsOrientation>(rotations[0][rotCou]);
+ iMultiPtrEventClient->iScreen->SetCurrentRotations(iCurrentScreenMode, newOrientation);
+
+#if !defined(__WINS__)
+ ptrNormalPos = screenOrigin;
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ SimulatePointerDownUp(ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+
+ ptrNormalPos.iX += 10;
+ ptrNormalPos.iY += 5;
+ ptrNum = iMaxDevPointers/2;
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ SimulatePointerDownUp(ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+
+ ptrNormalPos.iX += 5;
+ ptrNormalPos.iY += 10;
+ ptrNum = iMaxDevPointers-1;
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ SimulatePointerDownUp(ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+ ptrNum = 0;
+#else
+ // This is not needed for NGA, becasue NGA wserv does not support positioning and scaling
+ // but for early access we are deliverying for NonNGA so we need it.
+ ptrPhyPos = screenOrigin;
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ SimulatePointerDownUp(ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+ ptrPhyPos.iX += 10;
+ ptrPhyPos.iY += 5;
+ ptrNum = iMaxDevPointers/2;
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ SimulatePointerDownUp(ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+ ptrPhyPos.iX += 5;
+ ptrPhyPos.iY += 10;
+ ptrNum = iMaxDevPointers-1;
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ SimulatePointerDownUp(ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+ ptrNum = 0;
+#endif
+ }
+ break;
+ case 1:
+ // Simulate moves for different rotations of a screenmode with different Proximity
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove,0);
+ for (TInt rotCou = 0; rotCou < rotations->Count(); rotCou++)
+ {
+ CFbsBitGc::TGraphicsOrientation newOrientation = static_cast<CFbsBitGc::TGraphicsOrientation>(rotations[0][rotCou]);
+ iMultiPtrEventClient->iScreen->SetCurrentRotations(iCurrentScreenMode, newOrientation);
+
+#if !defined(__WINS__)
+ ptrNormalPos = screenOrigin;
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ proxValue = -iProximityStep;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrRotatedPos.iX, ptrRotatedPos.iY, proxValue, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrLogPos, proxValue, 0, ptrNum);
+ SimulatePointerDownUp(ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+
+ ptrNormalPos.iX += 10;
+ ptrNormalPos.iY += 5;
+ ptrNum = iMaxDevPointers/2;
+ if (proxValue-iProximityStep > iMaxProximity)
+ {
+ proxValue -= iProximityStep;
+ }
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrRotatedPos.iX, ptrRotatedPos.iY, proxValue, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrLogPos, proxValue, 0, ptrNum);
+ SimulatePointerDownUp(ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+ ptrNum = 0;
+#else
+ ptrPhyPos = screenOrigin;
+ proxValue = -iProximityStep;
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPhyPos.iX, ptrPhyPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrLogPos, proxValue, 0, ptrNum);
+ SimulatePointerDownUp(ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+
+ ptrPhyPos.iX += 10;
+ ptrPhyPos.iY += 5;
+ ptrNum = iMaxDevPointers/2;
+ if (proxValue-iProximityStep > iMaxProximity)
+ {
+ proxValue -= iProximityStep;
+ }
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPhyPos.iX, ptrPhyPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrLogPos, proxValue, 0, ptrNum);
+ SimulatePointerDownUp(ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrLogPos, 0, ptrNum);
+ ptrNum = 0;
+#endif
+ }
+ break;
+ case 2:
+ {
+ // Simulate drags for different rotations of a screenmode
+#if !defined(__WINS__)
+ TPoint intNormalPt;
+ TPoint intRotatedPt;
+#else
+ TPoint interPhyPt;
+ TPoint interLogPt;
+#endif
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag,0);
+ for (TInt rotCou = 0; rotCou < rotations->Count(); rotCou++)
+ {
+ CFbsBitGc::TGraphicsOrientation newOrientation = static_cast<CFbsBitGc::TGraphicsOrientation>(rotations[0][rotCou]);
+ iMultiPtrEventClient->iScreen->SetCurrentRotations(iCurrentScreenMode, newOrientation);
+#if !defined(__WINS__)
+ ptrNormalPos = screenOrigin;
+ intNormalPt.iX = ptrNormalPos.iX+4;
+ intNormalPt.iY = ptrNormalPos.iY+5;
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ intRotatedPt = GetPointerPostionOnRotatedMode(intNormalPt, newOrientation);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, intRotatedPt.iX, intRotatedPt.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, intRotatedPt.iX, intRotatedPt.iY, 0, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrLogPos, 0, 0, ptrNum);
+ TPoint intLogPt = PhysicalToLogical(intNormalPt, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, intLogPt, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, intLogPt, 0, 0, ptrNum);
+
+ ptrNormalPos.iX += 10;
+ ptrNormalPos.iY += 5;
+ ptrNum = iMaxDevPointers-1;
+ intNormalPt.iX = ptrNormalPos.iX+5;
+ intNormalPt.iY = ptrNormalPos.iY+4;
+ ptrRotatedPos = GetPointerPostionOnRotatedMode(ptrNormalPos, newOrientation);
+ intRotatedPt = GetPointerPostionOnRotatedMode(intNormalPt, newOrientation);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrRotatedPos.iX, ptrRotatedPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, intRotatedPt.iX, intRotatedPt.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, intRotatedPt.iX, intRotatedPt.iY, 0, ptrNum);
+ ptrLogPos = PhysicalToLogical(ptrNormalPos, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrLogPos, 0, 0, ptrNum);
+ intLogPt = PhysicalToLogical(intNormalPt, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, intLogPt, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, intLogPt, 0, 0, ptrNum);
+
+ ptrNum = 0;
+#else
+ ptrPhyPos = screenOrigin;
+ interPhyPt.iX = ptrPhyPos.iX+4;
+ interPhyPt.iY = ptrPhyPos.iY+5;
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ interLogPt = PhysicalToLogical(interPhyPt, screenOrigin, scale);
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPhyPt.iX, interPhyPt.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPhyPt.iX, interPhyPt.iY, 0, ptrNum);
+ interLogPt = PhysicalToLogical(interPhyPt, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrLogPos, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interLogPt, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interLogPt, 0, 0, ptrNum);
+
+ ptrPhyPos.iX += 10;
+ ptrPhyPos.iY += 5;
+ ptrNum = iMaxDevPointers-1;
+ interPhyPt.iX = ptrPhyPos.iX+5;
+ interPhyPt.iY = ptrPhyPos.iY+4;
+
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPhyPos.iX, ptrPhyPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPhyPt.iX, interPhyPt.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPhyPt.iX, interPhyPt.iY, 0, ptrNum);
+
+ ptrLogPos = PhysicalToLogical(ptrPhyPos, screenOrigin, scale);
+ interLogPt = PhysicalToLogical(interPhyPt, screenOrigin, scale);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrLogPos, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interLogPt, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interLogPt, 0, 0, ptrNum);
+ ptrNum = 0;
+#endif
+ }
+ }
+ iChangeScreenMode = ETrue;
+ iEventSet = 0;
+ iCurrentScreenMode++;
+ break;
+ default:
+ break;
+ }
+
+ delete rotations;
+
+ LogEventsAdded();
+ }
+
+/*
+ Checks if pointer click plugin has an error when testing its events
+ If so then it gets the error deescription and displays the same
+ */
+void CTMultiPtrEventTest::TestAndDisplayPtrClickError()
+ {
+ TPckgBuf<TInt> intPkg;
+ TInt retErr = iClick.CommandReply(EMultiPtrClickEventError, intPkg);
+ if (retErr != KErrNone)
+ {
+ _LIT(KError, "Failed in Pointer click plugin");
+ LOG_MESSAGE(KError);
+ // Error is ignored here, becasue this function should not leave
+ TRAPD(errMem, iErrDesc = iHeap->AllocL(KErrDescSize));
+ if (errMem == KErrNone)
+ {
+ intPkg() = reinterpret_cast<TUint8*>(iErrDesc) - iChunk.Base() ;
+
+ // get the error desccription, print it out and stop the tests
+ TInt retVal = iClick.CommandReply(EADllMultiPtrEventErrorDesc, intPkg);
+ if (retVal > KErrNone)
+ {
+ TPtr8 memPtr2(reinterpret_cast<TUint8*>(iErrDesc), retVal, retVal);
+ HBufC16* buf16 = NULL;
+ TRAPD(err, buf16 = HBufC16::NewL(retVal)); // Error is ignored here
+ if (err == KErrNone)
+ {
+ buf16->Des().Copy(memPtr2);
+ LOG_MESSAGE(buf16->Des());
+ delete buf16;
+ }
+ }
+ iHeap->Free(iErrDesc);
+ }
+ Failed();
+ }
+ iClick.CommandReply(EMultiPtrClickEventReset, intPkg);
+ }
+
+void CTMultiPtrEventTest::AddExpectedMultiPtrClickEvent(TPointerEvent::TType aType, TPoint aPos, TInt aZ, TUint aModifier, TUint8 aPointerNumber, TUint aHandle)
+ {
+ TPckgBuf<TWsEvent> evtPkg;
+ TWsEvent& event=evtPkg();
+ event.SetType(EEventPointer);
+ iMultiPtrEventClient->CalculatePtrPosAndSet3Ddata(event, aType, aPos, aModifier, aZ, aPointerNumber, aHandle);
+
+ // change the parent position here as they r with respect to screen corodinates.
+ event.Pointer()->iParentPosition = aPos;
+
+ iClick.CommandReply(EMultiPtrClickEventAdd, evtPkg);
+ AddExpectedMultiPtrClickOtherEvent(aType, aPos, aZ, aModifier, aPointerNumber, aHandle);
+ }
+
+void CTMultiPtrEventTest::AddExpectedMultiPtrClickOtherEvent(TPointerEvent::TType aType, TPoint aPos, TInt aZ, TUint aModifier, TUint8 aPointerNumber, TUint aHandle)
+ {
+ TWsEvent event;
+ event.SetType(EEventPointer);
+ iMultiPtrEventClient->CalculatePtrPosAndSet3Ddata(event, aType, aPos, aModifier, aZ, aPointerNumber, aHandle);
+
+ TPointerEventData otherEvent;
+ otherEvent.iClientHandle = event.Handle();
+ otherEvent.iCurrentPos = aPos;
+ otherEvent.iPointerEvent = *event.Pointer();
+
+ TPckgBuf<TPointerEventData> evtPkg(otherEvent);
+ iClick.CommandReply(EMultiPtrOtherEventAdd, evtPkg);
+ }
+
+/*
+ Function of creating
+ 1. Pointer click plugin
+ 2. RChunk for transfering error description from pointer click plugin to current test
+ 3. RHeap for allocating memory in RChunk
+*/
+void CTMultiPtrEventTest::CreatePointerClickPluginL()
+ {
+ // tranfer this to another function
+ iClick=RSoundPlugIn(TheClient->iWs);
+ User::LeaveIfError(iClick.Construct(TUid::Uid(MULTIPTR_CLICK_THIRD_UID)));
+ TBool ptrPluginLoadable = EFalse;
+ iClick.IsLoaded(ptrPluginLoadable);
+ if (ptrPluginLoadable)
+ {
+ User::LeaveIfError(iClick.Load(KMultiPtrPluginDll));
+ iPtrPluginLoaded = ETrue;
+ }
+ iClick.SetPenClick(ETrue);
+ iHeap = UserHeap::ChunkHeap(&KMultiPtrClickChunk, 128, 256, 10);
+ if (iHeap == NULL)
+ {
+ User::LeaveNoMemory();
+ }
+ User::LeaveIfError(iChunk.OpenGlobal(KMultiPtrClickChunk, ETrue));
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0027
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677, REQ9683
+@SYMTestPriority High
+@SYMTestCaseDesc To check Wserv sends multi pointer events to PointerClickPlugin
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate multi pointer events for PointerClickPlugin
+@SYMTestExpectedResults The received events must match the simulated raw events
+*/
+void CTMultiPtrEventTest::MultiPointerEventsForPointerClickL()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "Multi pointer events for PointerClickPlugin: %d of 4");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ }
+
+ TPoint ptrPos;
+ TInt ptrNum = 0;
+ TInt prValue = 0;
+ TInt proxValue = 0;
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ // Creates RSoundPlugin, loads the plugin DLL, create RChunk and RHeap
+ CreatePointerClickPluginL();
+ AddExpectedWsEvent(EEventFocusGained);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayPtrClickError();
+ break;
+ case 1:
+ // Simulate moves from different pointer with different pressure
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove,0);
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerFilterMove,0);
+ ptrPos.SetXY(0,0);
+ prValue = iPressureStep;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EMove, ptrPos, prValue, 0, ptrNum);
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Down,ptrPos,0,0,ptrNum);
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Up,ptrPos,0,0,ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, prValue, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayPtrClickError();
+ break;
+ case 2:
+ // Simulate moves from different pointer with different proximity
+ ptrPos.SetXY(0,0);
+ proxValue = -iProximityStep;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Down,ptrPos,0,0,ptrNum);
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Up,ptrPos,0,0,ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayPtrClickError();
+ break;
+ case 3:
+ {
+ // Simulate drags from all pointers
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag,0);
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerFilterDrag,0);
+ ptrPos.SetXY(0,0);
+ TPoint interPt;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ interPt.iX = ptrPos.iX+1;
+ interPt.iY = ptrPos.iY+2;
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrNum);
+ AddExpectedMultiPtrClickEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrNum);
+
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayPtrClickError();
+ }
+ break;
+ default:
+ iClick.Unload();
+ iClick.Close();
+ iPtrPluginLoaded = EFalse;
+ iHeap->Close();
+ iHeap = NULL;
+ iChunk.Close();
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+void CTMultiPtrEventTest::GetRemainingEventsFromSecondaryClient()
+ {
+ if (iSecMultiPtrEventClient->EventBuffer()->EventsRemaining() != 0)
+ {
+ iSecMultiPtrEventClient->EventBuffer()->SetNestedLoopState(ETrue);
+ CActiveScheduler::Start();
+ }
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0011
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677,REQ9674,
+@SYMTestPriority High
+@SYMTestCaseDesc To check Wserv sends Multi Pointer events to correct clients
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate multi pointer events on windows from different client.
+@SYMTestExpectedResults The received events must match the simulated raw events
+*/
+void CTMultiPtrEventTest::MultiClientMultiPointerEvents()
+ {
+ // Logic for this test code
+ // Create a secondary client when running this test
+ // Simulate events for both main client and secondary simulataneously
+ // Get events from DoRunL() of event buffer class
+ // Before running next set of events, get all the events from secondary client
+ // If test fails on any client make sure both active scheduler are stopped
+ TLogMessageText logText;
+ _LIT(KSet, "Multi pointer events for Multi client: %d of 5");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ iSecMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ iSecClientFlush = iSecMultiPtrEventClient->iWs.SetAutoFlush(ETrue);
+ }
+
+ TPoint ptrPos;
+ TInt ptrNum = 0;
+ TInt prValue = 0;
+ TInt proxValue = 0;
+ TInt xInc = (iPhysicalScreenSize.iWidth/2)/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+ TPoint secPt(iPhysicalScreenSize.iWidth/2,0);
+ TInt ptrSecNum = iMaxDevPointers-1;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ ptrPos.SetXY(0,0);
+
+ // These events are generated when primary client is created and its group
+ // window constructed and then when button down for primary client is called
+ AddExpectedWsEvent(EEventFocusGained);
+ AddExpectedWsEvent(EEventFocusLost);
+ AddExpectedWsEvent(EEventFocusGained);
+
+ // Simulate pointer down/up events for primary client from 0,1,3... pointers and 6,5,4... pointers for secondary client
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ ptrPos.iX = iPhysicalScreenSize.iWidth/2;
+ ptrPos.iY = 0;
+
+ // These events are generated when secondary cleint is created and then when
+ // button down for primary client is called, then when SetOrdinalPosition is
+ // called on secondary cleint's group window
+ AddExpectedWsEvent(EEventFocusGained, ETrue);
+ AddExpectedWsEvent(EEventFocusLost, ETrue);
+ iSecMultiPtrEventClient->iGroup->GroupWin()->SetOrdinalPosition(0, 1);
+ AddExpectedWsEvent(EEventFocusGained, ETrue);
+
+ AddExpectedWsEvent(EEventFocusLost);
+
+ for (ptrNum = iMaxDevPointers/2; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ break;
+ case 1:
+ // Simulate move events from primary and secondary client simultaneously with pressure
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ iSecMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+
+ ptrPos.SetXY(0,0);
+ prValue = iPressureStep;
+
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrSecNum >= iMaxDevPointers/2); ptrNum++, ptrSecNum--)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, prValue, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+
+ SimulatePointerEvent(TRawEvent::EPointerMove, secPt.iX, secPt.iY, prValue, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, secPt, prValue, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ secPt.iX += xInc;
+ secPt.iY += yInc;
+ }
+ break;
+ case 2:
+ // Simulate move events from primary and secondary client simultaneously with proximity
+ ptrPos.SetXY(0,0);
+ proxValue = -iProximityStep;
+
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrSecNum >= iMaxDevPointers/2); ptrNum++, ptrSecNum--)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+
+ SimulatePointerEvent(TRawEvent::EPointerMove, secPt.iX, secPt.iY, proxValue, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, secPt, proxValue, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ secPt.iX += xInc;
+ secPt.iY += yInc;
+ }
+ break;
+ case 3:
+ {
+ // Simulate drag events on different clients window one after the other
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag, 0);
+ iSecMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag, 0);
+
+ ptrPos.SetXY(0,0);
+ secPt.iX = iPhysicalScreenSize.iWidth/2;
+ secPt.iY = 0;
+ ptrSecNum = iMaxDevPointers-1;
+ TPoint interPt;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrSecNum >= iMaxDevPointers/2); ptrNum++, ptrSecNum--)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ interPt.iX = ptrPos.iX+2;
+ interPt.iY = ptrPos.iY+1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrNum);
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+
+ SimulatePointerEvent(TRawEvent::EButton1Down, secPt.iX, secPt.iY, 0, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, secPt, 0, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ interPt.iX = secPt.iX+2;
+ interPt.iY = secPt.iY+1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ secPt.iX += xInc;
+ secPt.iY += yInc;
+ }
+ }
+ break;
+ case 4:
+ {
+ // Simulate drag events on different clients, but interleaved each other
+ ptrPos.SetXY(0,0);
+ secPt.iX = iPhysicalScreenSize.iWidth/2;
+ secPt.iY = 0;
+ ptrSecNum = iMaxDevPointers-1;
+ TPoint interPt;
+
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrSecNum >= iMaxDevPointers/2); ptrNum++, ptrSecNum--)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+
+ SimulatePointerEvent(TRawEvent::EButton1Down, secPt.iX, secPt.iY, 0, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, secPt, 0, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ secPt.iX += xInc;
+ secPt.iY += yInc;
+ }
+
+ ptrPos.SetXY(0,0);
+ secPt.iX = iPhysicalScreenSize.iWidth/2;
+ secPt.iY = 0;
+ ptrSecNum = iMaxDevPointers-1;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrSecNum >= iMaxDevPointers/2); ptrNum++, ptrSecNum--)
+ {
+ interPt.iX = ptrPos.iX+2;
+ interPt.iY = ptrPos.iY+1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+
+
+ interPt.iX = secPt.iX+2;
+ interPt.iY = secPt.iY+1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ secPt.iX += xInc;
+ secPt.iY += yInc;
+ }
+
+ ptrPos.SetXY(0,0);
+ secPt.iX = iPhysicalScreenSize.iWidth/2;
+ secPt.iY = 0;
+ ptrSecNum = iMaxDevPointers-1;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers/2 && ptrSecNum >= iMaxDevPointers/2); ptrNum++, ptrSecNum--)
+ {
+ interPt.iX = ptrPos.iX+2;
+ interPt.iY = ptrPos.iY+1;
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+
+ interPt.iX = secPt.iX+2;
+ interPt.iY = secPt.iY+1;
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrSecNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrSecNum, (TUint)iSecMultiPtrEventClient->ParentWin(), ETrue);
+ secPt.iX += xInc;
+ secPt.iY += yInc;
+ }
+ }
+ break;
+ default:
+ ResetFlushStopAS();
+ iSecMultiPtrEventClient->iWs.SetAutoFlush(iSecClientFlush);
+ break;
+ }
+
+ _LIT(KEventsAdded, "Events added to Primary client's buffer = %d");
+ logText.Format(KEventsAdded, iMultiPtrEventClient->EventBuffer()->EventsRemaining());
+ LOG_MESSAGE(logText);
+ _LIT(KEventsAdded1, "Events added to Secondary client's buffer = %d");
+ logText.Format(KEventsAdded1, iSecMultiPtrEventClient->EventBuffer()->EventsRemaining());
+ LOG_MESSAGE(logText);
+ }
+
+
+// RMultiPointerAnim
+RMultiPointerAnim* RMultiPointerAnim::NewL(RWindowBase* aWin, RAnimDll* aDll)
+ {
+ RMultiPointerAnim* self=new(ELeave) RMultiPointerAnim(aDll);
+ CleanupStack::PushL(TCleanupItem(DestroyAnim,self));
+ User::LeaveIfError(self->Construct(*aWin, EAnimTypeMultiPointer, TPtrC8()));
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+TInt RMultiPointerAnim::AddExpectedAnimPointerEvent(TRawEvent::TType aType, TPoint aPos, TInt aZ, TUint /*aModifier*/, TUint8 aPointerNumber, TBool aEat /*= ETrue*/)
+ {
+ TRawEvent rawEvent;
+ rawEvent.Set(aType, aPos.iX, aPos.iY, aZ, aPointerNumber);
+ TAnimRawEvent animEvent;
+ animEvent.iRawEvent = rawEvent;
+ animEvent.iEat = aEat;
+ TPckgBuf<TAnimRawEvent> param;
+ param()=animEvent;
+ return CommandReply(EADllAddExpectedMultiPtrEvent, param);
+ }
+
+void CTMultiPtrEventTest::TestAndDisplayAnimError()
+ {
+ TInt err = iAnim->CommandReply(EADllMultiPtrEventError);
+ if (err != KErrNone)
+ {
+ _LIT(KError, "Failed in Anim dll");
+ LOG_MESSAGE(KError);
+ TBuf<255> errDesc;
+ errDesc.SetMax();
+ TIpcArgs ipcArgs;
+ ipcArgs.Set(KIpcSlot,&errDesc);
+ // get the error desccription, print it out and stop the tests
+ TInt retVal = iAnim->CommandReply(EADllMultiPtrEventErrorDesc, KNullDesC8, ipcArgs);
+ if (retVal == KErrNone)
+ {
+ LOG_MESSAGE(errDesc);
+ }
+ Failed();
+ }
+ iAnim->CommandReply(EADllMultiPtrEventReset);
+ }
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0013
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677,REQ9683,
+@SYMTestPriority High
+@SYMTestCaseDesc To check Wserv sends Multi Pointer events to Anims
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate multi pointer events for anims
+@SYMTestExpectedResults The received events must match the simulated raw events
+*/
+void CTMultiPtrEventTest::MultiPointerEventsForAnimsL()
+ {
+ // The logic behind these tests is
+ // Create an anim, which creates animation at server side(which swicthes raw event handling on)
+ // Add the required events to the animtaion at server side buffer
+ // Simulate those events and check simulated events are same as required at server side
+ // If any test fail, error description is got from server and displayed in the log file
+ TLogMessageText logText;
+ _LIT(KSet, "Multi pointer events for Anims: %d of 3");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+ _LIT(KEventsChecked, "Events checked at server side = %d");
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ iAnimDll = new(ELeave) RAnimDll(iMultiPtrEventClient->iWs);
+ User::LeaveIfError(iAnimDll->Load(KAnimDLLName));
+ }
+
+ TPoint ptrPos;
+ TInt ptrNum = 0;
+ TInt prValue = 0;
+ TInt proxValue = 0;
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ // Simulate downup events for all pointers
+ iAnim = RMultiPointerAnim::NewL(iMultiPtrEventClient->ParentWin()->BaseWin(), iAnimDll);
+ AddExpectedWsEvent(EEventFocusGained);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Down,ptrPos,0,0,ptrNum);
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Up,ptrPos,0,0,ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayAnimError();
+ logText.Format(KEventsChecked, iMaxDevPointers*2);
+ LOG_MESSAGE(logText);
+ break;
+ case 1:
+ // Simulate moves from different pointer with different pressure
+ // Here there is no need for events to be exaclty on the anim window.
+ // becasue when the animtaions ask for events it will be delivered all the events
+ // irrespective of where they occured.
+ ptrPos.SetXY(0,0);
+ prValue = iPressureStep;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EPointerMove, ptrPos, prValue, 0, ptrNum);
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Down,ptrPos,0,0,ptrNum);
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Up,ptrPos,0,0,ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayAnimError();
+
+ // This is for just to add run the next test
+ SimulatePointerEvent(TRawEvent::EPointerSwitchOn, 0, 0, 0, 0);
+
+ logText.Format(KEventsChecked, iMaxDevPointers*3);
+ LOG_MESSAGE(logText);
+ break;
+ case 2:
+ // Simulate moves from different pointer with different proximity
+ ptrPos.SetXY(0,0);
+ proxValue = -iProximityStep;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EPointerMove, ptrPos, proxValue, 0, ptrNum);
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Down,ptrPos,0,0,ptrNum);
+ iAnim->AddExpectedAnimPointerEvent(TRawEvent::EButton1Up,ptrPos,0,0,ptrNum);
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ TestAndDisplayAnimError();
+
+ // This is for just to add run the next test
+ SimulatePointerEvent(TRawEvent::EPointerSwitchOn, 0, 0, 0, 0);
+
+ logText.Format(KEventsChecked, iMaxDevPointers*3);
+ LOG_MESSAGE(logText);
+ break;
+ default:
+ DestroyAnimDllAndAnim();
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0014
+@SYMPREQ PREQ1226
+@SYMREQ REQ9677,REQ9683,
+@SYMTestPriority High
+@SYMTestCaseDesc To check Wserv purges multi pointer events with standard rules
+@SYMTestStatus Implemented
+
+@SYMTestActions Simulate raw events to be purged
+@SYMTestExpectedResults The purged events should not be delivered to client
+*/
+void CTMultiPtrEventTest::PurgingMultiPointerEvents()
+ {
+ // Test purging of multi pointer events
+ // 1. Test down/up pairs are purged
+ // 2. Test moves events are purged
+ // 3. Test drag events are purged
+ // 4. Test lone down events are purged
+ // 5. And finally test lone up events are also purged
+ TLogMessageText logText;
+ _LIT(KSet, "Purging of multi pointer events: %d of 6");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+ TInt xInc = iPhysicalScreenSize.iWidth/KMaxQueueSize;
+ TInt yInc = iPhysicalScreenSize.iHeight/KMaxQueueSize;
+ TPoint ptrPos(xInc,yInc);
+ TInt ptrNum = 0;
+ TInt prValue = 0;
+ TInt proxValue = 0;
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ }
+
+ // Point to note is that Kernel has an event queue size of 40
+ // So make sure that you don't send more than 40 events
+ switch(iEventSet++)
+ {
+ case 0:
+ // Simulate pointer down/up events for all pointers
+ // Simulate many up events from any pointer which will purge down/up events
+ AddExpectedWsEvent(EEventFocusGained);
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 4); ptrNum++)
+ {
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ }
+ SimulateAndAddLoneUpEvents(KMaxQueueSize, KMaxQueueSize-1, ptrPos);
+ break;
+ case 1:
+ // Repeat the same for Move events
+ // Simulate moves for all pointers with different pressure and proximity value
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ prValue = iPressureStep;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && prValue < iMaxPressure && ptrNum < 4); ptrNum++,prValue+=iPressureStep)
+ {
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ }
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ proxValue = -iProximityStep;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && proxValue > iMaxProximity && ptrNum < 4); ptrNum++,proxValue-=iProximityStep)
+ {
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ }
+ SimulateAndAddLoneUpEvents(KMaxQueueSize, KMaxQueueSize, ptrPos);
+ break;
+ case 2:
+ {
+ // Repeat the same for drag events
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag, 0);
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerFilterDrag, 0);
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 2); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ TPoint interPt = ptrPos;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 2); ptrNum++)
+ {
+ interPt.iX += 2;
+ interPt.iY += 1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ interPt = ptrPos;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 2); ptrNum++)
+ {
+ interPt.iX += 2;
+ interPt.iY += 1;
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+ SimulateAndAddLoneUpEvents(KMaxQueueSize, KMaxQueueSize, ptrPos);
+ }
+ break;
+ case 3:
+ // Repeat the same for lone down events
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 3); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+ SimulateAndAddLoneUpEvents(KMaxQueueSize+1, KMaxQueueSize, ptrPos);
+
+ // Before this we had to send dummy 7 EButton1Up events from 1 to 7 pointers so that iLastUnmatchedDown1
+ // variable to be reset and that consecutive events was not sent to client. But now EPointer3DOutOfRange
+ // resets all the variables.
+ for (ptrNum = 1; (ptrNum < iMaxDevPointers && ptrNum < 3); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointer3DOutOfRange, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ }
+ break;
+ case 4:
+ // Finally for even lone up events, check that when you send events more then the queuesize
+ // the events are not sent back and they are ignored in wserv
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; (ptrNum < iMaxDevPointers && ptrNum < 4); ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (TInt count = 0; count < KMaxQueueSize; count++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ // For all up events more then KMaxQueueSize, wserv igoners then as the queue if full
+ if (count < (KMaxQueueSize - iMaxDevPointers))
+ {
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, 0);
+ }
+ }
+ break;
+ case 5:
+ // Check PurgePointerEvents works with multi pointer events
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ iMultiPtrEventClient->iWs.PurgePointerEvents();
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, 0);
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+ LogEventsAdded();
+ }
+
+void CTMultiPtrEventTest::MultiPointerEvents()
+ {
+ TLogMessageText logText;
+ _LIT(KSet, "MultiPtrEvents SetOfEvents: %d of 9");
+ logText.AppendFormat(KSet, iEventSet);
+ LOG_MESSAGE(logText);
+
+ if (!iEventSet)
+ {
+ SetAutoFlush();
+ }
+ iMultiPtrEventClient->EventBuffer()->SetEventCount(0);
+
+ TPoint ptrPos;
+ TInt ptrNum = 0;
+ TInt prValue = 0;
+ TInt proxValue = 0;
+ TInt xInc = iPhysicalScreenSize.iWidth/iMaxDevPointers;
+ TInt yInc = iPhysicalScreenSize.iHeight/iMaxDevPointers;
+
+ switch(iEventSet++)
+ {
+ case 0:
+ /**
+ @SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0001
+ @SYMPREQ PREQ1226
+ @SYMREQ REQ9674,REQ9687,
+ @SYMTestPriority High
+ @SYMTestCaseDesc Checks Wserv sends multi touch pointer events received by it
+ @SYMTestStatus Implemented
+
+ @SYMTestActions Simulate raw events from different pointers
+ @SYMTestExpectedResults The received events must match the simulated raw events
+ */
+ INFO_PRINTF1(_L("Simulate pointer events from all pointers"));
+ INFO_PRINTF1(_L("Test pattern is PointerDown0/PointerUp0, PointerDown1/PointerUp1, PointerDown2/PointerUp2..."));
+ // Test pattern is down0/up0, down1/up1, down2/up2, down3/up3....
+ AddExpectedWsEvent(EEventFocusGained);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ break;
+ case 1:
+ /**
+ @SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0003
+ @SYMPREQ PREQ1226
+ @SYMREQ REQ9674,REQ9687,
+ @SYMTestPriority High
+ @SYMTestCaseDesc To check Wserv sends simultaneous multi touch pointer events
+ @SYMTestStatus Implemented
+
+ @SYMTestActions Simulate simultaneous raw events from different pointers
+ @SYMTestExpectedResults The received events must match the simulated raw events
+ */
+ INFO_PRINTF1(_L("Test pattern PointerDown0/PointerDown1/PointerDown2/... PointerUp0/PointerUp1/PointerUp2..."));
+ // Test pattern is pointer0Down/pointer1Down/pointer2Down/pointer3Down.... pointer0Up/pointer1Up/pointer2Up/pointer3Up....
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ break;
+ case 2:
+ /**
+ @SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0005
+ @SYMPREQ PREQ1226
+ @SYMREQ REQ9676
+ @SYMTestPriority High
+ @SYMTestCaseDesc To check Wserv sends the multi touch pointer events received
+ by it along with the Pressure or Proximity
+ @SYMTestStatus Implemented
+
+ @SYMTestActions Simulate raw events with pressure and proximity from different pointers
+ @SYMTestExpectedResults The received events must match the simulated raw events
+ */
+ // Simulate Button1Down with differet pressure
+ // Simulate Button1Up with zero pressure
+ INFO_PRINTF1(_L("Simulate pointer events with different pressure values"));
+ ptrPos.SetXY(0,0);
+ prValue = iPressureStep;
+ for (; (prValue <= iMaxPressure && ptrPos.iX < iPhysicalScreenSize.iWidth && ptrPos.iY < iPhysicalScreenSize.iHeight); prValue+=iPressureStep)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, 0);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, 0);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ // Test with max pressure it might be that the width may cross the physical screen size
+ ptrPos.SetXY(0,0);
+ prValue = iMaxPressure;
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, prValue, 0);
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, prValue, 0, 0);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, 0);
+ break;
+ case 3:
+ // Simulate EPointerMove with different pressure values and for differernt pointers
+ INFO_PRINTF1(_L("Simulate pointer events with different pressure values and from different pointers"));
+ ptrPos.SetXY(0,0);
+ prValue = iPressureStep;
+
+ // Enable move events
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+ iMultiPtrEventClient->ChildWin()->BaseWin()->PointerFilter(EPointerFilterMove, 0);
+
+ // Right now when 2 or more moves occur, wserv deletes all the moves except the last one.
+ // So test only one move per Pointer and then one set of button down and button up
+ // Then repeat the same for different pressure values
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, prValue, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ // Test moves with different pressure
+ ptrPos.SetXY(0,0);
+ if ((prValue+iPressureStep) <= iMaxPressure)
+ {
+ prValue += iPressureStep;
+ }
+ ptrNum = 0;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, prValue, 0, ptrNum);
+ break;
+ case 4:
+ INFO_PRINTF1(_L("Simulate pointer events with different proximity values"));
+ // Repeat the same test of case 3 for different proximity values
+ ptrPos.SetXY(0,0);
+
+ proxValue = -iProximityStep;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerDownUp(ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerDownUp(ptrPos, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+
+ ptrPos.SetXY(0,0);
+ if ((proxValue-iProximityStep) > iMaxProximity)
+ {
+ proxValue -= iProximityStep;
+ }
+ ptrNum = 0;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ break;
+ case 5:
+ /**
+ @SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0007
+ @SYMPREQ PREQ1226
+ @SYMREQ REQ9677
+ @SYMTestPriority High
+ @SYMTestCaseDesc To check Wserv sends move/drags of different pointers
+ @SYMTestStatus Implemented
+
+ @SYMTestActions Simulate raw move and drag events from different pointers
+ @SYMTestExpectedResults The received events must match the simulated raw events
+ */
+ INFO_PRINTF1(_L("Simulate pointer drag events"));
+ ptrPos.SetXY(0,0);
+ iMultiPtrEventClient->ParentWin()->BaseWin()->PointerFilter(EPointerFilterDrag, 0);
+
+ // Simulate EButton1Down and then one move and then EButton1Up event
+ // which will lead to corresponding drag, do it for all the pointers
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ TestDragForMultiPointer(ptrPos, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+
+ // Check the drag with different pressure value with different pointer
+ prValue = iPressureStep;
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ if ((prValue+iPressureStep) <= iMaxPressure)
+ {
+ prValue += iPressureStep;
+ }
+ ptrNum = 0;
+ TestDragForMultiPointer(ptrPos, prValue, ptrNum);
+ break;
+ case 6:
+ {
+ /**
+ @SYMTestCaseID GRAPHICS-WSERV-ADVANCEDPOINTER-0009
+ @SYMPREQ PREQ1226
+ @SYMREQ REQ9677, REQ9674
+ @SYMTestPriority High
+ @SYMTestCaseDesc To check Wserv sends simultaneous move/drags of different pointers
+ @SYMTestStatus Implemented
+
+ @SYMTestActions Simulate simulatneous raw move and drag events from different pointers
+ @SYMTestExpectedResults The received events must match the simulated raw events
+ */
+ INFO_PRINTF1(_L("Simulate pointer drag events in different pattern"));
+ // Dragging done in this pattern
+ // pointer0Down/pointer1Down/pointer2Down/pointer3Down... pointer0Up/pointer1Up/pointer2Up/pointer3Up....
+
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+
+ ptrPos.SetXY(0,0);
+ TPoint interPt = ptrPos;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ interPt.iX += 2;
+ interPt.iY += 1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+
+ ptrPos.SetXY(0,0);
+ interPt = ptrPos;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers; ptrNum++)
+ {
+ interPt.iX += 2;
+ interPt.iY += 1;
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+ break;
+ }
+ case 7:
+ {
+ // Mixing of drag and moves of different pointers
+ ptrPos.SetXY(0,0);
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ }
+ ptrPos.SetXY(0,0);
+ TPoint interPt = ptrPos;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ interPt.iX += 2;
+ interPt.iY += 1;
+ SimulatePointerEvent(TRawEvent::EPointerMove, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+
+ ptrPos.SetXY(0,0);
+ interPt = ptrPos;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ interPt.iX += 2;
+ interPt.iY += 1;
+ SimulatePointerEvent(TRawEvent::EButton1Up, interPt.iX, interPt.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, interPt, 0, 0, ptrNum);
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ interPt = ptrPos;
+ }
+
+ ptrPos.SetXY(0,0);
+ prValue = iPressureStep;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2 && prValue < iMaxPressure; ptrNum++, prValue+=iPressureStep)
+ {
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, prValue, 0, ptrNum);
+ ptrPos.iX += xInc;
+ ptrPos.iY += yInc;
+ }
+ }
+ break;
+ case 8:
+ {
+ INFO_PRINTF1(_L("Check intermediate Moves and Drags are deleted except last event"));
+ // Check if intermediate move and drag events are deleted
+ // The deletion is done with respect to same pointer and same window
+ xInc = iPhysicalScreenSize.iWidth/KMaxQueueSize;
+ yInc = iPhysicalScreenSize.iHeight/KMaxQueueSize;
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ TInt count = 0;
+
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ // Make sure that ptrPos does not go out of screen area, i,e the loop count should not exceed 4
+ for (count = proxValue = 0; proxValue > iMaxProximity && count < 4; proxValue=proxValue-(4*iProximityStep), count++)
+ {
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, proxValue, ptrNum);
+ }
+ // Since the for loop increments the variables at the end
+ proxValue = proxValue + (4*iProximityStep);
+ AddExpectedPointerEvent(TPointerEvent::EMove, ptrPos, proxValue, 0, ptrNum);
+ }
+
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ SimulatePointerEvent(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Down, ptrPos, 0, 0, ptrNum);
+ }
+
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ // Make sure that ptrPos does not go out of screen area, i,e the loop count shuld not exceed 4
+ for (count = prValue = 0; prValue < iMaxPressure && count < 4; prValue=prValue+(4*iPressureStep), count++)
+ {
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ SimulatePointerEvent(TRawEvent::EPointerMove, ptrPos.iX, ptrPos.iY, prValue, ptrNum);
+ }
+ prValue = prValue-(4*iPressureStep);
+ AddExpectedPointerEvent(TPointerEvent::EDrag, ptrPos, prValue, 0, ptrNum);
+ }
+
+ ptrPos.iX = xInc;
+ ptrPos.iY = yInc;
+ for (ptrNum = 0; ptrNum < iMaxDevPointers/2; ptrNum++)
+ {
+ ptrPos.iX += xInc/2;
+ ptrPos.iY += yInc/2;
+ SimulatePointerEvent(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, 0, ptrNum);
+ AddExpectedPointerEvent(TPointerEvent::EButton1Up, ptrPos, 0, 0, ptrNum);
+ }
+ }
+ break;
+ default:
+ ResetFlushStopAS();
+ break;
+ }
+
+ LogEventsAdded();
+ }
+
+// Logs number of events added to test buffer for comaparison
+void CTMultiPtrEventTest::LogEventsAdded()
+ {
+ TLogMessageText logText1;
+ _LIT(KEventsAdded, "Events added to buffer = %d");
+ logText1.AppendFormat(KEventsAdded, iMultiPtrEventClient->EventBuffer()->EventsRemaining());
+ LOG_MESSAGE(logText1);
+ }
+
+// If any of the Tests fails, bring the wserv in a consistent state for other test to run,
+// stop ActiveScheduler and display some logs where the fail occured.
+void CTMultiPtrEventTest::Failed()
+ {
+ switch (iTest->iState)
+ {
+ case 2: // Anim tests
+ DestroyAnimDllAndAnim();
+ break;
+ case 3: // MultiClient tests
+ if (iMultiPtrEventClient->EventBuffer()->NestedLoopState())
+ {
+ iSecMultiPtrEventClient->EventBuffer()->SetNestedLoopState(EFalse);
+ CActiveScheduler::Stop();
+ }
+ break;
+ case 4: //PtrClick tests
+ if (iPtrPluginLoaded)
+ {
+ iPtrPluginLoaded = EFalse;
+ iClick.Unload();
+ iClick.Close();
+ }
+ if (iHeap)
+ {
+ iHeap->Close();
+ iHeap = NULL;
+ iChunk.Close();
+ }
+ break;
+ case 5: //Screen mode tests
+ SetDefaultScreenMode();
+ break;
+ case 11:
+ iMultiPtrEventClient->DeleteGroupBlankWin();
+ break;
+ case 12: //Emulation tests, iEventSet is incremented in main switch case.
+ switch (iEventSet)
+ {
+ case 9:
+ DeleteGroupWin();
+ break;
+ case 10:
+ DestroyAnimDllAndAnim();
+ break;
+ case 11:
+ case 12:
+ iMultiPtrEventClient->ParentWin()->BaseWin()->FreePointerMoveBuffer();
+ iMultiPtrEventClient->ParentWin()->BaseWin()->DisablePointerMoveBuffer();
+ break;
+ case 14:
+ case 15:
+ iMultiPtrEventClient->iWs.SetPointerCursorArea(iOrigPtrCursorArea);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 15:
+ if (iEventSet > 1)
+ {
+ DeleteGroupWinForCapturing();
+ }
+ break;
+ case 13:
+ case 16:
+ SetThresholdValues(KMaxTInt, KMinTInt, KMaxTInt, KMinTInt);
+ break;
+ default:
+ break;
+ }
+
+ if (iActiveSchedulerStarted)
+ {
+ iActiveSchedulerStarted = EFalse;
+ CActiveScheduler::Stop();
+ }
+
+ // Display the test case number, subtest case number and number of events left in the buffer which can be used to
+ // find out which event actually caused the failure when any test fails
+ TLogMessageText logText1;
+ _LIT(KEventsAdded, "Test case number %d Sub test case number %d Events remaining in the buffer %d \n");
+ logText1.AppendFormat(KEventsAdded, iTest->iState, iEventSet, iMultiPtrEventClient->EventBuffer()->EventsRemaining());
+ LOG_MESSAGE(logText1);
+ RDebug::Printf("Test case number %d Sub test case number %d Events remaining in the buffer %d \n", iTest->iState, iEventSet, iMultiPtrEventClient->EventBuffer()->EventsRemaining());
+
+ iFailed=ETrue;
+ }
+
+// This function is called by TestExecute Framework, through which all the testcases are run
+void CTMultiPtrEventTest::RunTestCaseL(TInt /*aCurTestCase*/)
+ {
+ _LIT(KTest0, "MultiPointerEvents with Pressure and Proximity");
+ _LIT(KTest1, "Purging Of MultiPointerEvents");
+ _LIT(KTest2, "MultiPointerEvents for Anims");
+ _LIT(KTest3, "MultiPointerEvents from multi client");
+ _LIT(KTest4, "MultiPointerEvents for pointer click plugin");
+ _LIT(KTest5, "MultiPointerEvents In Different ScreenModes");
+ _LIT(KTest6, "Filtering Of MultiPointerEvents");
+ _LIT(KTest7, "Grabbing Of MultiPointerEvents");
+ _LIT(KTest8, "VirtualKeyboard for Multiple Pointers");
+ _LIT(KTest9, "DoubleClick events for Multiple Pointer");
+ _LIT(KTest10, "OutOfRange & EnterExit for Multiple Pointer");
+ _LIT(KTest11, "Auto foreground for Multiple Pointer");
+ _LIT(KTest12, "Emulation rules for Mulitple Pointers");
+ _LIT(KTest13, "Close proximity and High Pressure events");
+ _LIT(KTest14, "Out of bound value testing");
+ _LIT(KTest15, "Capturing Of MultiPointerEvents");
+ _LIT(KTest16, "Negative testing for Proximity and Pressure events");
+ _LIT(KTest17, "PointerRepeatEvent for Multiple Pointers");
+
+ if (!TestBase()->ConfigurationSupportsPointerEventTesting())
+ {
+ INFO_PRINTF1(_L("Test skipped because config does not support pointer event testing"));
+ TestComplete();
+ return;
+ }
+
+ switch(iTest->iState)
+ {
+ case 0:
+ iTest->LogSubTest(KTest0);
+ RunTestsL();
+ break;
+ case 1:
+ iTest->LogSubTest(KTest1);
+ RunTestsL();
+ break;
+ case 2:
+ iTest->LogSubTest(KTest2);
+ RunTestsL();
+ break;
+ case 3:
+ iTest->LogSubTest(KTest3);
+ RunTestsL();
+ break;
+ case 4:
+ iTest->LogSubTest(KTest4);
+ RunTestsL();
+ break;
+ case 5:
+ iTest->LogSubTest(KTest5);
+ RunTestsL();
+ break;
+ case 6:
+ iTest->LogSubTest(KTest6);
+ RunTestsL();
+ break;
+ case 7:
+ iTest->LogSubTest(KTest7);
+ RunTestsL();
+ break;
+ case 8:
+ iTest->LogSubTest(KTest8);
+ RunTestsL();
+ break;
+ case 9:
+ iTest->LogSubTest(KTest9);
+ RunTestsL();
+ break;
+ case 10:
+ iTest->LogSubTest(KTest10);
+ RunTestsL();
+ break;
+ case 11:
+ iTest->LogSubTest(KTest11);
+ RunTestsL();
+ break;
+ case 12:
+ iTest->LogSubTest(KTest12);
+ RunTestsL();
+ break;
+ case 13:
+ iTest->LogSubTest(KTest13);
+ RunTestsL();
+ break;
+ case 14:
+ iTest->LogSubTest(KTest14);
+ RunTestsL();
+ break;
+ case 15:
+ iTest->LogSubTest(KTest15);
+ RunTestsL();
+ break;
+ case 16:
+ iTest->LogSubTest(KTest16);
+ RunTestsL();
+ break;
+ case 17:
+ iTest->LogSubTest(KTest17);
+ RunTestsL();
+ break;
+ case 18:
+ // Keep this code in last case statement for main test completion
+ TestComplete();
+ break;
+ default:
+ AutoPanic(EAutoPanicWrongTest);
+ }
+
+ //
+ if (iFailed)
+ {
+ TEST(EFalse);
+ iFailed=EFalse;
+ }
+ ++iTest->iState;
+ }
+
+// Macro which is used for construction of CTMultiPtrEventTestStep object
+// and also used to call CreateTestL() which creates CTMultiPtrEventTest and CTestBase objects
+__WS_CONSTRUCT_STEP__(MultiPtrEventTest)