webengine/webkitutils/stmgesturefw/src/statemachine.cpp
changeset 28 d39add9822e2
child 46 30342f40acbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/webkitutils/stmgesturefw/src/statemachine.cpp	Tue Feb 02 00:56:45 2010 +0200
@@ -0,0 +1,789 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:   
+*
+*/
+
+#include <coemain.h>
+#include <aknutils.h>
+#include <aknappui.h>
+
+#include "statemachine.h"
+#include "stateengine.h"
+#include "rt_uievent.h"
+#include "callbacktimer.h"
+#include "stateengineconfiguration.h"
+
+#include "filelogger.h"
+#include "utils.h"
+
+using namespace stmUiEventEngine ;
+
+GLREF_D const char* stateNames[8] ;
+
+const char* const ttypeNames[] = {  // for debugging purposes define the names of the pointer events
+            "EButton1Down         ",
+            "EButton1Up           ",
+            "EButton2Down         ",
+            "EButton2Up           ",
+            "EButton3Down         ",
+            "EButton3Up           ",
+            "EDrag                ",
+            "EMove                ",
+            "EButtonRepeat        ",
+            "ESwitchOn            ",
+            "EOutOfRange          ",
+            "EEnterCloseProximity ",
+            "EExitCloseProximity  ",
+            "EEnterHighPressure   ",
+            "EExitHighPressure    "
+            };
+
+/// Fast integer distance
+int stmUiEventEngine::Distance(int x, int y)
+{
+/*
+    double d = dx * dx + dy * dy;
+    double dist ;
+    Math::Sqrt(dist, d) ;
+    return dist;
+*/
+    if(x<0) x=-x;
+    if(y<0) y=-y;
+    if(x < y)
+    {
+      int t = x;
+      x = y;
+      y = t;        // ensures that x >= y
+    }
+    int dist = (y < ((13107 * x)>>15)) ?    // * (.4)
+              (x + ((y * 6310)>>15)) :      // * (.192582403)
+              (((x * 27926)>>15)            // * (.852245894)
+                 + ((y * 18414)>>15));      // * (.561967668)
+    return dist;
+}
+
+
+/*!
+  CStateMachine implements the state machine and the integration fo the
+  state machine to the OS.  The CStateEngine handles the actual processing of the
+  finite state machine but CStateMachine provides the OS specific things like timers
+  and message conversion.
+
+  The CStateMachine implements the MAknWsEventObserver interface so it adds
+  itself to be the observer to the event monitor of the application UI.
+
+  It handles the pointer events either by using the monitoring interface or
+  lets the application call the HandlePointerEventL method.
+
+  If MAknWsEventObserver interface is used then all the events passed to the
+  application are seen.  The target of the gesture starting event is stored
+  so that the generated UI event contains the target as a void pointer. (should it just be CoeControl*?)
+
+  There is possibility to adjust the Y coordinate of the touch point.
+  In capacitive touch (Alvin) it seems that the perceived touch point is
+  below the middle part of the fingertip.  The user however tries to use the
+  finger to point so that the touch point should correspond to the tip of the finger.
+  It seems that this illusion can be achieved by adjusting the Y position about 3 mm up.
+  However, this adjustment can properly be done only when the touch point is far enough
+  from the window borders up or down.  When close to top or bottom of window, the adjustment
+  makes it impossible touch points near the edge, unless adjustment depends on the distance from
+  window border.
+  So in practice it should be the window server doing the adjustment, and after adjustment
+  deciding the target window.  At application level the adjustment can only be done properly
+  if window borders do not need to be crossed.
+
+ */
+CStateMachine::CStateMachine()
+{
+    m_WasMessageFiltered = false ;
+    m_wseventmonitoringenabled = false ; // NB: enabled only if really used by application
+    m_loggingenabled = false ;
+    m_capacitiveup = false ;
+    m_adjustYposition = false ;
+}
+/*!Destructor
+ */
+CStateMachine::~CStateMachine()
+{
+    for (int i = 0; i < KMaxNumberOfPointers; i++)
+    {
+        delete m_holdTimer[i] ;
+        delete m_touchTimer[i] ;
+        delete m_suppressTimer[i] ;
+        delete m_impl[i] ;
+    }
+    delete m_config ;
+}
+
+CStateMachine* CStateMachine::NewLC()
+{
+    CStateMachine* self = new (ELeave) CStateMachine();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+}
+
+CStateMachine* CStateMachine::NewL()
+{
+    CStateMachine* self = CStateMachine::NewLC();
+    CleanupStack::Pop(self); 
+    return self;
+}
+/*!
+ Construct the actual state machine implemented in CStateEngine and
+ creates the timers.  It also adds itself to the observer list of
+ CAknWsEventMonitor of the application.
+
+ */
+void CStateMachine::ConstructL()
+{
+    m_config = new(ELeave)CStateEngineConfiguration() ;
+    m_config->ConstructL();
+
+    for (int i = 0; i < KMaxNumberOfPointers; i++)
+    {
+        m_impl[i] = new(ELeave) CStateEngine(m_config, this, i) ;
+        m_holdTimer[i] = CCallbackTimer::NewL(*this, handleholdTimer, 0, i, ETrue);
+        m_touchTimer[i] = CCallbackTimer::NewL(*this, handletouchTimer, 0, i, ETrue);
+        m_suppressTimer[i] = CCallbackTimer::NewL(*this, handlesuppressTimer, 0, i, ETrue);
+    }
+
+    m_coeEnv = CCoeEnv::Static();
+
+    /* IMEX: monitor added only if enabled
+      add us to see the WsEvents so that we are able to interpret them;
+
+    CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ;
+    pui->EventMonitor()->AddObserverL(this) ;
+    pui->EventMonitor()->Enable(ETrue) ;
+    */
+
+    m_3mminpixels = Mm2Pixels(1.5) ;
+}
+/*!
+ * Process one pointer event in the state machine.
+ * \return true, if the event did not generate a UI event immediately.
+ */
+bool CStateMachine::HandleStateEvent(const TPointerEvent& aPointerEvent, 
+                                     void* aTarget, 
+                                     const TTime& aTime)
+{
+    TInt index = PointerIndex(aPointerEvent);
+    CStateEngine* engine = m_impl[index];
+    CreateHwEvent(engine->initEvent(), aPointerEvent, aTarget, aTime) ;
+    if (m_loggingenabled)
+    {
+        LOGARG("HandleStateEvent: ptr %d", index) ;
+    }
+    m_WasMessageFiltered = engine->handleStateEvent() ;
+    return m_WasMessageFiltered ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+bool CStateMachine::wasLastMessageFiltered(TInt aPointerNumber)
+{
+    return m_impl[aPointerNumber]->wasLastMessageFiltered() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+TRect CStateMachine::getTouchArea(TInt aPointerNumber)
+{
+    return m_impl[aPointerNumber]->getTouchArea() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setTouchTimeArea(long fingersize_mm)
+{
+    m_config->setTouchTimeArea(fingersize_mm) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setTouchArea(long fingersize_mm)
+{
+    m_config->setTouchArea(fingersize_mm) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+TAreaShape CStateMachine::getTouchAreaShape()
+{
+    return m_config->getTouchAreaShape() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setTouchAreaShape(const TAreaShape aShape)
+{
+    m_config->setTouchAreaShape(aShape) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+unsigned int CStateMachine::getTouchTimeout()
+{
+    return m_config->getTouchTimeout() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setTouchTimeout(unsigned int aDelay)
+{
+    m_config->setTouchTimeout(aDelay) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+TRect CStateMachine::getHoldArea(TInt aPointerNumber)
+{
+    return m_impl[aPointerNumber]->getHoldArea() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setHoldArea(long fingersize_mm)
+{
+    m_config->setHoldArea(fingersize_mm) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+TAreaShape CStateMachine::getHoldAreaShape()
+{
+    return m_config->getHoldAreaShape() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setHoldAreaShape(const TAreaShape aShape)
+{
+    m_config->setHoldAreaShape(aShape) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+unsigned int CStateMachine::getHoldTimeout()
+{
+    return m_config->getHoldTimeout() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setHoldTimeout(unsigned int a)
+{
+    m_config->setHoldTimeout(a) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+unsigned int CStateMachine::getTouchSuppressTimeout()
+{
+    return m_config->getTouchSuppressTimeout() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setTouchSuppressTimeout(unsigned int a)
+{
+    m_config->setTouchSuppressTimeout(a) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+unsigned int CStateMachine::getMoveSuppressTimeout()
+{
+    return m_config->getMoveSuppressTimeout() ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::setMoveSuppressTimeout(unsigned int a)
+{
+    m_config->setMoveSuppressTimeout(a) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+bool CStateMachine::addUiEventObserver(MUiEventObserver* observer)
+{
+    return m_config->addUiEventObserver(observer) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+bool CStateMachine::removeUiEventObserver(MUiEventObserver* observer)
+{
+    return m_config->removeUiEventObserver(observer) ;
+}
+/*!
+ * wrapper method for the actual implementation in the CStateEngine.
+ */
+void CStateMachine::enableLogging(bool aEnable)
+{
+    m_loggingenabled = aEnable ;
+    m_config->enableLogging(aEnable) ;
+}
+
+TInt CStateMachine::PointerIndex(const TPointerEvent& aPointerEvent)
+{
+    TInt index = 0;
+#if defined(ADVANCED_POINTER_EVENTS)
+    if (aPointerEvent.IsAdvancedPointerEvent())
+    {
+        const TAdvancedPointerEvent* tadvp = aPointerEvent.AdvancedPointerEvent() ;
+        index = tadvp->PointerNumber() ;
+    }
+#endif
+    return index;
+}
+
+/*!
+ * Convert pointer event (TPointerEvent) into THwEvent into the variable m_hwe.
+ * THwEvent contains the position and simplified event type
+ * but also has the target window and timestamp included.
+ */
+void CStateMachine::CreateHwEvent(THwEvent& aEvent, 
+                                  const TPointerEvent& aPointerEvent, 
+                                  void* aTarget, 
+                                  const TTime& aTime)
+{
+/*  should be set by this moment by CStateEngine with that index in CStateEngine::initEvent()
+    aEvent.iPointerNumber = PointerIndex(aPointerEvent);
+*/
+    aEvent.iTarget = aTarget ;
+    aEvent.iTime = aTime;
+    // Change to screen coordinates here while the window is still existing....
+    aEvent.iPosition = screenCoordinates(aPointerEvent.iPosition, aTarget) ;
+    switch (aPointerEvent.iType)
+    {
+    case TPointerEvent::EButton1Down:
+    case TPointerEvent::EButton2Down:
+    case TPointerEvent::EButton3Down:
+    {
+        aEvent.iType = stmUiEventEngine::EDown ;
+        break ;
+    }
+    case TPointerEvent::EButton1Up:
+    case TPointerEvent::EButton2Up:
+    case TPointerEvent::EButton3Up:
+    {
+        if (m_capacitiveup)
+        {
+            aEvent.iType = stmUiEventEngine::ECapacitiveUP ;   // How could this be checked automagically?
+        }
+        else
+        {
+            aEvent.iType = stmUiEventEngine::EResistiveUP ;    // How could this be checked automagically?
+        }
+
+        break ;
+    }
+    case TPointerEvent::EDrag:
+    {
+        aEvent.iType = stmUiEventEngine::EDrag ;
+        break ;
+    }
+    }
+}
+////////////////////////////////////////////////////////////////////////////////////////////
+/*!
+ * Start the hold timer if it is not already active.
+ */
+void CStateMachine::startholdTimer(TInt aPointerNumber)
+{
+    if (!m_holdTimer[aPointerNumber]->IsActive())
+    {
+        m_holdTimer[aPointerNumber]->Start();
+    }
+}
+
+/*!
+ * The hold timer expiration: create a timer event and call the state machine
+ */
+void CStateMachine::handleholdTimer(TInt aPointerNumber)
+{
+    // We get an event, lets kick the state machine
+    CStateEngine* engine = m_impl[aPointerNumber];
+    CreateTimerEvent(engine->initEvent(), stmUiEventEngine::EHoldTimer) ;
+    engine->handleStateEvent() ;
+}
+/*!
+ * Stop the hold timer
+ */
+void CStateMachine::cancelholdTimer(TInt aPointerNumber)
+{
+    m_holdTimer[aPointerNumber]->Cancel();
+}
+/*!
+ * Start suppress timer.  The timeout has been set beforehand.
+ */
+void CStateMachine::startsuppressTimer(TInt aPointerNumber)
+{
+    m_suppressTimer[aPointerNumber]->Start();
+}
+/*!
+ * The suppress timer expiration, create a timer event and call the state machine.
+ */
+void CStateMachine::handlesuppressTimer(TInt aPointerNumber)
+{
+    // We get an event, lets kick the state machine
+    CStateEngine* engine = m_impl[aPointerNumber];
+    CreateTimerEvent(engine->initEvent(), stmUiEventEngine::ESuppressTimer) ;
+    engine->handleStateEvent() ;
+}
+/*!
+ * stop the suppress timer
+ */
+void CStateMachine::cancelsuppressTimer(TInt aPointerNumber)
+{
+    m_suppressTimer[aPointerNumber]->Cancel();
+}
+/*!
+ * start the touch timer if it is not already active.
+ */
+void CStateMachine::starttouchTimer(TInt aPointerNumber)
+{
+    if (!m_touchTimer[aPointerNumber]->IsActive())
+    {
+        m_touchTimer[aPointerNumber]->Start();
+    }
+}
+
+/*!
+ * The touch timer expiration, create timer event and call the state machine.
+ */
+void CStateMachine::handletouchTimer(TInt aPointerNumber)
+{
+    // We get an event, lets kick the state machine
+    CStateEngine* engine = m_impl[aPointerNumber];
+    CreateTimerEvent(engine->initEvent(), stmUiEventEngine::ETouchTimer) ;
+    engine->handleStateEvent() ;
+}
+/*!
+ * stop the touch timer
+ */
+void CStateMachine::canceltouchTimer(TInt aPointerNumber)
+{
+    if (m_touchTimer[aPointerNumber]->IsActive()) // we were waiting for additional events
+    {
+        m_touchTimer[aPointerNumber]->Cancel();
+    }
+}
+/*!
+ * CreateTimerEvent creates a timer event to the m_hwe variable.
+ */
+void CStateMachine::CreateTimerEvent(THwEvent& aEvent, TStateMachineEvent aEventCode)
+{
+    aEvent.iType = aEventCode ;
+    // m_hwe.iPosition = TPos(0, 0) ;      should we just leave the previous pos
+    TTime now ;
+    now.HomeTime() ;
+    aEvent.iTime = now ;
+}
+/*!
+ * Events are processed either using the MAknWsEventObserver interface
+ * or letting the view/container pass the pointer events to the state machine.
+ * The member variable m_wseventmonitoringenabled defines which method is used.
+ * If handlePoingterEventL is called, the calling CCoeCOntrol must provide itself
+ * as the target.
+ */
+void CStateMachine::HandlePointerEventL(const TPointerEvent& aPointerEvent, void *target)
+{
+    if (m_wseventmonitoringenabled) return ;    // events are handled in the event monitor
+    if (m_loggingenabled)
+    {
+#if defined(ADVANCED_POINTER_EVENTS)
+        TInt pointerNumber = PointerIndex(aPointerEvent) ;
+        LOGARG("Pointer %d event %s at (%d %d)", pointerNumber,
+                ttypeNames[aPointerEvent.iType], aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY) ;
+#else
+        LOGARG("Pointer event %s at (%d %d)",
+                ttypeNames[aPointerEvent.iType], aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY) ;
+#endif
+    }
+    TTime time = m_coeEnv->LastEvent().Time();
+    HandleStateEvent(aPointerEvent, target, time) ;   // target needs to be there to convert from window to screen coordinates
+}
+/**
+ * One possibility to implement gesture recognition is to intercept the events
+ * using the event monitoring interface.  The HandleWsEventL method will get all events
+ * passed to the application.  The aDestination parameter defines the window where the event
+ * was targeted to.  The gesture recognition should use the target information
+ * to determine how the gesture should be interpreted.
+ * In the current implementation the aDestination needs to be one of the UI event observers
+ * in order to process the message, but later when gesture recognition is added, this check
+ * needs to be removed and the gesture recognition should handle the target of the gesture.
+ */
+void CStateMachine::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
+{
+    // Check which processing type we have for events.
+    // If WsEvent monitoring, then process the message, otherwise return
+    if (!m_wseventmonitoringenabled) return ;
+
+    // Log the events passing trough to see what kind of stuff there goes...
+    // and could the gesture recogniser grab them from here?
+    TInt type=aEvent.Type();
+    switch (type)
+        {
+    case EEventKey:
+    case EEventKeyUp:
+    case EEventKeyDown:
+    {
+        if (m_loggingenabled)
+        {
+            TKeyEvent* tke = aEvent.Key() ;
+            LOGARG("Key event %d %d to %u", tke->iCode, tke->iScanCode, aDestination) ;
+        }
+        break;
+    }
+    case EEventPointer:
+    {
+        TPointerEvent* tpe = aEvent.Pointer() ;
+        if (m_loggingenabled)
+        {
+            TRect rcd = aDestination->Rect() ;
+            TPoint org = aDestination->PositionRelativeToScreen() ;
+            TRect rcd2 = rcd ;
+            rcd2.Move(org) ;
+            TPoint screenpos = tpe->iPosition ;
+            screenpos += org ;
+
+#if defined(ADVANCED_POINTER_EVENTS)
+            TInt pointerNumber = PointerIndex(*tpe) ;
+            LOGARG("Pointer %d event %s at (%d %d)[%d,%d] to 0x%x ((%d,%d)(%d,%d)): screen: ((%d,%d)(%d,%d))",
+                    pointerNumber,
+                    ttypeNames[tpe->iType],
+                    tpe->iPosition.iX, tpe->iPosition.iY,
+                    screenpos.iX, screenpos.iY,
+                    aDestination,
+                rcd.iTl.iX, rcd.iTl.iY, rcd.iBr.iX, rcd.iBr.iY,
+                rcd2.iTl.iX, rcd2.iTl.iY, rcd2.iBr.iX, rcd2.iBr.iY) ;
+#else
+            LOGARG("Pointer event %s at (%d %d)[%d,%d] to 0x%x ((%d,%d)(%d,%d)): screen: ((%d,%d)(%d,%d))",
+                    ttypeNames[tpe->iType], tpe->iPosition.iX, tpe->iPosition.iY,
+                    screenpos.iX, screenpos.iY,
+                    aDestination,
+                rcd.iTl.iX, rcd.iTl.iY, rcd.iBr.iX, rcd.iBr.iY,
+                rcd2.iTl.iX, rcd2.iTl.iY, rcd2.iBr.iX, rcd2.iBr.iY) ;
+#endif
+        }
+        HandleStateEvent(*tpe, aDestination, aEvent.Time()) ;
+        break;
+    }
+    case EEventPointerBufferReady:
+        if (m_loggingenabled)
+        {
+            LOGARG("Pointer buffer ready event to %u", aDestination) ;
+        }
+        break;
+    case EEventFocusLost:
+    case EEventFocusGained:
+        if (m_loggingenabled)
+        {
+            LOGARG("Focus message event to %u", aDestination) ;
+        }
+        break;
+    case EEventSwitchOn:
+        if (m_loggingenabled)
+        {
+            LOGARG("Switch On event to %u", aDestination) ;
+        }
+        break;
+    case EEventUser:
+        if (m_loggingenabled)
+        {
+            LOGARG("User event to %u", aDestination) ;
+        }
+        break;
+    case EEventPowerMgmt:
+        if (m_loggingenabled)
+        {
+            LOGARG("Power Mgmnt event to %u", aDestination) ;
+        }
+        break;
+    case EEventMessageReady:
+        if (m_loggingenabled)
+        {
+            LOGARG("Message Ready event to %u", aDestination) ;
+        }
+        break;
+    case EEventScreenDeviceChanged:
+        if (m_loggingenabled)
+        {
+            LOGARG("Screen device changed event to %u", aDestination) ;
+        }
+        break;
+
+    default:
+        if (m_loggingenabled)
+        {
+            LOGARG("default changed event %d to %u", type, aDestination) ;
+        }
+        break;
+    }
+}
+/*!
+ * Start the touch timer using a specified delay
+ */
+void CStateMachine::startTouchTimer(TInt aDelay, TInt aPointerNumber)
+{
+    m_touchTimer[aPointerNumber]->SetDelay(aDelay) ;
+    starttouchTimer(aPointerNumber) ;
+}
+/*!
+ *  Stop the touch timer.
+ */
+void CStateMachine::cancelTouchTimer(TInt aPointerNumber)
+{
+    canceltouchTimer(aPointerNumber) ;
+}
+/*!
+ * Start hold timer using specified delay
+ */
+void CStateMachine::startHoldTimer(TInt aDelay, TInt aPointerNumber)
+{
+    m_holdTimer[aPointerNumber]->SetDelay(aDelay) ;
+    startholdTimer(aPointerNumber) ;
+}
+/*!
+ * Stop the hold timer
+ */
+void CStateMachine::cancelHoldTimer(TInt aPointerNumber)
+{
+    cancelholdTimer(aPointerNumber) ;
+}
+/*!
+ * Start suppress timer using specified delay.
+ */
+void CStateMachine::startSuppressTimer(TInt aDelay, TInt aPointerNumber)
+{
+    m_suppressTimer[aPointerNumber]->SetDelay(aDelay) ;
+    startsuppressTimer(aPointerNumber) ;
+}
+/*!
+ *  Stop the suppress timer.
+ */
+void CStateMachine::cancelSuppressTimer(TInt aPointerNumber)
+{
+    cancelsuppressTimer(aPointerNumber) ;
+}
+
+/*!
+ * Method sets the m_wseventmonitoringenabled.  If it is true,
+ * then the state machine will be called from the HandleWsEventL method which
+ * sees all the events passed to the application.
+ *
+ * Otherwise the HandlePointerEventL method call will cause the call to
+ * state machine so the view/container needs to pass the pointer events to the state machine
+ * in its own HandlePointerEventL -method.
+ *
+ */
+void CStateMachine::EnableWsEventMonitoring(bool aEnable)
+{
+    if( !m_wseventmonitoringenabled && aEnable )
+    {
+        CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ;
+        TRAPD(err, pui->EventMonitor()->AddObserverL(this)) ;
+        if(!err)
+            pui->EventMonitor()->Enable(ETrue) ;
+    }
+    else if( m_wseventmonitoringenabled && !aEnable )
+    {
+        CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ;
+        pui->EventMonitor()->RemoveObserver(this) ;
+        // Should not disable since it may be not the only user
+        //pui->EventMonitor()->Enable(EFalse) ;
+    }
+
+    m_wseventmonitoringenabled = aEnable ;
+}
+TPoint CStateMachine::screenCoordinates(const TPoint& aPos, void* aGestureTarget)
+{
+    TPoint newPos = aPos ;
+    if (aGestureTarget)
+    {
+       CCoeControl* pcc = (CCoeControl*) aGestureTarget ;
+       TPoint tp(TPoint(0,0));
+        if (m_adjustYposition)
+        {
+            TSize sz = pcc->Size() ;
+
+            // If we are running in capacitive touch device,
+            // adjust the point up about 3 mm unless we are
+            // near top or bottom of the window
+
+            // Y position in the window
+            int wY = newPos.iY - tp.iY;
+            int edge = 2*m_3mminpixels;
+
+            if (Rng(0, wY, edge - 1))
+            {
+                // close to the top we adjust suitably so that immediately at the top adjust is 0
+                int adjust = wY / 2 ;
+                newPos.iY -= adjust ;
+                if (m_loggingenabled)
+                {
+                    LOGARG("adjustment: nY %d tY %d [3mm: %d  adj: %d]", 
+                            newPos.iY, tp.iY, m_3mminpixels, adjust) ;
+                }
+
+            }
+            else if (Rng(edge, wY, sz.iHeight - edge))
+            {
+                int from = newPos.iY ;
+                newPos.iY -= m_3mminpixels ;
+                if (m_loggingenabled)
+                {
+                    LOGARG("adjustment: %d to %d [3mm: %d  middle]", 
+                            from, newPos.iY, m_3mminpixels) ;
+                }
+
+            }
+            else
+            {
+                // similarly at the bottom we adjust less the closer we get to the edge
+                int adjust = (sz.iHeight - wY) / 2 ;
+                newPos.iY -= adjust ;
+                if (m_loggingenabled)
+                {
+                    LOGARG("adjustment: nY %d tY %d  sH %d [3mm: %d  adj: %d]",
+                            newPos.iY, tp.iY, sz.iHeight, m_3mminpixels, adjust) ;
+                }
+
+            }
+        }
+        else
+        {
+            // if the target does not own a window how can we adjust to the screen?
+        }
+    }
+    return newPos ;
+}
+void CStateMachine::enableCapacitiveUp(bool aEnable)
+{
+    m_capacitiveup = aEnable ;
+}
+void CStateMachine::enableYadjustment(bool aEnable)
+{
+    m_adjustYposition = aEnable ;
+}
+int CStateMachine::getNumberOfPointers()
+{
+    return KMaxNumberOfPointers ;
+}
+