qstmgesturelib/qstmgestureapi.cpp
author hgs
Fri, 15 Oct 2010 17:30:59 -0400
changeset 16 3c88a81ff781
parent 3 0954f5dd2cd0
permissions -rw-r--r--
201041

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, 
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* Description:
*  Gesture UI Engine
*/


// Gesture Library: Framework
#include <qstmgestureengine.h>
#include <qstmstatemachine.h>
// Gesture Library: Recognizers
#include <qstmtapgesturerecogniser.h>
#include <qstmpangesturerecogniser.h>
#include <qstmhoveringgesturerecogniser.h>
#include <qstmedgescrollgesturerecogniser.h>
#include <qstmlongpressgesturerecogniser.h>
#include <qstmpinchgesturerecogniser.h>
#include <qstmtouchgesturerecogniser.h>
#include <qstmreleasegesturerecogniser.h>
#include <qstmleftrightgesturerecogniser.h>
#include <qstmupdowngesturerecogniser.h>
#include <qstmflickgesturerecogniser.h>
#include <qstmunknowngesturerecogniser.h>
#include <qstmzoomgesturerecogniser.h>
#include <qstmmaybetapgesturerecogniser.h>

#include <qstmgestureapi.h>
#include <qstmgestureevent.h>
#include <QtGui>

using namespace qstmGesture;
using namespace qstmUiEventEngine;

QStm_GestureParameters::QStm_GestureParameters()
{
}

QStm_GestureParameters::QStm_GestureParameters(const QStm_GestureParameters& params )
{
    memcpy(&m_param[0], &params.m_param[0], sizeof(m_param));
    memcpy(&m_areaSettings[0], &params.m_areaSettings[0], sizeof(m_areaSettings));
    memcpy(&m_enabled[0], &params.m_enabled[0], sizeof(m_enabled));
}


QStm_GestureEngineApi::QStm_GestureEngineApi() : m_gestureEngine(0), m_statemachine(0), m_config(0)
{
	init();
}

void QStm_GestureEngineApi::init()
{
    //m_gf = new QStm_GestureFramework();
	m_gestureEngine = new QStm_GestureEngine();
	m_statemachine = new QStm_StateMachine();
	m_statemachine->addUiEventObserver(m_gestureEngine);
	//m_config = new QStm_GestureParameters();    
}

QStm_GestureEngineApi::~QStm_GestureEngineApi()
{
    // Prevent reactivation of contexts as they remove themselves
    m_dtorPhase = true;

    qDeleteAll(m_contexts.begin(), m_contexts.end());
    m_contexts.clear();
    m_ctxtStack.clear();
    //delete m_config;
    delete m_gestureEngine;
    delete m_statemachine;
}

QStm_GestureContext* QStm_GestureEngineApi::createContext(int /*aId*/ )
{
    QStm_GestureContext* ctxt = new QStm_GestureContext(*this);
    return ctxt;
}

QStm_GestureContext* QStm_GestureEngineApi::context(int /*aId*/ )
{
    return NULL;
}

void QStm_GestureEngineApi::enableContext(QStm_GestureContext& context )
{
    // NB: enabling context puts it on top of the Context Stack
    int idx = m_ctxtStack.indexOf(&context);
    if(idx >= 0) {
        m_ctxtStack.removeAt(idx);
    }

    setupRecognizers(context, true);

    m_ctxtStack.append(&context);
}

void QStm_GestureEngineApi::disableContext(QStm_GestureContext& context )
{
    int idx = m_ctxtStack.indexOf(&context);
    
    if(idx == -1) {
        return;
    }

    m_ctxtStack.removeAt(idx);

    for(int i = 0; i < qstmGesture::EStmGestureUid_Count; ++i) {
    	qstmGesture::QStm_GestureRecogniserIf* rec = context.m_recognizers[i];
        if(rec) {
        	m_gestureEngine->removeGesture(rec);
        }
    }
/* OK: we need to decide semantics of the GestureContext concept:
   - is only one is active at a time?
   - is there a stack of them
   OR
   - application activates and deactivates them as needed
   - GestureEngine only ensures that proper order of recognizers is used

   Disabled code below, because it doesn't allow porting of the stmProto demo,
   where two TestContainer are used, each with own gesture context, simultaneously.

   If app uses only one context, then this change doesn't break anything

    // re-activate previous (new top-most) context
    // NB: if deleted context is not top-most (active) one, no updates done
    TInt count = m_ctxtStack.Count();
    if(idx == count && count > 0 && !m_dtorPhase)
        {
        QStm_GestureContext* previous = m_ctxtStack[count - 1];
        setupRecognizers(*previous, EFalse);
        }
*/
}

template<class T>
void QStm_GestureEngineApi::initRecognizer(T*& gesture, QStm_GestureContext& context, bool isNewCtx )
{
    qstmGesture::QStm_GestureRecogniserIf*& recognizer = context.m_recognizers[T::KUid];
    gesture = static_cast<T*>(recognizer);
    if(!gesture && isNewCtx) {
        recognizer = gesture = new T(&context);
        recognizer->enableLogging((context.m_logging & (1<<T::KUid)) != 0);
    }

    // TODO: Add in right place according to gesture class
    // Find similar (by Uid gesture, insert before it), otherwise add as last or
    //      before any known gestures that should follow after it (NOT IMPLEMENTED)
    
    int pos = m_gestureEngine->findGesture(T::KUid);
    bool added = m_gestureEngine->insertGesture(gesture, pos >= 0 ? pos : m_gestureEngine->gestureCount());
    if(!added) {
    	// TODO: exception here?
    }
}

void QStm_GestureEngineApi::setupRecognizers(QStm_GestureContext& context, bool isNewCtx )
{
    // Order of recognizers in the Gesture Engine (upper ones receive input before lower ones)
    //
    // PINCH
    // CORNER_ZOOM
    // EDGE_SCROLL
    // LONGPRESS
    // TOUCH
    // UP_DOWN
    // LEFT_RIGHT
    // HOVER
    // PAN
    // TAP / DOUBLE_TAP
    // FLICK
    // RELEASE
    // UNKNOWN

    QStm_GestureParameters& conf = context.config();

    bool filter = conf.param(qstmGesture::EEnableFiltering) != 0;

    // TOUCH AREA
    qstmGesture::QStm_GestureArea& touchArea = *(conf.area(qstmGesture::ETouchArea));
    int touchAreaSizeInMm = touchArea.m_size.width();
    m_statemachine->setTouchAreaShape ( qstmUiEventEngine::QStm_AreaShape(touchArea.m_shape) );
    m_statemachine->setTouchArea      ( !filter ? 0 : touchAreaSizeInMm );
    m_statemachine->setTouchTimeout   ( !filter ? 0 : touchArea.m_timeout);
    int moveToleranceInMm = conf.param(qstmGesture::EMoveTolerance);
    m_statemachine->setMoveTolerance(moveToleranceInMm);
    
    qreal axisLock = conf.param(qstmGesture::EAxisLockThreshold) /100.f;
    
    QWidget* gestureContext = static_cast<QWidget*>(context.getOwner());
    QRect ctxtRect = gestureContext ? gestureContext->rect() : QRect();
    if(gestureContext) {
        QPoint p = gestureContext->mapToGlobal(QPoint(0,0)) ;
        ctxtRect.moveTo(p) ;
        }

    // ===================================================== PINCH
    using qstmGesture::QStm_PinchGestureRecogniser;

    if (conf.enabled(QStm_PinchGestureRecogniser::KUid)) {
        QStm_PinchGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            qreal pspeed = conf.param(qstmGesture::EPinchSpeed) / 100.f;
            gesture->setPinchingSpeed(pspeed);
        }
    }

    // ===================================================== CORNER ZOOM
    using qstmGesture::QStm_ZoomGestureRecogniser;

    if (conf.enabled(QStm_ZoomGestureRecogniser::KUid)) {
        QStm_ZoomGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            gesture->setArea(ctxtRect);
            gesture->setRange(conf.param(qstmGesture::EZoomCornerSize));
        }
    }

    // ===================================================== EDGE SCROLL
    using qstmGesture::QStm_EdgeScrollGestureRecogniser;

    if (conf.enabled(QStm_EdgeScrollGestureRecogniser::KUid)) {
        QStm_EdgeScrollGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            gesture->setArea(ctxtRect);
            gesture->setScrollRange(conf.param(qstmGesture::EEdgeScrollRange)); // range is 20 pixels from the edge TODO: add this to settings...
        }
    }

    // ===================================================== LONG PRESS
    using qstmGesture::QStm_LongPressGestureRecogniser;

    if (conf.enabled(QStm_LongPressGestureRecogniser::KUid)) {
        QStm_LongPressGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            gesture->setArea(ctxtRect);
        }
    }

    // ===================================================== TOUCH
    using qstmGesture::QStm_TouchGestureRecogniser;

    if (conf.enabled(QStm_TouchGestureRecogniser::KUid)) {
    	QStm_TouchGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            // define empty area so that touch is reported only inside
            // our window (touch recognizer handles either an area or the target window)
            gesture->setArea(QRect());
        }
    }

    // ===================================================== LEFT-RIGHT
    using qstmGesture::QStm_LeftrightGestureRecogniser;

    if (conf.enabled(QStm_LeftrightGestureRecogniser::KUid)) {
        QStm_LeftrightGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);
        gesture->setAxisLockThreshold(axisLock);
        
    }

    // ===================================================== UP-DOWN
    using qstmGesture::QStm_UpdownGestureRecogniser;

    if (conf.enabled(QStm_UpdownGestureRecogniser::KUid)) {
        QStm_UpdownGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);
        gesture->setAxisLockThreshold(axisLock);
    }

    // ===================================================== HOVER
    using qstmGesture::QStm_HoveringGestureRecogniser;

    if (conf.enabled(QStm_HoveringGestureRecogniser::KUid)) {
        QStm_HoveringGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);
        if(gesture) {
            gesture->setHoveringSpeed(conf.param(qstmGesture::EHoverSpeed) / 100.f);
        }
    }

    // ===================================================== PAN
    using qstmGesture::QStm_PanGestureRecogniser;

    if (conf.enabled(QStm_PanGestureRecogniser::KUid)) {
        QStm_PanGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            gesture->setPanningSpeedLow ( conf.param(qstmGesture::EPanSpeedLow)  / 100.f );
            gesture->setPanningSpeedHigh( conf.param(qstmGesture::EPanSpeedHigh) / 100.f );
        }
    }

    // ===================================================== MAYBE TAP
    using qstmGesture::QStm_MaybeTapGestureRecogniser;

    if (conf.enabled(QStm_MaybeTapGestureRecogniser::KUid)) {
        int pos = m_gestureEngine->findGesture(QStm_MaybeTapGestureRecogniser::KUid);
        QStm_MaybeTapGestureRecogniser* gesture = NULL;
        
        if (pos > -1) {
            gesture = static_cast<QStm_MaybeTapGestureRecogniser*>(m_gestureEngine->gestureAt(pos));
            gesture->addTapListener(&context, context.getOwner());
        }
        else {
        initRecognizer(gesture, context, isNewCtx);
        }
        
        if(gesture) {
            gesture->setTapRange( touchAreaSizeInMm );
        }

    }
    
    
    // ===================================================== TAP / DOUBLE TAP
    // Add recognizer before any existing Flick, Release, Unknown
    // Add the gesture to the gesture engine
    using qstmGesture::QStm_TapGestureRecogniser;

    if (conf.enabled(QStm_TapGestureRecogniser::KUid)) {
        int pos = m_gestureEngine->findGesture(QStm_TapGestureRecogniser::KUid);
        QStm_TapGestureRecogniser* gesture = NULL;
        
        if (pos > -1) {
            gesture = static_cast<QStm_TapGestureRecogniser*>(m_gestureEngine->gestureAt(pos));
            gesture->addTapListener(&context, context.getOwner());
            gesture->addDoubleTapListener(&context, context.getOwner());
        }
        else {
            initRecognizer(gesture, context, isNewCtx);
        }

        if(gesture) {
            gesture->setDoubleTapTimeout(conf.param(qstmGesture::EDoubleTapTimeout));
            gesture->setDoubleTapRange( touchAreaSizeInMm );
            gesture->ignoreFirstTap(false);
        }
    }

    // ===================================================== FLICK
    using qstmGesture::QStm_FlickGestureRecogniser;

    if (conf.enabled(QStm_FlickGestureRecogniser::KUid)) {
        QStm_FlickGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);

        if(gesture) {
            qreal flickSpeed = conf.param(qstmGesture::EFlickSpeed) / 100.f;
            gesture->setFlickingSpeed(flickSpeed);
        }
    }

    // ===================================================== RELEASE
            using qstmGesture::QStm_ReleaseGestureRecogniser;

            if (conf.enabled(QStm_ReleaseGestureRecogniser::KUid)) {
                QStm_ReleaseGestureRecogniser* gesture = NULL;
                initRecognizer(gesture, context, isNewCtx);

                if(gesture) {
                    gesture->setArea(QRect());
                }
            }

    // ===================================================== UNKNOWN
    using qstmGesture::QStm_UnknownGestureRecogniser;

    if (conf.enabled(QStm_UnknownGestureRecogniser::KUid)) {
    	QStm_UnknownGestureRecogniser* gesture = NULL;
        initRecognizer(gesture, context, isNewCtx);
    }

    // ===========================================================
    if(isNewCtx) {
        for(int i = 0; i < qstmGesture::EStmGestureUid_Count; ++i) {
        	qstmGesture::QStm_GestureRecogniserIf* rec = context.m_recognizers[i];
            if(rec) {
                rec->enableLogging(context.m_logging & (1<<i)) ;
            }
        }
    }


    // HOLD AREA
    qstmGesture::QStm_GestureArea& holdArea = *conf.area(qstmGesture::EHoldArea);
    int holdAreaSizeInMm = holdArea.m_size.width();
    m_statemachine->setHoldAreaShape  ( qstmUiEventEngine::QStm_AreaShape(holdArea.m_shape) );
    m_statemachine->setHoldArea       ( !filter ? 0 : holdAreaSizeInMm );
    m_statemachine->setHoldTimeout    ( !filter ? 0 : holdArea.m_timeout);

    // TOUCH-TIME AREA
    qstmGesture::QStm_GestureArea& tTimeArea = *conf.area(qstmGesture::ETouchTimeArea);
    int tTimeAreaSizeInMm = tTimeArea.m_size.width();
    // NB: shape <-- TouchAreaShape
    m_statemachine->setTouchTimeArea      ( !filter ? 0 : tTimeAreaSizeInMm );

    // Timeouts, Adjustments, etc.
    m_statemachine->setTouchSuppressTimeout(!filter ? 0 : conf.param(qstmGesture::ESuppressTimeout)) ;
    m_statemachine->setMoveSuppressTimeout(!filter ? 0 : conf.param(qstmGesture::EMoveSuppressTimeout)) ;
    m_statemachine->enableCapacitiveUp    (!filter ? 0 : conf.param(qstmGesture::ECapacitiveUpUsed));
    m_statemachine->enableYadjustment     (!filter ? 0 : conf.param(qstmGesture::EAdjustYPos));
    m_statemachine->enableLogging(context.m_logging);
}

// =============================================================

QStm_GestureContext::QStm_GestureContext(QStm_GestureEngineApi& engine ) : 
		             m_engine(engine),
		             m_isActivated(false),
		             m_ownerControl(NULL),
		             m_config(NULL)
		            		 
{
	init();
}

void QStm_GestureContext::init()
{
    m_engine.m_contexts.append(this);
    m_config = new QStm_GestureParameters();
    //m_engine.getStateMachine()->addUiEventObserver(this);
    
    for(int i = 0; i < qstmGesture::EStmGestureUid_Count; ++i) {
        m_recognizers[i] = NULL;
    }
    
}

QStm_GestureContext::~QStm_GestureContext()
{
    // Remove all gesture listeners
    for(int i = m_listeners.count() - 1; i >= 0; --i) {
    	QStm_GestureListenerApiIf* listener = m_listeners[i];
        m_listeners.removeAt(i);
        listener->handleGestureListenerRemoved();
    }

    m_listeners.clear();

    // Remove all context's recognizers from the Gesture Engine
    deactivate();

    // Destroy all recognizers
    for(int r = 0; r < qstmGesture::EStmGestureUid_Count; ++r) {
    	qstmGesture::QStm_GestureRecogniserIf*& rec = m_recognizers[r];
        if(rec) {
            delete rec;
            rec = NULL;
        }
    }

    // Remove context from the Gesture Engine
    int idx = m_engine.m_contexts.indexOf(this);
    if(idx != -1) {
        m_engine.m_contexts.removeAt(idx);
    }

    delete m_config;
}

void QStm_GestureContext::addListener(QStm_GestureListenerApiIf* listener, int pos)
{
    m_listeners.insert(pos, listener);
}

int QStm_GestureContext::removeListener(QStm_GestureListenerApiIf* listener )
{
    int ind = m_listeners.indexOf(listener);
    if(ind >= 0) {
        m_listeners.removeAt(ind);
    }
    return ind;
}

void QStm_GestureContext::setContext(void* control)
{
    m_ownerControl = control;

    for(int i = 0; i < qstmGesture::EStmGestureUid_Count; ++i) {
    	QStm_GestureRecogniserIf* rec = m_recognizers[i];
        if(rec) {
            rec->setOwner(control);
        }
    }
}

void QStm_GestureContext::activate(void* control)
{
	setContext(control);
	activate();
}

void QStm_GestureContext::activate()
{
    if(isActive()) {
        // re-enable all recognizers
        enableRecognizers();
        return;
    }

    // 1. Tell Engine to deactivate active context

    // 2. Setup all gesture recognizers
    m_engine.enableContext(*this);

    // 3. Notify listeners
    enableRecognizers();

    //
    m_isActivated = true;
}

void QStm_GestureContext::deactivate()
{
    m_engine.disableContext(*this);
    m_isActivated = false;    
}

void QStm_GestureContext::gestureEnter(QStm_GestureIf& gesture )
{
	dispatchGestureEvent(gesture.gestureUid(), &gesture);
}

void QStm_GestureContext::gestureExit(QStm_GestureIf& gesture )
{
    dispatchGestureEvent(gesture.gestureUid(), NULL);
}

void* QStm_GestureContext::getOwner()
{
    return m_ownerControl;
}

QStm_Gesture* QStm_GestureContext::createQStmGesture(QStm_GestureUid uid,
                                                           QStm_GestureIf* gesture)
{
    QStm_Gesture* gest = new QStm_Gesture();
    int stmGestType = gesture ? gesture->getType() : -1;
    
    switch(uid) {
        case qstmGesture::EGestureUidTap:
        {
            qstmGesture::QStm_TapType type = qstmGesture::QStm_TapType(stmGestType);
            if (type == qstmGesture::ETapTypeDouble) {
                gest->setGestureStmType(QStmDoubleTapGestureType);
            }
            else  {
                gest->setGestureStmType(QStmTapGestureType);
            }
            break;    
        }
        
        case qstmGesture::EGestureUidTouch:
        {
            gest->setGestureStmType(QStmTouchGestureType);
            break;    
        }
        
        case qstmGesture::EGestureUidRelease:
        {
            gest->setGestureStmType(QStmReleaseGestureType);
            break;
        }
        
        case qstmGesture::EGestureUidFlick:
        {
            gest->setGestureStmType(QStmFlickGestureType);
            break;    
        }
        
        case qstmGesture::EGestureUidLeftRight:
        {
            gest->setGestureStmType(QStmLeftRightGestureType);
            break;    
        }
        
        case qstmGesture::EGestureUidUpDown:
        {
            gest->setGestureStmType(QStmUpDownGestureType);
            break;
        }
        
        case qstmGesture::EGestureUidPan:
        {
            gest->setGestureStmType(QStmPanGestureType);
            break;
        }
        
        case qstmGesture::EGestureUidHover:
        {
            gest->setGestureStmType(QStmHoverGestureType);
            break;
        }

        case qstmGesture::EGestureUidLongPress:
        {
            gest->setGestureStmType(QStmLongPressGestureType);
            break;
        }
        
        case qstmGesture::EGestureUidEdgeScroll:
        {
            gest->setGestureStmType(QStmEdgeScrollGestureType);
            break;
        }
        
        case qstmGesture::EGestureUidCornerZoom:
        {
            gest->setGestureStmType(QStmCornerZoomGestureType);
            break;
        }
        
        case qstmGesture::EGestureUidPinch:
        {
            gest->setGestureStmType(QStmPinchGestureType);
            break;
        }
    }
    
    if (gesture) { //gesture enter
        gest->setGestureSubType(gesture->getType());
        gest->setDirection(gesture->getDirection());
        QPoint vec = gesture->getLengthAndDirection();
        gest->setLengthAndDirection(vec);
        gest->setSpeed(gesture->getSpeed());
        QPoint pos = gesture->getLocation();
        gest->setPosition(pos);
        QPoint pos2 = gesture->getLocation2();
        gest->setPosition2(pos2);
        gest->setDetails(gesture->getDetails());
        gest->setSpeedVec(gesture->getSpeedVec());
        QWidget* w = static_cast<QWidget*>(gesture->target());
        gest->setTarget(w);
    }
    else {
    	gest->setGestureState(Qt::GestureFinished);
    }
    
    return gest;
}

void QStm_GestureContext::dispatchGestureEvent(qstmGesture::QStm_GestureUid uid,
                                               qstmGesture::QStm_GestureIf* gesture )
{
    bool consumed = false;
    bool suspended = false;
    
    
    
    for(int i = 0; i < m_listeners.count(); ++i) {
    	QStm_GestureListenerApiIf* listener = m_listeners[i];
        if(consumed) {
            listener->handleGestureListenerSuppressed(uid, gesture);
        }
        else {
        	QStm_GestureListenerApiIf::QStm_ProcessingResult res = listener->handleGestureEvent(uid, gesture);
            if(res & QStm_GestureListenerApiIf::EConsume) {
                consumed = true; // TODO: maybe we should notify all previous listeners as well...
            }

            suspended |= (res & QStm_GestureListenerApiIf::ESuspend) != 0; // TODO: notify listeners?
        }
    }
    if(suspended) {
        suspendRecognizer(uid);
    }
}

void QStm_GestureContext::suspendRecognizer(qstmGesture::QStm_GestureUid uid)
{
	qstmGesture::QStm_GestureRecogniserIf* rec = m_recognizers[uid];
    if(rec && !rec->isEnabled()) {
        rec->enable(false);
        // TODO: Notify listener
    }
}

void QStm_GestureContext::enableRecognizers()
{
    for(int i = 0; i < qstmGesture::EStmGestureUid_Count; ++i) {
        enableRecognizer(qstmGesture::QStm_GestureUid(i));
    }
}

void QStm_GestureContext::enableRecognizer(qstmGesture::QStm_GestureUid uid )
{
    qstmGesture::QStm_GestureRecogniserIf* rec = m_recognizers[uid];
    if(rec && !rec->isEnabled()) {
        rec->enable(true);
        // TODO: Notify listener
    }
}


void QStm_GestureContext::handleUiEvent( const qstmUiEventEngine::QStm_UiEventIf& event )
{
    emit(uiEvent(event));	
}


bool QStm_GestureContext::handleSymbianPlatformEvent(const QSymbianEvent* platEvent) 
{ 
    return m_engine.getStateMachine()->handleSymbianPlatformEvent(platEvent); 
}


bool QStm_GestureContext::handleX11PlatformEvent(const XEvent* platEvent)
{
    return m_engine.getStateMachine()->handleX11PlatformEvent(platEvent);
}

bool QStm_GestureContext::handleWinPlatformEvent(const void* platEvent)
{
    return m_engine.getStateMachine()->handleWinPlatformEvent(platEvent);
}

void QStm_GestureContext::enableDblClick(bool enable)
{
    m_engine.getStateMachine()->enableDblClick(enable);
}

void QStm_GestureContext::setLogging(int enabled)
{ 
    m_logging = enabled;
    m_engine.getGestureEngine()->enableLogging(enabled);
}