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