uifw/AvKon/animdllsrc/AknKeyEventMap.cpp
changeset 0 2f259fa3e83a
child 15 c52421ed5f07
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2005 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 "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:  An implementation of a configurable key translation map.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include "AknKeyEventMap.h"
       
    21 #include <e32std.h>
       
    22 #include <e32math.h>
       
    23 #include <barsc.h>
       
    24 #include <barsread.h>
       
    25 #include <bautils.h>
       
    26 #include "AknKeyResource.h"
       
    27 #include <aknkeyeventmap.rsg>
       
    28 #include "AknAnimLogger.h"
       
    29 #include "aknanimdllstd.h"
       
    30 
       
    31 // CONSTANTS
       
    32 #define STRIP_MODS  &0x0000FFFF
       
    33 #define GET_MODS    &0xFFFF0000
       
    34 
       
    35 // Key event map resource file.
       
    36 _LIT( KAknKeyTableRsc, "z:\\resource\\AknKeyEventMap.rsc" );
       
    37 
       
    38 // Publish & Subscribe device mode category.
       
    39 const TInt32 KUidWinservCategoryValue = 0x10003B20;
       
    40 
       
    41 // Publish & Subscribe device mode category as TUid.
       
    42 const TUid KUidWinservCategory = { KUidWinservCategoryValue };
       
    43 
       
    44 // Always pass policy.
       
    45 _LIT_SECURITY_POLICY_PASS(KAlwaysPassPolicy);
       
    46 
       
    47 // Only system application can access.
       
    48 _LIT_SECURITY_POLICY_S0(KSysapOnlyPolicy, 0x100058F3);
       
    49 
       
    50 // ============================ MEMBER FUNCTIONS ===============================
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CAknKeyEventMap::CAknKeyEventMap
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CAknKeyEventMap::CAknKeyEventMap(CAknAsynchTonePlayer& aSoundSession)
       
    57     : iDownEvents( KAknMaxComboKeys ), iUpEvents( KAknMaxComboKeys ), iSoundSession(aSoundSession)
       
    58     {    
       
    59     }
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // CAknKeyEventMap::ConstructL
       
    63 //
       
    64 // Initializes member variables, reads the default keytables from a resource 
       
    65 // file, instantiates P&S subscriber and opens the door for raw events.
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 void CAknKeyEventMap::ConstructL( MAnimGeneralFunctions* aFunctions )
       
    69     {
       
    70     iFunctions = aFunctions;
       
    71 
       
    72     if ( KAknMaxDeviceMode < 1 || KAknMaxDeviceMode > 15)
       
    73         {
       
    74         __AKNANIMLOGSTRING("CAknKeyEventMap::ConstructL ERROR: must have at least 1 and at most 15 device modes");
       
    75         User::Leave(KErrGeneral);
       
    76         }
       
    77 
       
    78     iCurrentDeviceMode = KAknModeDefault;
       
    79     iKeyBeacon.iKeyCode = EKeyNull;
       
    80     iKeyBeacon.iEventType = 0;
       
    81     iDownTimer = CPeriodic::New( CActive::EPriorityLow );
       
    82     iCombos = new (ELeave) RArray<RArray<TUint32>*>( KAknMaxComboKeys );
       
    83     
       
    84     iRepeatRate = KAknRepeatRate;
       
    85     iKeyPollInterval = static_cast<TTimeIntervalMicroSeconds32>(1000000./iRepeatRate);
       
    86     
       
    87     iConsume = EFalse;
       
    88     iIsCanceled = EFalse;
       
    89     
       
    90     iScanCodeIJustGenerated = -1;
       
    91     
       
    92     // Initialize keymap.
       
    93     const TAknKeyEvent nullEvent = { EKeyNull, EKeyNull, 0 };
       
    94     for ( TUint j = 0; j < KAknKeyMapRows; j++ )
       
    95         {
       
    96         for ( TUint i = 0; i < KAknKeyMapColumns; i++ )
       
    97             {
       
    98             iKeyMap[i][j] = nullEvent;
       
    99             }
       
   100         }
       
   101     
       
   102     // Load the default configuration.
       
   103     TRAPD( ierr, InitializeKeyTableFromResourceL( KAknKeyTableRsc ) );
       
   104     if ( ierr != KErrNone )
       
   105         {
       
   106         __AKNANIMLOGSTRING1( "Error initializing the key tables, %d", ierr );
       
   107         }
       
   108 
       
   109     if ( !IsKeyEventMapEnabled() )
       
   110         {
       
   111         return;
       
   112         }
       
   113     
       
   114     // Define Publish & Subscribe key
       
   115     TInt err = RProperty::Define( KUidWinservCategory, KAknPSDeviceMode, 
       
   116         RProperty::EInt, KAlwaysPassPolicy, KSysapOnlyPolicy );
       
   117     if ( err != KErrNone )
       
   118         {
       
   119         __AKNANIMLOGSTRING1("CAknKeyEventMap::ConstrucL() Problem defining The Key %d", err);
       
   120         }
       
   121 
       
   122     // Subscribe to Publish & Subscribe keys
       
   123     err = KErrNone;
       
   124     CAknKefSubscriber *sub = NULL;
       
   125     
       
   126     sub = CAknKefSubscriber::NewL( *this, KUidWinservCategory , KAknPSDeviceMode  );
       
   127     if ( sub )
       
   128         {        
       
   129         err = iKefSubscribers.Append( sub );
       
   130         if ( err != KErrNone )
       
   131             {
       
   132             delete sub;
       
   133             __AKNANIMLOGSTRING( "CAknKeyEventMap::ConstructL ERROR: device mode subscription failed." );
       
   134             // We could stop the boot here, but we can also continue, just without 
       
   135             // the device modes.
       
   136             }
       
   137         }
       
   138     }
       
   139 
       
   140 // -----------------------------------------------------------------------------
       
   141 // CAknKeyEventMap::~CAknKeyEventMap
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 CAknKeyEventMap::~CAknKeyEventMap()
       
   145     {
       
   146     __AKNANIMLOGSTRING("CAknKeyEventMap::Destructor entered.");
       
   147     
       
   148     if ( iCombos )
       
   149         {
       
   150         const TInt count = iCombos->Count();
       
   151         for ( TInt i = count - 1; i >= 0; i-- ) 
       
   152             {
       
   153             (*iCombos)[i]->Close();
       
   154             delete (*iCombos)[i];
       
   155             iCombos->Remove(i);
       
   156             }
       
   157         iCombos->Close();
       
   158         delete iCombos;
       
   159         }
       
   160     
       
   161     delete iDownTimer;
       
   162 
       
   163     iUpEvents.Close();   
       
   164     iDownEvents.Close();
       
   165     iRepeatRates.Close();
       
   166     
       
   167     iKefSubscribers.ResetAndDestroy();
       
   168     iKefSubscribers.Close();
       
   169     }
       
   170 
       
   171 // -----------------------------------------------------------------------------
       
   172 // CAknKeyEventMap::IsKeyEventMapEnabled
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 TBool CAknKeyEventMap::IsKeyEventMapEnabled() const
       
   176     {
       
   177     return iKeyEventMapEnabled;
       
   178     }
       
   179     
       
   180 // -----------------------------------------------------------------------------
       
   181 // CAknKeyEventMap::OfferRawEvent
       
   182 // 
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 TBool CAknKeyEventMap::OfferRawEvent( const TRawEvent& aRawEvent )
       
   186     {
       
   187     return OfferRawEvent(aRawEvent, EFalse);
       
   188     }    
       
   189     
       
   190 // -----------------------------------------------------------------------------
       
   191 // CAknKeyEventMap::OfferRawEvent
       
   192 // 
       
   193 // This is where the raw events end up in, and
       
   194 // where we have to decide what to do with them.
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 TBool CAknKeyEventMap::OfferRawEvent( const TRawEvent& aRawEvent, TBool aSilentEvent )    
       
   198     {
       
   199     const TBool downEvent = ( aRawEvent.Type() == TRawEvent::EKeyDown );
       
   200     const TBool upEvent = ( aRawEvent.Type() == TRawEvent::EKeyUp );
       
   201     
       
   202     //
       
   203     // Raw events created by this CAknKeyEventMap itself: pass them on.
       
   204     //
       
   205     if ( ( downEvent || upEvent ) && 
       
   206          ( aRawEvent.ScanCode() == iScanCodeIJustGenerated ) )
       
   207         {
       
   208         if ( downEvent )
       
   209             {
       
   210             // Add this scan code to iUpEvents so we can generate
       
   211             // the appropriate raw UPs when the key press is finished.
       
   212             __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent adding %x to iUpEvents", iScanCodeIJustGenerated);
       
   213             TInt err = iUpEvents.Append( iScanCodeIJustGenerated );
       
   214             if ( err != KErrNone )  // never happened
       
   215                 {
       
   216                 __AKNANIMLOGSTRING("CAknKeyEventMap::OfferRawEvent ERROR appending up event!");
       
   217                 }        
       
   218             }
       
   219     
       
   220         if ( upEvent )
       
   221             {
       
   222             // would be nice to .Remove() elements from iUpEvents here,
       
   223             // but that'd require another call to ResolveMapping(),
       
   224             //  -- .Remove() in CancelProcessingKeyPress() instead.
       
   225             }
       
   226             
       
   227         iScanCodeIJustGenerated = -1;
       
   228         return EFalse;  // not further processing for scan codes iJustGenerated.
       
   229         }       
       
   230         
       
   231     TInt err = KErrNone;
       
   232     iConsume = EFalse;  // very important to set this here.
       
   233     
       
   234     // log arrays
       
   235     for ( TInt i = 0 ; i < iDownEvents.Count() ; i++ )
       
   236         {
       
   237         __AKNANIMLOGSTRING2("CAknKeyEventMap::OfferRawEvent iDownEvents[%d] = %x", i, iDownEvents[i] );
       
   238         }
       
   239     for ( TInt i = 0 ; i < iUpEvents.Count() ; i++ )
       
   240         {
       
   241         __AKNANIMLOGSTRING2("CAknKeyEventMap::OfferRawEvent iUpEvents[%d] = %x", i, iUpEvents[i] );
       
   242         }
       
   243     
       
   244     // Down events
       
   245     if ( downEvent && aRawEvent.ScanCode() >= 0 )
       
   246         {
       
   247         iCurrentScanCode = aRawEvent.ScanCode(); 
       
   248         iPostMeOnUp.iKeyCode = EKeyNull;
       
   249         iPostMeOnUp.iEventType = 0;
       
   250         __AKNANIMLOGSTRING3( "CAknKeyEventMap::OfferRawEvent KeyDown scancode=%x mods=%x, we're in devicemode=%d", 
       
   251             iCurrentScanCode STRIP_MODS, iCurrentScanCode GET_MODS, iCurrentDeviceMode);
       
   252         
       
   253         // Combo support
       
   254         if ( iDownEvents.Count() < KAknMaxComboKeys )
       
   255             {
       
   256             err = iDownEvents.Append( aRawEvent.ScanCode() STRIP_MODS );
       
   257             if ( err != KErrNone )  // never happened
       
   258                 {
       
   259                 __AKNANIMLOGSTRING("CAknKeyEventMap::OfferRawEvent ERROR appending down event!");
       
   260                 }                
       
   261             }
       
   262         else 
       
   263             {
       
   264             // User is trying to press more simultaneous keys than supported.
       
   265             // We have no problem with that, just ignore it.
       
   266             }
       
   267         
       
   268         // Resolve mapping for this event and set is as the beacon.
       
   269         iKeyBeacon = ResolveMapping();
       
   270 
       
   271         // Launch a CPeriodic so the duration of the keypress can be known.  
       
   272         // There's only one timer; for combos, it measures the time starting
       
   273         // from the first DOWN event of the combo.  If usability troubles appear,
       
   274         // try re-starting the timer for each participating key in a combo
       
   275         // (by removing the test against iDownEvents.Count())
       
   276         if ( iDownEvents.Count() < 2 )
       
   277             {            
       
   278             iKeyPressDuration = 0.0;
       
   279             iDownTimer->Cancel();
       
   280             iIsCanceled = EFalse; // set this before Start()
       
   281             iDownTimer->Start( iKeyPollInterval, iKeyPollInterval, 
       
   282                 TCallBack( &KeyPressDuration, (TAny*) this ) );
       
   283             }
       
   284 
       
   285         if ( iKeyBeacon.iKeyCode > KAknKeyDisabled )
       
   286             {
       
   287             if ( ( iKeyBeacon.iEventType & KAknIsLongOnly ) )
       
   288                 {
       
   289                 // delayed posting of the short event when KAknIsLongOnly
       
   290                 iPostMeOnUp = iKeyBeacon;  
       
   291                 return iConsume;      // notice!  we're finished with this event.
       
   292                 }
       
   293             else
       
   294                 {
       
   295                 if ( ( iKeyBeacon.iEventType & KAknIsShortKey ) == EFalse )
       
   296                     {
       
   297                     PostEvent( EAknPostRaw );
       
   298                     }
       
   299                 else 
       
   300                     {
       
   301                     PostEvent( EAknPostKey );
       
   302                     }
       
   303                 }
       
   304             }       
       
   305         
       
   306         // Emit a keyclick.
       
   307         if ( !aSilentEvent && iKeyBeacon.iKeyCode != KAknKeyDisabled )
       
   308             {
       
   309             if ( iKeyBeacon.iKeyCode > KAknKeyDisabled )
       
   310                 {
       
   311                 iSoundSession.KeyPressed( iKeyBeacon.iKeyCode STRIP_MODS );
       
   312                 }
       
   313             else
       
   314                 {
       
   315                 iSoundSession.KeyPressed( aRawEvent.ScanCode() STRIP_MODS );
       
   316                 }
       
   317             }
       
   318         
       
   319         return iConsume; // this was set by ResolveMapping
       
   320         }
       
   321     
       
   322     //  Up events    
       
   323     if ( upEvent )
       
   324         {
       
   325         iCurrentScanCode = aRawEvent.ScanCode(); 
       
   326         __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent KeyUp scancode=%x",aRawEvent.ScanCode());
       
   327         
       
   328         // Check whether this up event finishes a keypress we've been handling.
       
   329         TInt finishesKeyPress = 
       
   330             iDownEvents.Find( aRawEvent.ScanCode() STRIP_MODS );
       
   331         __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent finishesKeypress index %d", finishesKeyPress);
       
   332         __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent Duration =%f",iKeyPressDuration);
       
   333 
       
   334         // We got an UP for a known DOWN
       
   335         if ( finishesKeyPress != KErrNotFound ) 
       
   336             {
       
   337             
       
   338             if ( iPostMeOnUp.iKeyCode > KAknKeyDisabled && !iIsLongKeyPress  )
       
   339                 {
       
   340                 iKeyBeacon = iPostMeOnUp;
       
   341                 if ( ( iKeyBeacon.iEventType & KAknIsShortKey ) == EFalse )
       
   342                     {
       
   343                     PostEvent( EAknPostRaw );
       
   344                     }
       
   345                 else 
       
   346                     {
       
   347                     PostEvent( EAknPostKey );
       
   348                     }
       
   349                 iPostMeOnUp.iKeyCode = EKeyNull;
       
   350                 iPostMeOnUp.iEventType = 0;
       
   351                 }
       
   352 
       
   353             iKeyBeacon = ResolveMapping();
       
   354 
       
   355             
       
   356             // Remove key from the down array
       
   357             iDownEvents.Remove( finishesKeyPress );
       
   358             
       
   359             // if it is mapped on the up array -> generate the up event
       
   360             TInt upKeyPressIndex = KErrNotFound;
       
   361             for ( TInt i = 0 ; i < iUpEvents.Count() ; i++ )
       
   362                 {
       
   363                 if ( (iUpEvents[i] STRIP_MODS) == ( iKeyBeacon.iKeyCode STRIP_MODS ) )
       
   364                     {
       
   365                     upKeyPressIndex = i;
       
   366                     break;
       
   367                     }
       
   368                 }
       
   369             
       
   370             if ( upKeyPressIndex != KErrNotFound )
       
   371                 {
       
   372                 iScanCodeIJustGenerated = iUpEvents[upKeyPressIndex];
       
   373                 TRawEvent rawEvent;
       
   374                 rawEvent.Set( TRawEvent::EKeyUp, iScanCodeIJustGenerated );
       
   375                 __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent POST RAW UP-EVENT for %x",iScanCodeIJustGenerated);
       
   376                 iFunctions->PostRawEvent( rawEvent ) ;
       
   377                 iUpEvents.Remove(upKeyPressIndex);
       
   378                 iConsume = ETrue;
       
   379                 }
       
   380                 
       
   381             if ( !iDownEvents.Count() )
       
   382                 {
       
   383                 CancelProcessingKeyPress();
       
   384                 }
       
   385 
       
   386             }
       
   387          else // finishesKeyPress == KErrNotFound
       
   388             {
       
   389             // probably a hardware/driver bug, in any case we're
       
   390             // confused now.
       
   391             __AKNANIMLOGSTRING("CAknKeyEventMap::OfferRawEvent INPUT IS CONFUSED: cancel key processing");            
       
   392             CancelProcessingKeyPress();
       
   393             }
       
   394         }
       
   395     
       
   396     return iConsume;
       
   397     }
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // CAknKeyEventMap::CancelProcessingKeyPress
       
   401 // -----------------------------------------------------------------------------
       
   402 
       
   403 void CAknKeyEventMap::CancelProcessingKeyPress()
       
   404     {
       
   405     iDownTimer->Cancel();
       
   406     iIsCanceled = ETrue;
       
   407     iDownEvents.Reset();
       
   408     
       
   409     // be sure to send out all raw upevents or CKeyTranslator
       
   410     // will think the key is still being pressed.
       
   411     TRawEvent rawEvent;    
       
   412     while ( iUpEvents.Count() > 0 )
       
   413         {
       
   414         iScanCodeIJustGenerated = iUpEvents[0];
       
   415         rawEvent.Set( TRawEvent::EKeyUp, iScanCodeIJustGenerated );
       
   416         __AKNANIMLOGSTRING1("CAknKeyEventMap::CancelProcessingKeyPress POST RAW UP-EVENT for %x",iScanCodeIJustGenerated);
       
   417         iFunctions->PostRawEvent( rawEvent ) ;
       
   418         iUpEvents.Remove(0);
       
   419         }
       
   420         
       
   421     iUpEvents.Reset();
       
   422     iRepeats = 0;
       
   423     iKeyPressDuration = 0.0;
       
   424     iIsLongKeyPress = EFalse;                
       
   425     __AKNANIMLOGSTRING1("CAknKeyEventMap::CancelProcessingKeyPress Last beacon sent: %x", iKeyBeacon.iKeyCode);
       
   426     iKeyBeacon.iKeyCode = EKeyNull;
       
   427     iKeyBeacon.iEventType = 0;
       
   428     }
       
   429     
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CAknKeyEventMap::HandlePropertyChangedL
       
   433 //
       
   434 // Callback for Publish & Subscribe key events, it tracks
       
   435 // the device mode changes for internal use.
       
   436 // -----------------------------------------------------------------------------
       
   437 //
       
   438 void CAknKeyEventMap::HandlePropertyChangedL( 
       
   439         const TUid& aCategory, 
       
   440         const TUint aKey )
       
   441     {
       
   442     TInt keyValue( 0 );
       
   443     TInt err = KErrNone;
       
   444     err = RProperty::Get( aCategory, aKey, keyValue );
       
   445     if ( err == KErrNone )
       
   446         {
       
   447         switch( aKey )
       
   448             {
       
   449             case KAknPSDeviceMode:
       
   450                 {
       
   451                 __AKNANIMLOGSTRING1("CAknKeyEventMap::HandlePropertyChanged VALUE: %d",aKey);
       
   452                 iCurrentDeviceMode = keyValue;
       
   453                 
       
   454                 const TInt count = iRepeatRates.Count();
       
   455                 TUint16 currentMode = iCurrentDeviceMode; 
       
   456                 for ( TInt ii = 0; ii < count; ii++ )
       
   457                     {
       
   458                     const TAknKeyRepeatRate& repeatRate = iRepeatRates[ ii ];
       
   459                     
       
   460                     if ( ( currentMode & repeatRate.iModeMask ) == 
       
   461                          repeatRate.iMode )
       
   462                         {
       
   463                         SetRepeatRate( repeatRate.iRate );
       
   464                         ii = count; // exit the loop.
       
   465                         }
       
   466                     }
       
   467                 }
       
   468                 break;
       
   469             default:
       
   470                 {
       
   471                 __AKNANIMLOGSTRING1("CAknKeyEventMap::HandlePropertyChanged GOT A P&S VALUE: %d",aKey);
       
   472                 }
       
   473                 break;
       
   474             }
       
   475         }
       
   476     }
       
   477 
       
   478 // -----------------------------------------------------------------------------
       
   479 // CAknKeyEventMap::InitializeKeyTableFromResourceL
       
   480 // -----------------------------------------------------------------------------
       
   481 //
       
   482 void CAknKeyEventMap::InitializeKeyTableFromResourceL(
       
   483         const TDesC& aConfigFile ) 
       
   484     {
       
   485     // Get a handle for the resource file.
       
   486     RFs fsSession;
       
   487     CleanupClosePushL( fsSession );
       
   488     TInt err = fsSession.Connect();
       
   489     if ( err != KErrNone )
       
   490         {
       
   491         User::Leave( err );
       
   492         }
       
   493     RResourceFile resourceFile;
       
   494     CleanupClosePushL( resourceFile );
       
   495     
       
   496     // Make sure we have the resource file.
       
   497     if ( BaflUtils::FileExists( fsSession, aConfigFile ) )
       
   498         {
       
   499         resourceFile.OpenL( fsSession, aConfigFile );
       
   500         }
       
   501     else
       
   502         {
       
   503         __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL: no configuration file!");
       
   504         CleanupStack::PopAndDestroy(); // CleanupClosePushL.
       
   505         CleanupStack::PopAndDestroy(); // CleanupClosePushL.
       
   506         return;
       
   507         }
       
   508     
       
   509     // Confirm signature of the resource file.
       
   510     resourceFile.ConfirmSignatureL( 0 );
       
   511     
       
   512     // Now just get the resource chunk into a heap buffer and give it to a 
       
   513     // TResourceReader.
       
   514     HBufC8* res;
       
   515     res = resourceFile.AllocReadLC( R_AVKON_KEY_EVENT_MAP );
       
   516     
       
   517     TResourceReader theReader;
       
   518     theReader.SetBuffer( res );
       
   519     
       
   520     // Check version field.
       
   521     const TUint16 version = theReader.ReadUint16();
       
   522     if ( version != KAknKeyEventVersion1 )
       
   523         {
       
   524         __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL: key event map disabled!");
       
   525         CleanupStack::PopAndDestroy( res );
       
   526         CleanupStack::PopAndDestroy(); // CleanupClosePushL.
       
   527         CleanupStack::PopAndDestroy(); // CleanupClosePushL.
       
   528         return;
       
   529         }
       
   530     
       
   531     iKeyEventMapEnabled = ETrue;
       
   532     theReader.ReadUint16(); // read flags, not in use yet.
       
   533 
       
   534     // Read repeat rates.
       
   535     const TUint count = theReader.ReadUint16();
       
   536     for ( TInt idx = 0; idx < count; idx++ )
       
   537         {
       
   538         TUint16 mode = theReader.ReadUint16();
       
   539         TUint16 modeMask = theReader.ReadUint16();
       
   540         TUint8 rate = theReader.ReadUint8();
       
   541         
       
   542         const TAknKeyRepeatRate repeatRate = 
       
   543             {
       
   544             mode,
       
   545             modeMask,
       
   546             rate
       
   547             };
       
   548         
       
   549         User::LeaveIfError( iRepeatRates.Append( repeatRate ) );
       
   550         }
       
   551 
       
   552     // Parses the resource data
       
   553     CAknKeyResourceArray* keyResourceArray = CAknKeyResourceArray::NewLC();
       
   554     CArrayPtrFlat<CAknKeyResource>* keyEvents = NULL;
       
   555     keyEvents = keyResourceArray->GetKeyEventsL( theReader );
       
   556     
       
   557     // At this point we have all the key event info; just put it in its place
       
   558     // in iKeyMap and iCombos.
       
   559     for ( TUint i = 0; i < (TUint)keyEvents->Count(); i++ )
       
   560         {
       
   561         CAknKeyResource* keyEvent = keyEvents->At(i);
       
   562         
       
   563         if ( keyEvent->GetScanCodes().Count() > 0 )
       
   564             {
       
   565             if ( (keyEvent->GetKeyCodes().Count() == keyEvent->GetDeviceModes().Count())
       
   566                  && (keyEvent->GetKeyCodes().Count() == keyEvent->GetEventTypes().Count()))
       
   567                 {
       
   568                 for ( TUint j = 0; 
       
   569                       j < (TUint)keyEvent->GetKeyCodes().Count(); 
       
   570                       j++ )
       
   571                     {            
       
   572                     TUint16 thisMode = keyEvent->GetDeviceModes().At(j);
       
   573                     RArray<TUint> theseModes;
       
   574                     CleanupClosePushL( theseModes );
       
   575                     
       
   576                     ResolveDeviceModeL( 
       
   577                         theseModes, 
       
   578                         keyEvent->GetDeviceModes().At(j) );
       
   579                     
       
   580                     TUint16 thisType = keyEvent->GetEventTypes().At(j);
       
   581                     for ( TUint k = 0; k < (TUint)theseModes.Count(); k++ )
       
   582                         {
       
   583                         TAknKeyDefinition thisKey;
       
   584                         thisKey.iScanCodes = &(keyEvent->GetScanCodes());
       
   585                         thisKey.iDeviceMode = theseModes[k];
       
   586                         thisKey.iKeyCode = keyEvent->GetKeyCodes().At(j);
       
   587                         thisKey.iEventType = thisType;
       
   588                         
       
   589                         TRAPD( error, SetKeyMappingL( thisKey ) );
       
   590                         if (error != KErrNone)
       
   591                             {
       
   592                             __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL ERROR setting a mapping");
       
   593                             }
       
   594                         }
       
   595                     
       
   596                     CleanupStack::PopAndDestroy( &theseModes );
       
   597                     }
       
   598                 }
       
   599             else
       
   600                 {
       
   601                 // Keyboard configuration is erroneous!
       
   602                 // When multiple keycodes have been defined, they must have
       
   603                 // an associated device mode, etc.
       
   604                 __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL ERROR: inconsistent data in KEY_EVENT" );
       
   605                 User::Leave( KErrGeneral );
       
   606                 }
       
   607             }
       
   608         else 
       
   609             {
       
   610             // Error. No scancodes for the key event.
       
   611             User::Leave( KErrGeneral );
       
   612             }    
       
   613         }
       
   614     
       
   615     // All done! The maps are now ready for use!
       
   616     CleanupStack::PopAndDestroy( 4 ); // keyResourceArray, res, 
       
   617                                       // &resourceFile, &fsSession
       
   618     }
       
   619     
       
   620 // -----------------------------------------------------------------------------
       
   621 // CAknKeyEventMap::SetRepeatRate
       
   622 // -----------------------------------------------------------------------------
       
   623 //
       
   624 void CAknKeyEventMap::SetRepeatRate( TUint8 aRepeatRate )
       
   625     {
       
   626     if ( iRepeatRate > 0 && iRepeatRate < 32 )
       
   627         {        
       
   628         iRepeatRate = aRepeatRate;
       
   629         }
       
   630     }
       
   631 
       
   632 // -----------------------------------------------------------------------------
       
   633 // CAknKeyEventMap::SetKeyMappingL
       
   634 //
       
   635 // Sets the keycodes in iKeyMap and iCombos for one device mode.
       
   636 // -----------------------------------------------------------------------------
       
   637 //
       
   638 void CAknKeyEventMap::SetKeyMappingL( const TAknKeyDefinition& aKey )
       
   639     {
       
   640     if ( aKey.iScanCodes->Count() == 1 )
       
   641         {        
       
   642         // Normal (=single key) mapping
       
   643         if ( (aKey.iEventType & KAknTypeShort) == KAknTypeShort )
       
   644             {
       
   645             // handle anykey definition for single presses.
       
   646             if ( aKey.iScanCodes->At(0) == KAknAnyKey)
       
   647                 {
       
   648                 for (TUint j = 0; j < KAknMaxScanCode; j++) 
       
   649                     {
       
   650                     iKeyMap[j][aKey.iDeviceMode].iShortPress = 
       
   651                         aKey.iKeyCode;
       
   652                     iKeyMap[j][aKey.iDeviceMode].iLongPress = 
       
   653                         aKey.iKeyCode;
       
   654                     iKeyMap[j][aKey.iDeviceMode].iEventType |=
       
   655                         ResolveEventType ( aKey.iEventType );
       
   656                     }
       
   657                 }
       
   658             else 
       
   659                 {                                
       
   660                 // default is to set iLongPress to same as iShortPress, which in 
       
   661                 // practice means that the default behavior for long keypresses is
       
   662                 // to repeat.
       
   663                 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iShortPress = 
       
   664                     aKey.iKeyCode;
       
   665                 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iLongPress = 
       
   666                     aKey.iKeyCode;
       
   667                 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iEventType |= 
       
   668                     ResolveEventType( aKey.iEventType );
       
   669                 }
       
   670             }
       
   671         else if ( ((aKey.iEventType & KAknTypeLong) == KAknTypeLong) ||
       
   672                   ((aKey.iEventType & KAknTypeLongOnly) == KAknTypeLongOnly))
       
   673             {
       
   674             iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iLongPress  = 
       
   675                 aKey.iKeyCode;
       
   676             iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iEventType |= 
       
   677                 ResolveEventType( aKey.iEventType );
       
   678             }
       
   679         else
       
   680             {
       
   681             // Ignored.
       
   682             }
       
   683         }
       
   684     else
       
   685         {
       
   686         // Combo mapping
       
   687         RArray<TUint32>* newCombo = 
       
   688             new (ELeave) RArray<TUint32>( KAknMaxComboKeys );
       
   689         TUint i;
       
   690         TInt err = KErrNone;
       
   691         for ( i = 0; i < aKey.iScanCodes->Count(); i++ ) 
       
   692             {           
       
   693             err = newCombo->Append( aKey.iScanCodes->At(i) );
       
   694             if ( err != KErrNone ) 
       
   695                 {
       
   696                 User::Leave( err );  // we're trapped, just bail out.
       
   697                 }
       
   698             }
       
   699         
       
   700         // For combos, the device mode information is encoded in to the
       
   701         // upper 16 bits of the Key Code value.    
       
   702         TUint32 keyMode = aKey.iKeyCode + ( aKey.iDeviceMode << 16 );
       
   703         newCombo->Insert( keyMode, 0 );
       
   704        
       
   705         TUint32 eventType = ResolveEventType( aKey.iEventType );
       
   706         newCombo->Insert( eventType, 1 );
       
   707 
       
   708         err = iCombos->Append( newCombo );
       
   709         if ( err != KErrNone )
       
   710             {
       
   711             User::Leave( KErrNone );
       
   712             }  
       
   713         }
       
   714     }
       
   715 
       
   716 // -----------------------------------------------------------------------------
       
   717 // CAknKeyEventMap::ResolveEventType
       
   718 //
       
   719 // A conversion between the eventtype representation in the resource file
       
   720 // and iKeyMap.
       
   721 // -----------------------------------------------------------------------------
       
   722 
       
   723 TUint8 CAknKeyEventMap::ResolveEventType( TUint8 aEventType )
       
   724     {
       
   725     TUint8 result = 0;
       
   726     
       
   727     if ( (aEventType & (KAknTypeLongOnly)) == KAknTypeLongOnly )
       
   728         {
       
   729         result |= KAknIsLongOnly;
       
   730         result |= KAknIsLongPress;
       
   731         if ( (aEventType & KAknTypeKey) )
       
   732             {
       
   733             result |= KAknIsLongKey;
       
   734             }
       
   735         }
       
   736     else if ( (aEventType & KAknTypeLong) == KAknTypeLong )
       
   737         {
       
   738         result |= KAknIsLongPress;
       
   739         if ( (aEventType & KAknTypeKey) == KAknTypeKey )
       
   740             {
       
   741             result |= KAknIsLongKey;
       
   742             }
       
   743         }
       
   744     else if ( (aEventType & KAknTypeShort) == KAknTypeShort )
       
   745         {
       
   746         result = 0; // to be 101% sure
       
   747         if ( (aEventType & KAknTypeKey) == KAknTypeKey )
       
   748             {
       
   749             result |= KAknIsShortKey;
       
   750             }
       
   751         }
       
   752 
       
   753     return result;
       
   754     }
       
   755     
       
   756 // -----------------------------------------------------------------------------
       
   757 // CAknKeyEventMap::ResolveDeviceModeLC
       
   758 //
       
   759 // Given a TUint specifying a device mode, this function figures out 
       
   760 // which rows of the iKeyMap are affected by a mapping. Only used in 
       
   761 // setting up the key tables, not when querying data from them (just use 
       
   762 // iCurrentDeviceMode then).
       
   763 // -----------------------------------------------------------------------------
       
   764 //
       
   765 void CAknKeyEventMap::ResolveDeviceModeL( 
       
   766         RArray<TUint>& aModes, 
       
   767         TUint16 aMode )
       
   768     {
       
   769     TInt err;   
       
   770     TUint16 myMode = aMode;
       
   771     
       
   772     for ( TUint k = 0; k < KAknKeyMapRows; k++ )
       
   773         {
       
   774         // The loop index is now tested against aMode to see whether
       
   775         // there should be a non-null value in iKeyMap.
       
   776         
       
   777         if ( k == myMode )
       
   778             {            
       
   779             err = aModes.InsertInOrder( k );
       
   780             if ( err != KErrNone && err != KErrAlreadyExists )
       
   781                 {
       
   782                 User::Leave( err );  // we can't initialize the table.  fail.
       
   783                 }
       
   784             }
       
   785         }
       
   786     }
       
   787 
       
   788 // -----------------------------------------------------------------------------
       
   789 // CAknKeyEventMap::GetKeyMapping
       
   790 //
       
   791 // Returns mappings from iKeyMap.
       
   792 // -----------------------------------------------------------------------------
       
   793 //
       
   794 TAknKeyBeacon CAknKeyEventMap::GetKeyMapping( 
       
   795         TUint16 aScanCode, 
       
   796         TUint16 aDeviceMode )
       
   797     {
       
   798     TAknKeyBeacon mapValue = { EKeyNull, 0 };      
       
   799     
       
   800     if ( aScanCode < KAknKeyMapColumns && aDeviceMode < KAknKeyMapRows )
       
   801         {
       
   802         // Look up the mode specific value, if any
       
   803         if ( iIsLongKeyPress == EFalse )
       
   804             {
       
   805             mapValue.iKeyCode = iKeyMap[aScanCode][aDeviceMode].iShortPress;
       
   806             }
       
   807         else
       
   808             {
       
   809             mapValue.iKeyCode = iKeyMap[aScanCode][aDeviceMode].iLongPress;
       
   810             }
       
   811 
       
   812         mapValue.iEventType = iKeyMap[aScanCode][aDeviceMode].iEventType;        
       
   813             
       
   814         // With this, we always return the default mapping (if any)
       
   815         // unless a mode-specific mapping was found.  
       
   816         if ( !mapValue.iKeyCode )
       
   817             {
       
   818             if ( iIsLongKeyPress == EFalse )
       
   819                 {
       
   820                 mapValue.iKeyCode = iKeyMap[aScanCode][ KAknModeDefault ].iShortPress; 
       
   821                 }
       
   822             else
       
   823                 {
       
   824                 mapValue.iKeyCode = iKeyMap[aScanCode][ KAknModeDefault ].iLongPress;
       
   825                 }
       
   826             mapValue.iEventType = iKeyMap[aScanCode][ KAknModeDefault ].iEventType;        
       
   827             }
       
   828         }
       
   829     return mapValue;
       
   830     }
       
   831 
       
   832 // -----------------------------------------------------------------------------
       
   833 // CAknKeyEventMap::GetComboMapping
       
   834 //
       
   835 // Returns mappings from iCombos.
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 TAknKeyBeacon CAknKeyEventMap::GetComboMapping( 
       
   839         RArray<TUint32>& aComboCandidate )
       
   840     {
       
   841     TAknKeyBeacon mapValue = { EKeyNull, 0 };        
       
   842     
       
   843     TUint i;
       
   844     TUint j;
       
   845     
       
   846     // First we check the first index of aComboCandidate
       
   847     // against the second index (= first scancode) of all combo
       
   848     // arrays in iCombos. If they match, then the i'th combo
       
   849     // array in iCombos could match aComboCandidate.
       
   850     //
       
   851     // iCombos[i][0] contains the key code that is to be returned for a 
       
   852     // succesful mapping, which introduces the offset-by-one in the following 
       
   853     // loops/lookups.also included in [i][0] are the device mode info and the 
       
   854     // event type info, both encoded into the upper 16 bits of iCombos[i][0].
       
   855     
       
   856     RArray<TUint> possibleMatch;  //  iCombos indices that might match
       
   857     for (i = 0; i < iCombos->Count(); i++) 
       
   858         {
       
   859         if ( (*(*iCombos)[i])[2] == aComboCandidate[0] && 
       
   860              ((*iCombos)[i])->Count()-2 == aComboCandidate.Count() ) 
       
   861             {
       
   862             possibleMatch.Append(i);
       
   863             __AKNANIMLOGSTRING1("CAknKeyEventMap::GetComboMapping ComboCandidate might hit iCombos[%d]",i);
       
   864             }                    
       
   865         }
       
   866     
       
   867     // If we have possibleMatches, then we just check whether any of
       
   868     // them matches aComboCandidate precisely. For the first match,
       
   869     // we return the keyvalue from the first element of the matching
       
   870     // combo array.
       
   871     if ( possibleMatch.Count() )
       
   872         {
       
   873         TInt8 isAMatch = -1;
       
   874         for ( i = 0; i < possibleMatch.Count() && isAMatch < 0; i++ ) 
       
   875             {
       
   876             // If isAMatch doesn't go to -1 within this loop, 
       
   877             // then we got a match.
       
   878             isAMatch = possibleMatch[i]; 
       
   879             for ( j = 2; j < (*(*iCombos)[possibleMatch[i]]).Count(); j++ ) 
       
   880                 {
       
   881                 // Try to find all scan codes of the current event 
       
   882                 // in a combo definition.
       
   883                 // NOTE: the order of the remaining scancodes is not matched,
       
   884                 // as long as the first scancode is OK, the others can come in 
       
   885                 // any order.
       
   886                 TInt err = KErrNotFound;
       
   887                 for ( TInt f = (*(*iCombos)[possibleMatch[i]]).Count()-1; f >= 0 ; f-- )
       
   888                     {
       
   889                     if ( (*(*iCombos)[possibleMatch[i]])[f] == aComboCandidate[j-2] )
       
   890                         {
       
   891                         err = f;
       
   892                         break;
       
   893                         }
       
   894                     }
       
   895                 
       
   896                 
       
   897                 // err < 2 must be discarded, because the first two elements are
       
   898                 // used for device mode & event type data.
       
   899                 if ( err == KErrNotFound || err < 2)
       
   900                     {
       
   901                     // If a scan code cannot be found, this possibleMatch is 
       
   902                     // not a real match.
       
   903                     isAMatch = -1;
       
   904                     }
       
   905                 }
       
   906             
       
   907             // If we get this far, a matching combination of keys has been 
       
   908             // found. Still need to check that the combo type (long/short) and 
       
   909             // the active device mode for this combo match those of the current
       
   910             // event.
       
   911             
       
   912             TUint16 comboMode = ((*(*iCombos)[possibleMatch[i]])[0] GET_MODS) >> 16;
       
   913             TUint16 comboType = ((*(*iCombos)[possibleMatch[i]])[1]);
       
   914             
       
   915             // If ..
       
   916             //    a matching set of scan codes was found,
       
   917             //    but it fails the long/short test,
       
   918             //    or it's defined for another device mode
       
   919             if ( isAMatch > -1 && 
       
   920                  ( iIsLongKeyPress && (!(comboType & KAknIsLongPress)  ) || 
       
   921                    ( ( iCurrentDeviceMode != comboMode ) && ( comboMode != KAknModeDefault ) ) ) )
       
   922                 {
       
   923                 isAMatch = -1;
       
   924                 }
       
   925             }
       
   926         
       
   927         if ( isAMatch > -1  && isAMatch < iCombos->Count() )
       
   928             {
       
   929             // The correct return value can be found from the isAMatch'th 
       
   930             // combo-mapping's first element.
       
   931             mapValue.iKeyCode = (*(*iCombos)[isAMatch])[0] STRIP_MODS;
       
   932             mapValue.iEventType = (*(*iCombos)[isAMatch])[1];
       
   933             __AKNANIMLOGSTRING1("CAknKeyEventMap::GetComboMapping ComboCandidate DID hit iCombos[%d]", isAMatch);
       
   934             __AKNANIMLOGSTRING1("CAknKeyEventMap::GetComboMapping mapValue = %d", mapValue.iKeyCode);
       
   935             }
       
   936         }
       
   937     else 
       
   938         {
       
   939         mapValue.iKeyCode = EKeyNull;
       
   940         mapValue.iEventType = 0 ;
       
   941         }
       
   942     possibleMatch.Close();
       
   943     return mapValue;
       
   944     }
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 // CAknKeyEventMap::ResolveMapping
       
   948 // 
       
   949 // A little macro for figuring out how to map the current scan code.  
       
   950 // -----------------------------------------------------------------------------
       
   951 //
       
   952 TAknKeyBeacon CAknKeyEventMap::ResolveMapping()
       
   953     {
       
   954     TAknKeyBeacon keyBeacon = 
       
   955     {
       
   956         EKeyNull, 0 
       
   957     };
       
   958     
       
   959     if ( iDownEvents.Count() > 1 && iDownEvents.Count() <= KAknMaxComboKeys ) 
       
   960         {
       
   961         // check that the current key is not disabled in this mode
       
   962         // if it is, then any combo containing this key must be 
       
   963         // blocked.
       
   964         TAknKeyBeacon tmp = GetKeyMapping( 
       
   965             iCurrentScanCode STRIP_MODS, iCurrentDeviceMode);
       
   966         
       
   967         if (tmp.iKeyCode != KAknKeyDisabled)
       
   968             {            
       
   969             keyBeacon = GetComboMapping( iDownEvents );
       
   970 
       
   971             // If we do not find combo, then try to map a single key.
       
   972             if ( keyBeacon.iKeyCode == EKeyNull )
       
   973                 {
       
   974                 __AKNANIMLOGSTRING( "CAknKeyEventMap::ResolveMapping Combo not found. Trying to get single." );
       
   975                 keyBeacon = GetKeyMapping( 
       
   976                     iCurrentScanCode STRIP_MODS, iCurrentDeviceMode );
       
   977                 }
       
   978             }
       
   979         else
       
   980             {
       
   981             __AKNANIMLOGSTRING("CAknKeyEventMap::ResolveMapping Ignoring combo because component is disabled");
       
   982             keyBeacon.iKeyCode = KAknKeyDisabled;
       
   983             keyBeacon.iEventType = 0;
       
   984             }
       
   985         }
       
   986     else if ( iDownEvents.Count() == 1 )
       
   987         {
       
   988         keyBeacon = GetKeyMapping( 
       
   989             iCurrentScanCode STRIP_MODS, iCurrentDeviceMode );
       
   990         }
       
   991     
       
   992     // Always consume succesful mappings, including EKeyDisabled
       
   993     if ( keyBeacon.iKeyCode != EKeyNull )
       
   994         {
       
   995         iConsume = ETrue;
       
   996         __AKNANIMLOGSTRING1( "CAknKeyEventMap::ResolveMapping mapping found: %x", keyBeacon.iKeyCode );
       
   997         }
       
   998     else
       
   999         {
       
  1000         __AKNANIMLOGSTRING( "CAknKeyEventMap::ResolveMapping mapping not found" );
       
  1001         }
       
  1002     
       
  1003     return keyBeacon;
       
  1004     }
       
  1005 
       
  1006 // -----------------------------------------------------------------------------
       
  1007 // CAknKeyEventMap::KeyPressDuration
       
  1008 //
       
  1009 // Callback for iDownTimer, used to distinguish between short and 
       
  1010 // long key presses and to handle repeats.
       
  1011 // -----------------------------------------------------------------------------
       
  1012 //
       
  1013 TInt CAknKeyEventMap::KeyPressDuration( TAny* aSelf )
       
  1014     {
       
  1015     if (aSelf != NULL)
       
  1016         {
       
  1017         CAknKeyEventMap* self = reinterpret_cast<CAknKeyEventMap*>(aSelf);
       
  1018         
       
  1019         self->iKeyPressDuration += ((TReal32)self->iKeyPollInterval.Int())/1e6;
       
  1020         
       
  1021         // Distinguish between short and long key presses.
       
  1022         if ( self->iKeyPressDuration < KAknKeyLongThreshold )
       
  1023             {
       
  1024             // nothing to do.  if combo duration measurement is changed
       
  1025             // so that each participating key resets the timer, then
       
  1026             // un-comment the following lines:
       
  1027             // self->iIsLongKeyPress = EFalse;
       
  1028             // self->iKeyBeacon = self->ResolveMapping();
       
  1029             }
       
  1030         else 
       
  1031             {            
       
  1032             // Keypress turned out to be a long one
       
  1033             if ( ! self->iIsLongKeyPress && ! self->iIsCanceled ) 
       
  1034                 {
       
  1035                 self->iIsLongKeyPress = ETrue;
       
  1036                 self->iKeyBeacon = self->ResolveMapping();
       
  1037     
       
  1038                 // post the KAknTypeLongOnly event
       
  1039                 if ( self->iKeyBeacon.iKeyCode > KAknKeyDisabled
       
  1040                     && (self->iKeyBeacon.iEventType & KAknIsLongPress))
       
  1041                     {
       
  1042                     if ( (self->iKeyBeacon.iEventType & KAknIsLongKey ) ) 
       
  1043                         {
       
  1044                         self->PostEvent( EAknPostKey );
       
  1045                         }
       
  1046                     else  
       
  1047                         {
       
  1048                         self->PostEvent( EAknPostRaw );
       
  1049                         }
       
  1050                     }
       
  1051                 }
       
  1052             }
       
  1053         
       
  1054         // Handle repeats.
       
  1055         if ( self->iKeyPressDuration >= KAknKeyLongThreshold && 
       
  1056              self->iKeyBeacon.iKeyCode > KAknKeyDisabled ) 
       
  1057             {
       
  1058             if ( ( self->iKeyBeacon.iEventType & KAknIsLongKey ) )
       
  1059                 {
       
  1060                 self->iRepeats++;  // perhaps don't do this?
       
  1061                 self->PostEvent( EAknPostKey );
       
  1062                 }
       
  1063             else
       
  1064                 {
       
  1065                 __AKNANIMLOGSTRING("CAknKeyEventMap::KeyPressDuration RAW repeat not sent (CKeyTranslator handles that)");   
       
  1066                 }
       
  1067             }
       
  1068         
       
  1069         if ( self->iIsCanceled )
       
  1070             {
       
  1071             self->iDownTimer->Cancel();
       
  1072             }
       
  1073         }
       
  1074     return KErrNone;
       
  1075     } 
       
  1076 
       
  1077 // -----------------------------------------------------------------------------
       
  1078 // CAknKeyEventMap::PostEvent
       
  1079 // -----------------------------------------------------------------------------
       
  1080 
       
  1081 void CAknKeyEventMap::PostEvent(TUint aType) 
       
  1082     {
       
  1083     switch ( aType )
       
  1084         {
       
  1085         case EAknPostKey:
       
  1086             TKeyEvent keyEvent;
       
  1087             keyEvent.iCode = iKeyBeacon.iKeyCode;
       
  1088             keyEvent.iScanCode = iCurrentScanCode STRIP_MODS;
       
  1089             keyEvent.iRepeats = iRepeats;
       
  1090             keyEvent.iModifiers = iCurrentScanCode GET_MODS; 
       
  1091             iFunctions->PostKeyEvent(keyEvent);
       
  1092             __AKNANIMLOGSTRING1( "CAknKeyEventMap::PostEvent() POST KEY code=%x", keyEvent.iCode);
       
  1093             
       
  1094             break;        
       
  1095         
       
  1096         case EAknPostRaw:
       
  1097         default:
       
  1098             TRawEvent rawEvent;
       
  1099             rawEvent.Set(TRawEvent::EKeyDown, (iCurrentScanCode GET_MODS) + iKeyBeacon.iKeyCode );
       
  1100             iScanCodeIJustGenerated = rawEvent.ScanCode();
       
  1101             __AKNANIMLOGSTRING1( "CAknKeyEventMap::PostEvent() POST RAW scancode=%x", rawEvent.ScanCode());
       
  1102             iFunctions->PostRawEvent( rawEvent );
       
  1103             break;
       
  1104         }
       
  1105     iConsume = ETrue;
       
  1106     }
       
  1107     
       
  1108 
       
  1109 
       
  1110 // End of File