webengine/webkitutils/stmgesturefw/src/statemachine.cpp
branchRCL_3
changeset 49 919f36ff910f
equal deleted inserted replaced
48:79859ed3eea9 49:919f36ff910f
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   
       
    15 *
       
    16 */
       
    17 
       
    18 #include <coemain.h>
       
    19 #include <aknutils.h>
       
    20 #include <aknappui.h>
       
    21 
       
    22 #include "statemachine.h"
       
    23 #include "stateengine.h"
       
    24 #include "rt_uievent.h"
       
    25 #include "callbacktimer.h"
       
    26 #include "stateengineconfiguration.h"
       
    27 
       
    28 #include "filelogger.h"
       
    29 #include "utils.h"
       
    30 
       
    31 using namespace stmUiEventEngine ;
       
    32 
       
    33 GLREF_D const char* stateNames[8] ;
       
    34 
       
    35 #ifdef GESTURE_LOGGING
       
    36 const char* const ttypeNames[] = {  // for debugging purposes define the names of the pointer events
       
    37             "EButton1Down         ",
       
    38             "EButton1Up           ",
       
    39             "EButton2Down         ",
       
    40             "EButton2Up           ",
       
    41             "EButton3Down         ",
       
    42             "EButton3Up           ",
       
    43             "EDrag                ",
       
    44             "EMove                ",
       
    45             "EButtonRepeat        ",
       
    46             "ESwitchOn            ",
       
    47             "EOutOfRange          ",
       
    48             "EEnterCloseProximity ",
       
    49             "EExitCloseProximity  ",
       
    50             "EEnterHighPressure   ",
       
    51             "EExitHighPressure    "
       
    52             };
       
    53 #endif
       
    54 
       
    55 /// Fast integer distance
       
    56 int stmUiEventEngine::Distance(int x, int y)
       
    57 {
       
    58 /*
       
    59     double d = dx * dx + dy * dy;
       
    60     double dist ;
       
    61     Math::Sqrt(dist, d) ;
       
    62     return dist;
       
    63 */
       
    64     if(x<0) x=-x;
       
    65     if(y<0) y=-y;
       
    66     if(x < y)
       
    67     {
       
    68       int t = x;
       
    69       x = y;
       
    70       y = t;        // ensures that x >= y
       
    71     }
       
    72     int dist = (y < ((13107 * x)>>15)) ?    // * (.4)
       
    73               (x + ((y * 6310)>>15)) :      // * (.192582403)
       
    74               (((x * 27926)>>15)            // * (.852245894)
       
    75                  + ((y * 18414)>>15));      // * (.561967668)
       
    76     return dist;
       
    77 }
       
    78 
       
    79 
       
    80 /*!
       
    81   CStateMachine implements the state machine and the integration fo the
       
    82   state machine to the OS.  The CStateEngine handles the actual processing of the
       
    83   finite state machine but CStateMachine provides the OS specific things like timers
       
    84   and message conversion.
       
    85 
       
    86   The CStateMachine implements the MAknWsEventObserver interface so it adds
       
    87   itself to be the observer to the event monitor of the application UI.
       
    88 
       
    89   It handles the pointer events either by using the monitoring interface or
       
    90   lets the application call the HandlePointerEventL method.
       
    91 
       
    92   If MAknWsEventObserver interface is used then all the events passed to the
       
    93   application are seen.  The target of the gesture starting event is stored
       
    94   so that the generated UI event contains the target as a void pointer. (should it just be CoeControl*?)
       
    95 
       
    96   There is possibility to adjust the Y coordinate of the touch point.
       
    97   In capacitive touch (Alvin) it seems that the perceived touch point is
       
    98   below the middle part of the fingertip.  The user however tries to use the
       
    99   finger to point so that the touch point should correspond to the tip of the finger.
       
   100   It seems that this illusion can be achieved by adjusting the Y position about 3 mm up.
       
   101   However, this adjustment can properly be done only when the touch point is far enough
       
   102   from the window borders up or down.  When close to top or bottom of window, the adjustment
       
   103   makes it impossible touch points near the edge, unless adjustment depends on the distance from
       
   104   window border.
       
   105   So in practice it should be the window server doing the adjustment, and after adjustment
       
   106   deciding the target window.  At application level the adjustment can only be done properly
       
   107   if window borders do not need to be crossed.
       
   108 
       
   109  */
       
   110 CStateMachine::CStateMachine()
       
   111 {
       
   112     m_WasMessageFiltered = false ;
       
   113     m_wseventmonitoringenabled = false ; // NB: enabled only if really used by application
       
   114     m_loggingenabled = false ;
       
   115     m_capacitiveup = false ;
       
   116     m_adjustYposition = false ;
       
   117 }
       
   118 /*!Destructor
       
   119  */
       
   120 CStateMachine::~CStateMachine()
       
   121 {
       
   122     for (int i = 0; i < KMaxNumberOfPointers; i++)
       
   123     {
       
   124         delete m_holdTimer[i] ;
       
   125         delete m_touchTimer[i] ;
       
   126         delete m_suppressTimer[i] ;
       
   127         delete m_impl[i] ;
       
   128     }
       
   129     delete m_config ;
       
   130 }
       
   131 
       
   132 CStateMachine* CStateMachine::NewLC()
       
   133 {
       
   134     CStateMachine* self = new (ELeave) CStateMachine();
       
   135     CleanupStack::PushL(self);
       
   136     self->ConstructL();
       
   137     return self;
       
   138 }
       
   139 
       
   140 CStateMachine* CStateMachine::NewL()
       
   141 {
       
   142     CStateMachine* self = CStateMachine::NewLC();
       
   143     CleanupStack::Pop(self); 
       
   144     return self;
       
   145 }
       
   146 /*!
       
   147  Construct the actual state machine implemented in CStateEngine and
       
   148  creates the timers.  It also adds itself to the observer list of
       
   149  CAknWsEventMonitor of the application.
       
   150 
       
   151  */
       
   152 void CStateMachine::ConstructL()
       
   153 {
       
   154     m_config = new(ELeave)CStateEngineConfiguration() ;
       
   155     m_config->ConstructL();
       
   156 
       
   157     for (int i = 0; i < KMaxNumberOfPointers; i++)
       
   158     {
       
   159         m_impl[i] = new(ELeave) CStateEngine(m_config, this, i) ;
       
   160         m_holdTimer[i] = CCallbackTimer::NewL(*this, handleholdTimer, 0, i, ETrue);
       
   161         m_touchTimer[i] = CCallbackTimer::NewL(*this, handletouchTimer, 0, i, ETrue);
       
   162         m_suppressTimer[i] = CCallbackTimer::NewL(*this, handlesuppressTimer, 0, i, ETrue);
       
   163     }
       
   164 
       
   165     m_coeEnv = CCoeEnv::Static();
       
   166 
       
   167     /* IMEX: monitor added only if enabled
       
   168       add us to see the WsEvents so that we are able to interpret them;
       
   169 
       
   170     CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ;
       
   171     pui->EventMonitor()->AddObserverL(this) ;
       
   172     pui->EventMonitor()->Enable(ETrue) ;
       
   173     */
       
   174 
       
   175     m_3mminpixels = Mm2Pixels(1.5) ;
       
   176 }
       
   177 /*!
       
   178  * Process one pointer event in the state machine.
       
   179  * \return true, if the event did not generate a UI event immediately.
       
   180  */
       
   181 bool CStateMachine::HandleStateEvent(const TPointerEvent& aPointerEvent, 
       
   182                                      void* aTarget, 
       
   183                                      const TTime& aTime)
       
   184 {
       
   185     TInt index = PointerIndex(aPointerEvent);
       
   186     CStateEngine* engine = m_impl[index];
       
   187     CreateHwEvent(engine->initEvent(), aPointerEvent, aTarget, aTime) ;
       
   188     if (m_loggingenabled)
       
   189     {
       
   190         LOGARG("HandleStateEvent: ptr %d", index) ;
       
   191     }
       
   192     m_WasMessageFiltered = engine->handleStateEvent() ;
       
   193     return m_WasMessageFiltered ;
       
   194 }
       
   195 /*!
       
   196  * wrapper method for the actual implementation in the CStateEngine.
       
   197  */
       
   198 bool CStateMachine::wasLastMessageFiltered(TInt aPointerNumber)
       
   199 {
       
   200     return m_impl[aPointerNumber]->wasLastMessageFiltered() ;
       
   201 }
       
   202 /*!
       
   203  * wrapper method for the actual implementation in the CStateEngine.
       
   204  */
       
   205 TRect CStateMachine::getTouchArea(TInt aPointerNumber)
       
   206 {
       
   207     return m_impl[aPointerNumber]->getTouchArea() ;
       
   208 }
       
   209 /*!
       
   210  * wrapper method for the actual implementation in the CStateEngine.
       
   211  */
       
   212 void CStateMachine::setTouchTimeArea(long fingersize_mm)
       
   213 {
       
   214     m_config->setTouchTimeArea(fingersize_mm) ;
       
   215 }
       
   216 /*!
       
   217  * wrapper method for the actual implementation in the CStateEngine.
       
   218  */
       
   219 void CStateMachine::setTouchArea(long fingersize_mm)
       
   220 {
       
   221     m_config->setTouchArea(fingersize_mm) ;
       
   222 }
       
   223 /*!
       
   224  * wrapper method for the actual implementation in the CStateEngine.
       
   225  */
       
   226 TAreaShape CStateMachine::getTouchAreaShape()
       
   227 {
       
   228     return m_config->getTouchAreaShape() ;
       
   229 }
       
   230 /*!
       
   231  * wrapper method for the actual implementation in the CStateEngine.
       
   232  */
       
   233 void CStateMachine::setTouchAreaShape(const TAreaShape aShape)
       
   234 {
       
   235     m_config->setTouchAreaShape(aShape) ;
       
   236 }
       
   237 /*!
       
   238  * wrapper method for the actual implementation in the CStateEngine.
       
   239  */
       
   240 unsigned int CStateMachine::getTouchTimeout()
       
   241 {
       
   242     return m_config->getTouchTimeout() ;
       
   243 }
       
   244 /*!
       
   245  * wrapper method for the actual implementation in the CStateEngine.
       
   246  */
       
   247 void CStateMachine::setTouchTimeout(unsigned int aDelay)
       
   248 {
       
   249     m_config->setTouchTimeout(aDelay) ;
       
   250 }
       
   251 /*!
       
   252  * wrapper method for the actual implementation in the CStateEngine.
       
   253  */
       
   254 TRect CStateMachine::getHoldArea(TInt aPointerNumber)
       
   255 {
       
   256     return m_impl[aPointerNumber]->getHoldArea() ;
       
   257 }
       
   258 /*!
       
   259  * wrapper method for the actual implementation in the CStateEngine.
       
   260  */
       
   261 void CStateMachine::setHoldArea(long fingersize_mm)
       
   262 {
       
   263     m_config->setHoldArea(fingersize_mm) ;
       
   264 }
       
   265 /*!
       
   266  * wrapper method for the actual implementation in the CStateEngine.
       
   267  */
       
   268 TAreaShape CStateMachine::getHoldAreaShape()
       
   269 {
       
   270     return m_config->getHoldAreaShape() ;
       
   271 }
       
   272 /*!
       
   273  * wrapper method for the actual implementation in the CStateEngine.
       
   274  */
       
   275 void CStateMachine::setHoldAreaShape(const TAreaShape aShape)
       
   276 {
       
   277     m_config->setHoldAreaShape(aShape) ;
       
   278 }
       
   279 /*!
       
   280  * wrapper method for the actual implementation in the CStateEngine.
       
   281  */
       
   282 unsigned int CStateMachine::getHoldTimeout()
       
   283 {
       
   284     return m_config->getHoldTimeout() ;
       
   285 }
       
   286 /*!
       
   287  * wrapper method for the actual implementation in the CStateEngine.
       
   288  */
       
   289 void CStateMachine::setHoldTimeout(unsigned int a)
       
   290 {
       
   291     m_config->setHoldTimeout(a) ;
       
   292 }
       
   293 /*!
       
   294  * wrapper method for the actual implementation in the CStateEngine.
       
   295  */
       
   296 unsigned int CStateMachine::getTouchSuppressTimeout()
       
   297 {
       
   298     return m_config->getTouchSuppressTimeout() ;
       
   299 }
       
   300 /*!
       
   301  * wrapper method for the actual implementation in the CStateEngine.
       
   302  */
       
   303 void CStateMachine::setTouchSuppressTimeout(unsigned int a)
       
   304 {
       
   305     m_config->setTouchSuppressTimeout(a) ;
       
   306 }
       
   307 /*!
       
   308  * wrapper method for the actual implementation in the CStateEngine.
       
   309  */
       
   310 unsigned int CStateMachine::getMoveSuppressTimeout()
       
   311 {
       
   312     return m_config->getMoveSuppressTimeout() ;
       
   313 }
       
   314 /*!
       
   315  * wrapper method for the actual implementation in the CStateEngine.
       
   316  */
       
   317 void CStateMachine::setMoveSuppressTimeout(unsigned int a)
       
   318 {
       
   319     m_config->setMoveSuppressTimeout(a) ;
       
   320 }
       
   321 /*!
       
   322  * wrapper method for the actual implementation in the CStateEngine.
       
   323  */
       
   324 bool CStateMachine::addUiEventObserver(MUiEventObserver* observer)
       
   325 {
       
   326     return m_config->addUiEventObserver(observer) ;
       
   327 }
       
   328 /*!
       
   329  * wrapper method for the actual implementation in the CStateEngine.
       
   330  */
       
   331 bool CStateMachine::removeUiEventObserver(MUiEventObserver* observer)
       
   332 {
       
   333     return m_config->removeUiEventObserver(observer) ;
       
   334 }
       
   335 /*!
       
   336  * wrapper method for the actual implementation in the CStateEngine.
       
   337  */
       
   338 void CStateMachine::enableLogging(bool aEnable)
       
   339 {
       
   340     m_loggingenabled = aEnable ;
       
   341     m_config->enableLogging(aEnable) ;
       
   342 }
       
   343 
       
   344 TInt CStateMachine::PointerIndex(const TPointerEvent& aPointerEvent)
       
   345 {
       
   346     TInt index = 0;
       
   347 #if defined(ADVANCED_POINTER_EVENTS)
       
   348     if (aPointerEvent.IsAdvancedPointerEvent())
       
   349     {
       
   350         const TAdvancedPointerEvent* tadvp = aPointerEvent.AdvancedPointerEvent() ;
       
   351         index = tadvp->PointerNumber() ;
       
   352     }
       
   353 #endif
       
   354     return index;
       
   355 }
       
   356 
       
   357 /*!
       
   358  * Convert pointer event (TPointerEvent) into THwEvent into the variable m_hwe.
       
   359  * THwEvent contains the position and simplified event type
       
   360  * but also has the target window and timestamp included.
       
   361  */
       
   362 void CStateMachine::CreateHwEvent(THwEvent& aEvent, 
       
   363                                   const TPointerEvent& aPointerEvent, 
       
   364                                   void* aTarget, 
       
   365                                   const TTime& aTime)
       
   366 {
       
   367 /*  should be set by this moment by CStateEngine with that index in CStateEngine::initEvent()
       
   368     aEvent.iPointerNumber = PointerIndex(aPointerEvent);
       
   369 */
       
   370     aEvent.iTarget = aTarget ;
       
   371     aEvent.iTime = aTime;
       
   372     // Change to screen coordinates here while the window is still existing....
       
   373     aEvent.iPosition = screenCoordinates(aPointerEvent.iPosition, aTarget) ;
       
   374     switch (aPointerEvent.iType)
       
   375     {
       
   376     case TPointerEvent::EButton1Down:
       
   377     case TPointerEvent::EButton2Down:
       
   378     case TPointerEvent::EButton3Down:
       
   379     {
       
   380         aEvent.iType = stmUiEventEngine::EDown ;
       
   381         break ;
       
   382     }
       
   383     case TPointerEvent::EButton1Up:
       
   384     case TPointerEvent::EButton2Up:
       
   385     case TPointerEvent::EButton3Up:
       
   386     {
       
   387         if (m_capacitiveup)
       
   388         {
       
   389             aEvent.iType = stmUiEventEngine::ECapacitiveUP ;   // How could this be checked automagically?
       
   390         }
       
   391         else
       
   392         {
       
   393             aEvent.iType = stmUiEventEngine::EResistiveUP ;    // How could this be checked automagically?
       
   394         }
       
   395 
       
   396         break ;
       
   397     }
       
   398     case TPointerEvent::EDrag:
       
   399     {
       
   400         aEvent.iType = stmUiEventEngine::EDrag ;
       
   401         break ;
       
   402     }
       
   403     }
       
   404 }
       
   405 ////////////////////////////////////////////////////////////////////////////////////////////
       
   406 /*!
       
   407  * Start the hold timer if it is not already active.
       
   408  */
       
   409 void CStateMachine::startholdTimer(TInt aPointerNumber)
       
   410 {
       
   411     if (!m_holdTimer[aPointerNumber]->IsActive())
       
   412     {
       
   413         m_holdTimer[aPointerNumber]->Start();
       
   414     }
       
   415 }
       
   416 
       
   417 /*!
       
   418  * The hold timer expiration: create a timer event and call the state machine
       
   419  */
       
   420 void CStateMachine::handleholdTimer(TInt aPointerNumber)
       
   421 {
       
   422     // We get an event, lets kick the state machine
       
   423     CStateEngine* engine = m_impl[aPointerNumber];
       
   424     CreateTimerEvent(engine->initEvent(), stmUiEventEngine::EHoldTimer) ;
       
   425     engine->handleStateEvent() ;
       
   426 }
       
   427 /*!
       
   428  * Stop the hold timer
       
   429  */
       
   430 void CStateMachine::cancelholdTimer(TInt aPointerNumber)
       
   431 {
       
   432     m_holdTimer[aPointerNumber]->Cancel();
       
   433 }
       
   434 /*!
       
   435  * Start suppress timer.  The timeout has been set beforehand.
       
   436  */
       
   437 void CStateMachine::startsuppressTimer(TInt aPointerNumber)
       
   438 {
       
   439     m_suppressTimer[aPointerNumber]->Start();
       
   440 }
       
   441 /*!
       
   442  * The suppress timer expiration, create a timer event and call the state machine.
       
   443  */
       
   444 void CStateMachine::handlesuppressTimer(TInt aPointerNumber)
       
   445 {
       
   446     // We get an event, lets kick the state machine
       
   447     CStateEngine* engine = m_impl[aPointerNumber];
       
   448     CreateTimerEvent(engine->initEvent(), stmUiEventEngine::ESuppressTimer) ;
       
   449     engine->handleStateEvent() ;
       
   450 }
       
   451 /*!
       
   452  * stop the suppress timer
       
   453  */
       
   454 void CStateMachine::cancelsuppressTimer(TInt aPointerNumber)
       
   455 {
       
   456     m_suppressTimer[aPointerNumber]->Cancel();
       
   457 }
       
   458 /*!
       
   459  * start the touch timer if it is not already active.
       
   460  */
       
   461 void CStateMachine::starttouchTimer(TInt aPointerNumber)
       
   462 {
       
   463     if (!m_touchTimer[aPointerNumber]->IsActive())
       
   464     {
       
   465         m_touchTimer[aPointerNumber]->Start();
       
   466     }
       
   467 }
       
   468 
       
   469 /*!
       
   470  * The touch timer expiration, create timer event and call the state machine.
       
   471  */
       
   472 void CStateMachine::handletouchTimer(TInt aPointerNumber)
       
   473 {
       
   474     // We get an event, lets kick the state machine
       
   475     CStateEngine* engine = m_impl[aPointerNumber];
       
   476     CreateTimerEvent(engine->initEvent(), stmUiEventEngine::ETouchTimer) ;
       
   477     engine->handleStateEvent() ;
       
   478 }
       
   479 /*!
       
   480  * stop the touch timer
       
   481  */
       
   482 void CStateMachine::canceltouchTimer(TInt aPointerNumber)
       
   483 {
       
   484     if (m_touchTimer[aPointerNumber]->IsActive()) // we were waiting for additional events
       
   485     {
       
   486         m_touchTimer[aPointerNumber]->Cancel();
       
   487     }
       
   488 }
       
   489 /*!
       
   490  * CreateTimerEvent creates a timer event to the m_hwe variable.
       
   491  */
       
   492 void CStateMachine::CreateTimerEvent(THwEvent& aEvent, TStateMachineEvent aEventCode)
       
   493 {
       
   494     aEvent.iType = aEventCode ;
       
   495     // m_hwe.iPosition = TPos(0, 0) ;      should we just leave the previous pos
       
   496     TTime now ;
       
   497     now.HomeTime() ;
       
   498     aEvent.iTime = now ;
       
   499 }
       
   500 /*!
       
   501  * Events are processed either using the MAknWsEventObserver interface
       
   502  * or letting the view/container pass the pointer events to the state machine.
       
   503  * The member variable m_wseventmonitoringenabled defines which method is used.
       
   504  * If handlePoingterEventL is called, the calling CCoeCOntrol must provide itself
       
   505  * as the target.
       
   506  */
       
   507 void CStateMachine::HandlePointerEventL(const TPointerEvent& aPointerEvent, void *target)
       
   508 {
       
   509     if (m_wseventmonitoringenabled) return ;    // events are handled in the event monitor
       
   510     if (m_loggingenabled)
       
   511     {
       
   512 #if defined(ADVANCED_POINTER_EVENTS)
       
   513         TInt pointerNumber = PointerIndex(aPointerEvent) ;
       
   514         LOGARG("Pointer %d event %s at (%d %d)", pointerNumber,
       
   515                 ttypeNames[aPointerEvent.iType], aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY) ;
       
   516 #else
       
   517         LOGARG("Pointer event %s at (%d %d)",
       
   518                 ttypeNames[aPointerEvent.iType], aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY) ;
       
   519 #endif
       
   520     }
       
   521     TTime time = m_coeEnv->LastEvent().Time();
       
   522     HandleStateEvent(aPointerEvent, target, time) ;   // target needs to be there to convert from window to screen coordinates
       
   523 }
       
   524 /**
       
   525  * One possibility to implement gesture recognition is to intercept the events
       
   526  * using the event monitoring interface.  The HandleWsEventL method will get all events
       
   527  * passed to the application.  The aDestination parameter defines the window where the event
       
   528  * was targeted to.  The gesture recognition should use the target information
       
   529  * to determine how the gesture should be interpreted.
       
   530  * In the current implementation the aDestination needs to be one of the UI event observers
       
   531  * in order to process the message, but later when gesture recognition is added, this check
       
   532  * needs to be removed and the gesture recognition should handle the target of the gesture.
       
   533  */
       
   534 void CStateMachine::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
       
   535 {
       
   536     // Check which processing type we have for events.
       
   537     // If WsEvent monitoring, then process the message, otherwise return
       
   538     if (!m_wseventmonitoringenabled) return ;
       
   539 
       
   540     // Log the events passing trough to see what kind of stuff there goes...
       
   541     // and could the gesture recogniser grab them from here?
       
   542     TInt type=aEvent.Type();
       
   543     switch (type)
       
   544         {
       
   545     case EEventKey:
       
   546     case EEventKeyUp:
       
   547     case EEventKeyDown:
       
   548     {
       
   549         if (m_loggingenabled)
       
   550         {
       
   551             TKeyEvent* tke = aEvent.Key() ;
       
   552             LOGARG("Key event %d %d to %u", tke->iCode, tke->iScanCode, aDestination) ;
       
   553         }
       
   554         break;
       
   555     }
       
   556     case EEventPointer:
       
   557     {
       
   558         TPointerEvent* tpe = aEvent.Pointer() ;
       
   559         if (m_loggingenabled)
       
   560         {
       
   561             TRect rcd = aDestination->Rect() ;
       
   562             TPoint org = aDestination->PositionRelativeToScreen() ;
       
   563             TRect rcd2 = rcd ;
       
   564             rcd2.Move(org) ;
       
   565             TPoint screenpos = tpe->iPosition ;
       
   566             screenpos += org ;
       
   567 
       
   568 #if defined(ADVANCED_POINTER_EVENTS)
       
   569             TInt pointerNumber = PointerIndex(*tpe) ;
       
   570             LOGARG("Pointer %d event %s at (%d %d)[%d,%d] to 0x%x ((%d,%d)(%d,%d)): screen: ((%d,%d)(%d,%d))",
       
   571                     pointerNumber,
       
   572                     ttypeNames[tpe->iType],
       
   573                     tpe->iPosition.iX, tpe->iPosition.iY,
       
   574                     screenpos.iX, screenpos.iY,
       
   575                     aDestination,
       
   576                 rcd.iTl.iX, rcd.iTl.iY, rcd.iBr.iX, rcd.iBr.iY,
       
   577                 rcd2.iTl.iX, rcd2.iTl.iY, rcd2.iBr.iX, rcd2.iBr.iY) ;
       
   578 #else
       
   579             LOGARG("Pointer event %s at (%d %d)[%d,%d] to 0x%x ((%d,%d)(%d,%d)): screen: ((%d,%d)(%d,%d))",
       
   580                     ttypeNames[tpe->iType], tpe->iPosition.iX, tpe->iPosition.iY,
       
   581                     screenpos.iX, screenpos.iY,
       
   582                     aDestination,
       
   583                 rcd.iTl.iX, rcd.iTl.iY, rcd.iBr.iX, rcd.iBr.iY,
       
   584                 rcd2.iTl.iX, rcd2.iTl.iY, rcd2.iBr.iX, rcd2.iBr.iY) ;
       
   585 #endif
       
   586         }
       
   587         HandleStateEvent(*tpe, aDestination, aEvent.Time()) ;
       
   588         break;
       
   589     }
       
   590     case EEventPointerBufferReady:
       
   591         if (m_loggingenabled)
       
   592         {
       
   593             LOGARG("Pointer buffer ready event to %u", aDestination) ;
       
   594         }
       
   595         break;
       
   596     case EEventFocusLost:
       
   597     case EEventFocusGained:
       
   598         if (m_loggingenabled)
       
   599         {
       
   600             LOGARG("Focus message event to %u", aDestination) ;
       
   601         }
       
   602         break;
       
   603     case EEventSwitchOn:
       
   604         if (m_loggingenabled)
       
   605         {
       
   606             LOGARG("Switch On event to %u", aDestination) ;
       
   607         }
       
   608         break;
       
   609     case EEventUser:
       
   610         if (m_loggingenabled)
       
   611         {
       
   612             LOGARG("User event to %u", aDestination) ;
       
   613         }
       
   614         break;
       
   615     case EEventPowerMgmt:
       
   616         if (m_loggingenabled)
       
   617         {
       
   618             LOGARG("Power Mgmnt event to %u", aDestination) ;
       
   619         }
       
   620         break;
       
   621     case EEventMessageReady:
       
   622         if (m_loggingenabled)
       
   623         {
       
   624             LOGARG("Message Ready event to %u", aDestination) ;
       
   625         }
       
   626         break;
       
   627     case EEventScreenDeviceChanged:
       
   628         if (m_loggingenabled)
       
   629         {
       
   630             LOGARG("Screen device changed event to %u", aDestination) ;
       
   631         }
       
   632         break;
       
   633 
       
   634     default:
       
   635         if (m_loggingenabled)
       
   636         {
       
   637             LOGARG("default changed event %d to %u", type, aDestination) ;
       
   638         }
       
   639         break;
       
   640     }
       
   641 }
       
   642 /*!
       
   643  * Start the touch timer using a specified delay
       
   644  */
       
   645 void CStateMachine::startTouchTimer(TInt aDelay, TInt aPointerNumber)
       
   646 {
       
   647     m_touchTimer[aPointerNumber]->SetDelay(aDelay) ;
       
   648     starttouchTimer(aPointerNumber) ;
       
   649 }
       
   650 /*!
       
   651  *  Stop the touch timer.
       
   652  */
       
   653 void CStateMachine::cancelTouchTimer(TInt aPointerNumber)
       
   654 {
       
   655     canceltouchTimer(aPointerNumber) ;
       
   656 }
       
   657 /*!
       
   658  * Start hold timer using specified delay
       
   659  */
       
   660 void CStateMachine::startHoldTimer(TInt aDelay, TInt aPointerNumber)
       
   661 {
       
   662     m_holdTimer[aPointerNumber]->SetDelay(aDelay) ;
       
   663     startholdTimer(aPointerNumber) ;
       
   664 }
       
   665 /*!
       
   666  * Stop the hold timer
       
   667  */
       
   668 void CStateMachine::cancelHoldTimer(TInt aPointerNumber)
       
   669 {
       
   670     cancelholdTimer(aPointerNumber) ;
       
   671 }
       
   672 /*!
       
   673  * Start suppress timer using specified delay.
       
   674  */
       
   675 void CStateMachine::startSuppressTimer(TInt aDelay, TInt aPointerNumber)
       
   676 {
       
   677     m_suppressTimer[aPointerNumber]->SetDelay(aDelay) ;
       
   678     startsuppressTimer(aPointerNumber) ;
       
   679 }
       
   680 /*!
       
   681  *  Stop the suppress timer.
       
   682  */
       
   683 void CStateMachine::cancelSuppressTimer(TInt aPointerNumber)
       
   684 {
       
   685     cancelsuppressTimer(aPointerNumber) ;
       
   686 }
       
   687 
       
   688 /*!
       
   689  * Method sets the m_wseventmonitoringenabled.  If it is true,
       
   690  * then the state machine will be called from the HandleWsEventL method which
       
   691  * sees all the events passed to the application.
       
   692  *
       
   693  * Otherwise the HandlePointerEventL method call will cause the call to
       
   694  * state machine so the view/container needs to pass the pointer events to the state machine
       
   695  * in its own HandlePointerEventL -method.
       
   696  *
       
   697  */
       
   698 void CStateMachine::EnableWsEventMonitoring(bool aEnable)
       
   699 {
       
   700     if( !m_wseventmonitoringenabled && aEnable )
       
   701     {
       
   702         CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ;
       
   703         TRAPD(err, pui->EventMonitor()->AddObserverL(this)) ;
       
   704         if(!err)
       
   705             pui->EventMonitor()->Enable(ETrue) ;
       
   706     }
       
   707     else if( m_wseventmonitoringenabled && !aEnable )
       
   708     {
       
   709         CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ;
       
   710         pui->EventMonitor()->RemoveObserver(this) ;
       
   711         // Should not disable since it may be not the only user
       
   712         //pui->EventMonitor()->Enable(EFalse) ;
       
   713     }
       
   714 
       
   715     m_wseventmonitoringenabled = aEnable ;
       
   716 }
       
   717 TPoint CStateMachine::screenCoordinates(const TPoint& aPos, void* aGestureTarget)
       
   718 {
       
   719     TPoint newPos = aPos ;
       
   720     if (aGestureTarget)
       
   721     {
       
   722        CCoeControl* pcc = (CCoeControl*) aGestureTarget ;
       
   723        TPoint tp(TPoint(0,0));
       
   724         if (m_adjustYposition)
       
   725         {
       
   726             TSize sz = pcc->Size() ;
       
   727 
       
   728             // If we are running in capacitive touch device,
       
   729             // adjust the point up about 3 mm unless we are
       
   730             // near top or bottom of the window
       
   731 
       
   732             // Y position in the window
       
   733             int wY = newPos.iY - tp.iY;
       
   734             int edge = 2*m_3mminpixels;
       
   735 
       
   736             if (Rng(0, wY, edge - 1))
       
   737             {
       
   738                 // close to the top we adjust suitably so that immediately at the top adjust is 0
       
   739                 int adjust = wY / 2 ;
       
   740                 newPos.iY -= adjust ;
       
   741                 if (m_loggingenabled)
       
   742                 {
       
   743                     LOGARG("adjustment: nY %d tY %d [3mm: %d  adj: %d]", 
       
   744                             newPos.iY, tp.iY, m_3mminpixels, adjust) ;
       
   745                 }
       
   746 
       
   747             }
       
   748             else if (Rng(edge, wY, sz.iHeight - edge))
       
   749             {
       
   750 #ifdef GESTURE_LOGGING
       
   751                 int from = newPos.iY ;
       
   752 #endif
       
   753                 newPos.iY -= m_3mminpixels ;
       
   754                 if (m_loggingenabled)
       
   755                 {
       
   756                     LOGARG("adjustment: %d to %d [3mm: %d  middle]", 
       
   757                             from, newPos.iY, m_3mminpixels) ;
       
   758                 }
       
   759 
       
   760             }
       
   761             else
       
   762             {
       
   763                 // similarly at the bottom we adjust less the closer we get to the edge
       
   764                 int adjust = (sz.iHeight - wY) / 2 ;
       
   765                 newPos.iY -= adjust ;
       
   766                 if (m_loggingenabled)
       
   767                 {
       
   768                     LOGARG("adjustment: nY %d tY %d  sH %d [3mm: %d  adj: %d]",
       
   769                             newPos.iY, tp.iY, sz.iHeight, m_3mminpixels, adjust) ;
       
   770                 }
       
   771 
       
   772             }
       
   773         }
       
   774         else
       
   775         {
       
   776             // if the target does not own a window how can we adjust to the screen?
       
   777         }
       
   778     }
       
   779     return newPos ;
       
   780 }
       
   781 void CStateMachine::enableCapacitiveUp(bool aEnable)
       
   782 {
       
   783     m_capacitiveup = aEnable ;
       
   784 }
       
   785 void CStateMachine::enableYadjustment(bool aEnable)
       
   786 {
       
   787     m_adjustYposition = aEnable ;
       
   788 }
       
   789 int CStateMachine::getNumberOfPointers()
       
   790 {
       
   791     return KMaxNumberOfPointers ;
       
   792 }
       
   793