bluetoothengine/bthid/keyboard/src/keyboard.cpp
changeset 0 f63038272f30
child 14 f7fbeaeb166a
child 17 f05641c183ff
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2004 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:  This is the implementation of application class
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <e32svr.h>
       
    21 #include <w32std.h>
       
    22 #include <coedef.h>
       
    23 #include <eiksvdef.h>
       
    24 #include <apgcli.h>
       
    25 #include <apgtask.h>
       
    26 #include <apacmdln.h>
       
    27 #include <e32property.h>
       
    28 
       
    29 #include "hidtranslate.h"
       
    30 #include "finder.h"
       
    31 #include "keyboard.h"
       
    32 #include "layoutmgr.h"
       
    33 #include "debug.h"
       
    34 #include "timeouttimer.h"
       
    35 #include "layoututils.h"
       
    36 #include "bthidPsKey.h"
       
    37 
       
    38 // ----------------------------------------------------------------------
       
    39 
       
    40 // Application UIDs for finding window groups.
       
    41 const TInt KIdleAppUid = 0x102750f0;
       
    42 const TInt KPhoneAppUid = 0x100058b3;
       
    43 const TInt KMenuAppUid = 0x101f4cd2;
       
    44 const TInt KSysApUid = 0x100058f3;
       
    45 const TInt KActiveNotesUid = 0x10281a31;
       
    46 const TInt KMessagingUid = 0x100058C5;
       
    47 const TInt KServicesUid = 0x10008D39;
       
    48 //const TInt KMultimediaMenuUid = 0x10281cfb;
       
    49 
       
    50 // Key repeat parameters to be configured
       
    51 const TInt KRepeatEndTimeout = 5000000; // 5 seconds
       
    52 
       
    53 const TInt KKeyRepeatDelay = 500000;
       
    54 const TInt KKeyRepeatInterval = 75000;
       
    55 _LIT(KAppName, "PaintCursor.exe");
       
    56 //----------------------------------------------------------------------------
       
    57 // CHidKeyboardDriver::CHidKeyboardDriver
       
    58 //----------------------------------------------------------------------------
       
    59 //
       
    60 CHidKeyboardDriver::CHidKeyboardDriver(MDriverAccess* aGenericHid) :
       
    61     iDriverState(EUninitialised), iGenericHid(aGenericHid), iMmKeyDown(0)
       
    62     {
       
    63         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::CHidKeyboardDriver(0x%08x)"), aGenericHid));
       
    64     }
       
    65 
       
    66 //----------------------------------------------------------------------------
       
    67 // CHidKeyboardDriver::NewLC
       
    68 //----------------------------------------------------------------------------
       
    69 //
       
    70 CHidKeyboardDriver* CHidKeyboardDriver::NewLC(MDriverAccess* aGenericHid)
       
    71     {
       
    72         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::NewLC(0x%08x)"), aGenericHid));
       
    73     CHidKeyboardDriver* self = new (ELeave) CHidKeyboardDriver(aGenericHid);
       
    74     CleanupStack::PushL(self);
       
    75     self->ConstructL();
       
    76     return self;
       
    77     }
       
    78 
       
    79 //----------------------------------------------------------------------------
       
    80 // CHidKeyboardDriver::NewL
       
    81 //----------------------------------------------------------------------------
       
    82 //
       
    83 CHidKeyboardDriver* CHidKeyboardDriver::NewL(MDriverAccess* aGenericHid)
       
    84     {
       
    85     CHidKeyboardDriver* self = CHidKeyboardDriver::NewLC(aGenericHid);
       
    86     CleanupStack::Pop();
       
    87     return self;
       
    88     }
       
    89 
       
    90 //----------------------------------------------------------------------------
       
    91 // CHidKeyboardDriver::ConstructL
       
    92 //----------------------------------------------------------------------------
       
    93 //
       
    94 void CHidKeyboardDriver::ConstructL()
       
    95     {
       
    96         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver{0x%08x}::ConstructL()"), this));
       
    97 
       
    98     User::LeaveIfNull(iGenericHid);
       
    99 
       
   100     // Create a session with the window server:
       
   101     User::LeaveIfError(iWsSession.Connect());
       
   102 
       
   103     // Create a session with the layout manager:
       
   104     User::LeaveIfError(iLayoutMgr.Connect());
       
   105 
       
   106     // We also need a key repeat timer:
       
   107     iRepeatTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   108 
       
   109     // repeat ending timer
       
   110     iRepeatEndTimer = CTimeOutTimer::NewL(EPriorityNormal, *this);
       
   111     iAppMenuId = AppMenuId();
       
   112     iPhoneAppId = PhoneAppId();
       
   113     iIdleAppId = IdleAppId();
       
   114 
       
   115     iComboDevice = EFalse;
       
   116 
       
   117     iSettings = CBtHidSettings::NewL();
       
   118     }
       
   119 
       
   120 //----------------------------------------------------------------------------
       
   121 // CHidKeyboardDriver::~CHidKeyboardDriver
       
   122 //----------------------------------------------------------------------------
       
   123 //
       
   124 CHidKeyboardDriver::~CHidKeyboardDriver()
       
   125     {
       
   126         TRACE_INFO( (_L("[HID]\t~CHidKeyboardDriver() 0x%08x"), this));
       
   127 
       
   128     CancelAllKeys();
       
   129     delete iRepeatTimer;
       
   130     delete iRepeatEndTimer;
       
   131     iWsSession.Close();
       
   132     iLayoutMgr.Close();
       
   133 
       
   134     for (TInt i = 0; i < KNumInputFieldTypes; ++i)
       
   135         {
       
   136         iKeys[i].Reset();
       
   137         }
       
   138 
       
   139     iPointBufQueue.Close();
       
   140 
       
   141     if (iComboDevice)
       
   142         {
       
   143         RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorHide );
       
   144         }
       
   145 
       
   146     if (iSettings)
       
   147         delete iSettings;
       
   148     }
       
   149 
       
   150 void CHidKeyboardDriver::MoveCursor(const TPoint& aPoint)
       
   151     {
       
   152     DBG(RDebug::Print(
       
   153                     _L("CHidKeyboard::MoveCursor")));
       
   154 
       
   155     PostPointer(aPoint);
       
   156     }
       
   157 // ---------------------------------------------------------------------------
       
   158 // CHidMouseDriver::PostPointer
       
   159 // Save the event to the buffer
       
   160 // ---------------------------------------------------------------------------
       
   161 //
       
   162 TInt CHidKeyboardDriver::PostPointer(const TPoint& aPoint)
       
   163     {
       
   164     DBG(RDebug::Print(_L("CHidKeyboard::PostPointer")));
       
   165     iPointerBuffer.iPoint[iPointerBuffer.iNum] = aPoint;
       
   166     iPointerBuffer.iType[iPointerBuffer.iNum] = KBufferPlainPointer;
       
   167     iPointerBuffer.iNum++;
       
   168     TInt ret = KErrNone;
       
   169 
       
   170     if (iPointerBuffer.iNum > KPMaxEvent)
       
   171         {
       
   172         ret = iPointBufQueue.Send(iPointerBuffer);
       
   173         iPointerBuffer.iNum = 0;
       
   174         }
       
   175     return ret;
       
   176     }
       
   177 
       
   178 TInt CHidKeyboardDriver::SendButtonEvent(TBool aButtonDown)
       
   179     {
       
   180     DBG(RDebug::Print(
       
   181                     _L("CHidKeyboard::SendButtonEvent")));
       
   182     iPointerBuffer.iPoint[iPointerBuffer.iNum] = TPoint(0, 0);
       
   183     iPointerBuffer.iType[iPointerBuffer.iNum] = aButtonDown
       
   184                                                             ? KBufferPenDown
       
   185                                                                : KBufferPenUp;
       
   186     iPointerBuffer.iNum++;
       
   187     TInt ret = iPointBufQueue.Send(iPointerBuffer);
       
   188     iPointerBuffer.iNum = 0;
       
   189     return ret;
       
   190     }
       
   191 //----------------------------------------------------------------------------
       
   192 // CHidKeyboardDriver:::StartL
       
   193 //----------------------------------------------------------------------------
       
   194 //
       
   195 void CHidKeyboardDriver::StartL(TInt aConnectionId)
       
   196     {
       
   197         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::StartL")));
       
   198     aConnectionId = aConnectionId;
       
   199     // No keys are pressed:
       
   200     iModifiers = 0;
       
   201     for (TInt i = 0; i < KNumInputFieldTypes; ++i)
       
   202         {
       
   203         if (iField[i])
       
   204             {
       
   205             // Reset the keys pressed array to all zeros
       
   206             RArray<TInt>& keys = iKeys[i];
       
   207 
       
   208             for (TInt j = 0; j < keys.Count(); j++)
       
   209                 {
       
   210                 keys[j] = 0;
       
   211                 }
       
   212             }
       
   213         }
       
   214 
       
   215     // Start up with Num Lock active:
       
   216     iLockState = ENumLock;
       
   217     SetKeyboardLeds();
       
   218 
       
   219     //In case of reconnection, try to initialize the Keybord driver...
       
   220     InitialiseL(aConnectionId);
       
   221 
       
   222     // Reset the state of the layout decoder:
       
   223     iLayoutMgr.Reset();
       
   224 
       
   225     TInt initialLayout;
       
   226     User::LeaveIfError(iLayoutMgr.GetLayout(initialLayout));
       
   227     iLastSelectedLayout = iSettings->LoadLayoutSetting();
       
   228     TBool sameCategory = CLayoutUtils::SameCategory(
       
   229             static_cast<THidKeyboardLayoutId> (initialLayout),
       
   230             iLastSelectedLayout);
       
   231     if (sameCategory)
       
   232         {
       
   233         //Used the layoutID from CenRep
       
   234         iLayoutMgr.SetLayout(iLastSelectedLayout);
       
   235         }
       
   236     TInt err = iPointBufQueue.OpenGlobal(KMsgBTMouseBufferQueue);   
       
   237     if (err == KErrNotFound)
       
   238         {
       
   239         User::LeaveIfError(iPointBufQueue.CreateGlobal(KMsgBTMouseBufferQueue, KPointQueueLen));    
       
   240         }
       
   241     else
       
   242         {
       
   243         User::LeaveIfError( err );
       
   244         }    
       
   245 
       
   246     // Ready to process keyboard events:
       
   247     iDriverState = EInitialised;
       
   248 
       
   249     if (iComboDevice)
       
   250         {
       
   251         LaunchApplicationL(KAppName);
       
   252         RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorShow );
       
   253         }
       
   254 
       
   255     }
       
   256 
       
   257 //----------------------------------------------------------------------------
       
   258 // CHidKeyboardDriver::InitialiseL
       
   259 //----------------------------------------------------------------------------
       
   260 //
       
   261 void CHidKeyboardDriver::InitialiseL(TInt aConnectionId)
       
   262     {
       
   263         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::InitialiseL(%d)"),
       
   264                         aConnectionId));
       
   265 
       
   266     // Store the connection ID:
       
   267     iConnectionId = aConnectionId;
       
   268 
       
   269     // Initialise the layout manager:
       
   270     TInt country = iGenericHid->CountryCodeL(aConnectionId);
       
   271     TInt vendor = iGenericHid->VendorIdL(aConnectionId);
       
   272     TInt product = iGenericHid->ProductIdL(aConnectionId);
       
   273 
       
   274         TRACE_INFO( (
       
   275                         _L("[HID]\t  Country = %d, vendor = %d, product = %d"),
       
   276                         country, vendor, product));
       
   277 
       
   278     User::LeaveIfError(iLayoutMgr.SetInitialLayout(country, vendor, product));
       
   279     }
       
   280 
       
   281 //----------------------------------------------------------------------------
       
   282 // CHidKeyboardDriver::Stop
       
   283 //----------------------------------------------------------------------------
       
   284 //
       
   285 void CHidKeyboardDriver::Stop()
       
   286     {
       
   287     iDriverState = EDisabled;
       
   288     CancelAllKeys();
       
   289     if (iComboDevice)
       
   290         {
       
   291         RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorHide );
       
   292         }
       
   293     }
       
   294 
       
   295 //----------------------------------------------------------------------------
       
   296 // CHidMouseDriver::LaunchApplicationL
       
   297 //----------------------------------------------------------------------------
       
   298 //
       
   299 void CHidKeyboardDriver::LaunchApplicationL(const TDesC& aName)
       
   300     {
       
   301     //Check if application is already running in the background
       
   302     TApaTaskList tasks(iWsSession);
       
   303     TApaTask task = tasks.FindApp(aName);
       
   304     if (task.Exists())
       
   305         {
       
   306         // Application is active, so just bring to foreground
       
   307         }
       
   308     else
       
   309         {
       
   310         // If application is not running, then create a new one
       
   311         CApaCommandLine* cmd = CApaCommandLine::NewLC();
       
   312         cmd->SetExecutableNameL(aName);
       
   313         cmd->SetCommandL(EApaCommandBackground); // EApaCommandRun
       
   314 
       
   315         RApaLsSession arcSession;
       
   316         //connect to AppArc server
       
   317         User::LeaveIfError(arcSession.Connect());
       
   318         CleanupClosePushL(arcSession);
       
   319         User::LeaveIfError(arcSession.StartApp(*cmd));
       
   320         arcSession.Close();
       
   321         CleanupStack::PopAndDestroy(2);
       
   322         }
       
   323 
       
   324     }
       
   325 
       
   326 // ----------------------------------------------------------------------
       
   327 // CHidDriver mandatory functions:
       
   328 
       
   329 //----------------------------------------------------------------------------
       
   330 // CHidKeyboardDriver::DataIn
       
   331 //----------------------------------------------------------------------------
       
   332 //
       
   333 TInt CHidKeyboardDriver::DataIn(CHidTransport::THidChannelType aChannel,
       
   334         const TDesC8& aPayload)
       
   335     {
       
   336     TInt err = KErrNone;
       
   337     switch (aChannel)
       
   338         {
       
   339         case CHidTransport::EHidChannelInt:
       
   340             if (EInitialised == iDriverState)
       
   341                 {
       
   342                 if (iComboDevice)
       
   343                     {
       
   344                     TInt mouseStatus;
       
   345                     TInt err = RProperty::Get( KPSUidBthidSrv, KBTMouseCursorState, mouseStatus );
       
   346                     if ( !err && (static_cast<THidMouseCursorState>(mouseStatus) == ECursorHide) )
       
   347                         {
       
   348                         err = RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorShow );
       
   349                         }
       
   350                     }
       
   351                 InterruptData(aPayload);
       
   352                 }
       
   353             break;
       
   354 
       
   355         case CHidTransport::EHidChannelCtrl:
       
   356             break;
       
   357 
       
   358         default:
       
   359             break;
       
   360         }
       
   361     return err;
       
   362     }
       
   363 
       
   364 //----------------------------------------------------------------------------
       
   365 // CHidKeyboardDriver::CommandResult
       
   366 //----------------------------------------------------------------------------
       
   367 //
       
   368 void CHidKeyboardDriver::CommandResult(TInt /*aCmdAck*/)
       
   369     {
       
   370     // No implementation as we don't issue any requests to be acknowledged
       
   371     }
       
   372 
       
   373 //----------------------------------------------------------------------------
       
   374 // CHidKeyboardDriver::Disconnected
       
   375 //----------------------------------------------------------------------------
       
   376 //
       
   377 void CHidKeyboardDriver::Disconnected(TInt aReason)
       
   378     {
       
   379     RDebug::Print(_L("CHidKeyboardDriver::Disconnected(%d)"), aReason);
       
   380     Stop();
       
   381     }
       
   382 
       
   383 void CHidKeyboardDriver::UpdateXY(TInt aFieldIndex, const TDesC8& aReport)
       
   384     {
       
   385     //    DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateModifiers()")));
       
   386 
       
   387     // Translate the HID usage values into a boot protocol style
       
   388     // modifier bitmask:
       
   389     //
       
   390     TReportTranslator report(aReport, iMouseField[aFieldIndex]);
       
   391 
       
   392     TInt Xvalue = 0;
       
   393     TInt Yvalue = 0;
       
   394 
       
   395     TInt errX = report.GetValue(Xvalue, EGenericDesktopUsageX);
       
   396     TInt errY = report.GetValue(Yvalue, EGenericDesktopUsageY);
       
   397 
       
   398     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateXY (%d,%d)"), Xvalue, Yvalue));
       
   399     if ((Xvalue != 0) || (Yvalue != 0))
       
   400         {
       
   401         MoveCursor(TPoint(Xvalue, Yvalue));
       
   402         }
       
   403     }
       
   404 
       
   405 void CHidKeyboardDriver::UpdateWheel(TInt aFieldIndex, const TDesC8& aReport)
       
   406     {
       
   407     TReportTranslator report(aReport, iMouseField[aFieldIndex]);
       
   408 
       
   409     TInt Yvalue = 0;
       
   410 
       
   411     TInt errY = report.GetValue(Yvalue, EGenericDesktopUsageWheel);
       
   412     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateWheel (%d)"), Yvalue));
       
   413     TInt absValue(Abs(Yvalue));
       
   414     if ((errY == KErrNone) && (absValue >= 1))
       
   415         {
       
   416         TRawEvent rawEvent;
       
   417         for (TInt ii = 0; ii < absValue; ii++)
       
   418             {
       
   419             rawEvent.Set(TRawEvent::EKeyDown,
       
   420                     (Yvalue > 0) ? EStdKeyUpArrow : EStdKeyDownArrow);
       
   421             UserSvr::AddEvent(rawEvent);
       
   422             rawEvent.Set(TRawEvent::EKeyUp,
       
   423                     (Yvalue > 0) ? EStdKeyUpArrow : EStdKeyDownArrow);
       
   424             UserSvr::AddEvent(rawEvent);
       
   425             }
       
   426         }
       
   427     DBG(RDebug::Print(_L("[HID]\t  new iModifiers = %02x"), iModifiers));
       
   428     }
       
   429 
       
   430 void CHidKeyboardDriver::UpdateButtons(TInt aFieldIndex,
       
   431         const TDesC8& aReport)
       
   432     {
       
   433     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons()")));
       
   434     // Translate the HID usage values into a boot protocol style
       
   435     // modifier bitmask:
       
   436     //
       
   437     const TInt KButton1 = 1;
       
   438     const TInt KButton2 = 2;
       
   439     const TInt KButton3 = 3;
       
   440 
       
   441     TBool buttonPressed(EFalse);
       
   442 
       
   443     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() %d, %d, %d"),
       
   444                     iMouseField[aFieldIndex]->UsagePage(),
       
   445                     iMouseField[aFieldIndex]->UsageMin(),
       
   446                     iMouseField[aFieldIndex]->UsageMax()));
       
   447     (void) aFieldIndex;
       
   448     // Hack but works
       
   449     // We dont come here if the report is wrong?
       
   450     TInt buttonByte = aReport[1];
       
   451     if (KButton1 == buttonByte)
       
   452         {
       
   453         DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() Button1")));
       
   454         buttonPressed = ETrue;
       
   455         }
       
   456 
       
   457     if (KButton2 == buttonByte)
       
   458         {
       
   459         DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() Button2")));
       
   460         if (!iButton2Down)
       
   461             {
       
   462             iButton2Down = ETrue;
       
   463             TRawEvent rawEvent;
       
   464             rawEvent.Set(TRawEvent::EKeyDown, EStdKeyApplication0);
       
   465             UserSvr::AddEvent(rawEvent);
       
   466             }
       
   467         }
       
   468     else
       
   469         {
       
   470         if (iButton2Down)
       
   471             {
       
   472             iButton2Down = EFalse;
       
   473             TRawEvent rawEvent;
       
   474             rawEvent.Set(TRawEvent::EKeyUp, EStdKeyApplication0);
       
   475             UserSvr::AddEvent(rawEvent);
       
   476             }
       
   477         }
       
   478 
       
   479     if (KButton3 == buttonByte)
       
   480         {
       
   481         DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() Button3")));
       
   482         buttonPressed = ETrue;
       
   483         }
       
   484 
       
   485     if (buttonPressed)
       
   486         {
       
   487         if (!iButtonDown)
       
   488             {
       
   489             iButtonDown = ETrue;
       
   490             SendButtonEvent(ETrue);//Send Mouse Button Down
       
   491             }
       
   492         }
       
   493     else
       
   494         {
       
   495         if (iButtonDown)
       
   496             {
       
   497             iButtonDown = EFalse;
       
   498             SendButtonEvent(EFalse); //Send Mouse Button Up
       
   499             }
       
   500         }
       
   501     }
       
   502 //----------------------------------------------------------------------------
       
   503 // CHidKeyboardDriver::InterruptData
       
   504 //----------------------------------------------------------------------------
       
   505 //
       
   506 void CHidKeyboardDriver::InterruptData(const TDesC8& aPayload)
       
   507     {
       
   508     // If the report has a report ID, it is in the first byte.
       
   509     // If not, this value is ignored (see CField::IsInReport()).
       
   510     //
       
   511     TInt firstByte = aPayload[0];
       
   512 
       
   513         TRACE_INFO( (
       
   514                         _L("[HID]\tCHidKeyboardDriver::InterruptData(), report %d, length %d"),
       
   515                         firstByte, aPayload.Length()));
       
   516 #ifdef _DEBUG
       
   517 
       
   518     for (TInt ii = 0; ii < aPayload.Length(); ii++)
       
   519         {
       
   520         TInt nextByte = aPayload[ii];
       
   521         DBG(RDebug::Print(
       
   522                         _L("[HID]\tCHidKeyboardDriver::InterruptData()  report[%d] =  %d"),
       
   523                         ii, nextByte));
       
   524         }
       
   525 #endif
       
   526     TBool mouseEvent(EFalse);
       
   527     if (iMouseField[EMouseXY] && iMouseField[EMouseXY]->IsInReport(firstByte))
       
   528         {
       
   529         UpdateXY(EMouseXY, aPayload);
       
   530         mouseEvent = ETrue;
       
   531         }
       
   532 
       
   533     if (iMouseField[EMouseButtons] && iMouseField[EMouseButtons]->IsInReport(
       
   534             firstByte))
       
   535         {
       
   536         UpdateButtons(EMouseButtons, aPayload);
       
   537         mouseEvent = ETrue;
       
   538         }
       
   539     if (iMouseField[EMouseXY] && iMouseField[EMouseXY]->IsInReport(firstByte))
       
   540         {
       
   541         UpdateWheel(EMouseWheel, aPayload);
       
   542         mouseEvent = ETrue;
       
   543         }
       
   544     DBG(RDebug::Print(_L("[HID]\tCHidKeyboardDriver::InterruptData()  mouseevent %d"),
       
   545                     mouseEvent));
       
   546     if (mouseEvent)
       
   547         {
       
   548         return;
       
   549         }
       
   550     // First check for any rollover errors:
       
   551     //
       
   552     TInt i;
       
   553     for (i = 0; i < KNumInputFieldTypes; ++i)
       
   554         {
       
   555         if (iField[i] && iField[i]->IsInReport(firstByte)
       
   556                 && (iField[i]->UsagePage() == EUsagePageKeyboard))
       
   557             {
       
   558             if (IsRollover(i, aPayload))
       
   559                 {
       
   560                 CancelAllKeys();
       
   561                 iLayoutMgr.Reset();
       
   562                 return;
       
   563                 }
       
   564             }
       
   565         }
       
   566 
       
   567     // Update the modifier state:
       
   568     //
       
   569     if (iField[EModifierKeys] && iField[EModifierKeys]->IsInReport(firstByte))
       
   570         {
       
   571         UpdateModifiers(EModifierKeys, aPayload);
       
   572         }
       
   573 
       
   574     // Finally, look for key events in all fields in this report:
       
   575     //
       
   576     for (i = 0; i < KNumInputFieldTypes; ++i)
       
   577         {
       
   578         if (iField[i] && iField[i]->IsInReport(firstByte))
       
   579             {
       
   580             ProcessKeys(i, aPayload);
       
   581             }
       
   582         }
       
   583     }
       
   584 
       
   585 //----------------------------------------------------------------------------
       
   586 // CHidKeyboardDriver::IsRollover
       
   587 //
       
   588 // IsRollover() checks to see if the keyboard is in a rollover state
       
   589 // (where too many keys are pressed to be able to give a sensible
       
   590 // report).
       
   591 //
       
   592 // Rollover can only happen for fields with usage page 0x07.
       
   593 //
       
   594 // Returns ETrue if the keyboard is in a rollover state
       
   595 //----------------------------------------------------------------------------
       
   596 //
       
   597 TBool CHidKeyboardDriver::IsRollover(TInt aFieldIndex, const TDesC8& aReport) const
       
   598     {
       
   599     TBool rollover = ETrue;
       
   600 
       
   601     TReportTranslator report(aReport, iField[aFieldIndex]);
       
   602 
       
   603     for (TInt i = 0; rollover && (i < report.Count()); ++i)
       
   604         {
       
   605         const TInt KRolloverError = 1;
       
   606         TInt usage;
       
   607 
       
   608         if (KErrNone == report.GetUsageId(usage, i) && usage
       
   609                 != KRolloverError)
       
   610             {
       
   611             rollover = EFalse;
       
   612             }
       
   613         }
       
   614 
       
   615     return rollover;
       
   616     }
       
   617 
       
   618 //----------------------------------------------------------------------------
       
   619 // CHidKeyboardDriver::ProcessKeys
       
   620 //----------------------------------------------------------------------------
       
   621 //
       
   622 void CHidKeyboardDriver::ProcessKeys(TInt aFieldIndex, const TDesC8& aReport)
       
   623     {
       
   624         TRACE_FUNC
       
   625     ((_L("[HID]\tCHidKeyboardDriver::ProcessKeys()")));
       
   626 
       
   627     // Get the appropriate field and key press array
       
   628     const CField* field = iField[aFieldIndex];
       
   629     RArray<TInt>& keysPressed = iKeys[aFieldIndex];
       
   630 
       
   631     TInt bufferSize = keysPressed.Count();
       
   632     TReportTranslator report(aReport, field);
       
   633 
       
   634         // 1. For each key that appeared in the last report but does
       
   635         //    not appear in this report, send a key UP event.
       
   636 
       
   637         TRACE_FUNC
       
   638     ((_L("[HID]\t  Testing for keys up")));
       
   639 
       
   640     TInt i;
       
   641     for (i = 0; i < bufferSize; ++i)
       
   642         {
       
   643         TInt key = keysPressed[i];
       
   644 
       
   645         if (key)
       
   646             {
       
   647             TInt pressed = EFalse;
       
   648 
       
   649             if ((report.GetValue(pressed, key) == KErrNone) && (!pressed))
       
   650                 {
       
   651                     TRACE_INFO( (_L("[HID]\t  Key up: %d [0x%04x]"), key, key));
       
   652                 KeyUp(key, field->UsagePage());
       
   653                 }
       
   654             }
       
   655         }
       
   656 
       
   657         // 2. For each key that appears in this report, but does
       
   658         //    not appear in the last report, send a key DOWN event.
       
   659 
       
   660         TRACE_FUNC
       
   661     ((_L("  Testing for keys down")));
       
   662 
       
   663     for (i = 0; i < report.Count(); ++i)
       
   664         {
       
   665         TInt key;
       
   666 
       
   667         if ((KErrNone == report.GetUsageId(key, i)) && (key != 0))
       
   668             {
       
   669             // Was the key present (pressed) in the last report?
       
   670             TBool match = EFalse;
       
   671 
       
   672             for (TInt j = 0; !match && (j < bufferSize); ++j)
       
   673                 {
       
   674                 match = (key == keysPressed[j]);
       
   675                 }
       
   676 
       
   677             // If it's a newly-pressed key then send a KeyDown
       
   678             if (!match)
       
   679                 {
       
   680                     TRACE_INFO( (_L("[HID]\t  Key down: %d [0x%02x]"), key, key));
       
   681                 if (iInputHandlingReg->AllowedToHandleEvent(
       
   682                         EUsagePageKeyboard, key))
       
   683                     {
       
   684                     iInputHandlingReg->AddHandledEvent(
       
   685                             EUsagePageGenericDesktop, key);
       
   686                     KeyDown(key, field->UsagePage());
       
   687                     UpdateLockState(key);
       
   688                     }
       
   689                 }
       
   690             }
       
   691         }
       
   692 
       
   693     // 3. Finally, record what keys are down:
       
   694 
       
   695     TInt index = 0;
       
   696     for (i = 0; (i < report.Count()) && (index < bufferSize); ++i)
       
   697         {
       
   698         TInt key;
       
   699 
       
   700         if (KErrNone == report.GetUsageId(key, i) && key != 0)
       
   701             {
       
   702             keysPressed[index++] = key;
       
   703             }
       
   704         }
       
   705     while (index < bufferSize)
       
   706         {
       
   707         keysPressed[index++] = 0;
       
   708         }
       
   709     }
       
   710 
       
   711 //----------------------------------------------------------------------------
       
   712 // CHidKeyboardDriver::KeyEvent
       
   713 //----------------------------------------------------------------------------
       
   714 //
       
   715 void CHidKeyboardDriver::KeyEvent(TBool aIsKeyDown, TInt aHidKey,
       
   716         TInt aUsagePage)
       
   717     {
       
   718         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::KeyEvent(%d, %d, %d)"), aIsKeyDown,
       
   719                         aUsagePage, aHidKey));
       
   720 
       
   721     // Any type of key event will cancel a repeating key:
       
   722     //
       
   723     if (iRepeatTimer->IsActive())
       
   724         {
       
   725         iRepeatTimer->Cancel();
       
   726         }
       
   727 
       
   728     if (iRepeatEndTimer->IsActive())
       
   729         {
       
   730         iRepeatEndTimer->Cancel();
       
   731         }
       
   732 
       
   733     // Pass the key info to the keyboard layout translator:
       
   734     //
       
   735     TDecodedKeyInfo decodedKeys;
       
   736     TInt err = iLayoutMgr.KeyEvent(aIsKeyDown, aHidKey, aUsagePage,
       
   737             iModifiers, TLockKeys(iLockState & ECapsLock, iLockState
       
   738                     & ENumLock), decodedKeys);
       
   739 
       
   740     TTranslatedKey& key = decodedKeys.iEvent[0];
       
   741     if (err == KErrNone)
       
   742         {
       
   743         // Send the "key down" or "key up" event to the system:
       
   744         // Handle special application launch key combinations
       
   745         TRAPD( err, HandleApplicationLaunchKeysL(decodedKeys.iScanCode, aIsKeyDown, iModifiers));
       
   746         if (KErrNone != err)
       
   747             {
       
   748                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::KeyEvent:Launch failed")));
       
   749             }
       
   750 
       
   751         //check if the key is multimedia key that needs to be sent as RawEvent and send it.
       
   752         // if key event is consumed don't send it anymore.
       
   753         if (!HandleMultimediaKeys(decodedKeys.iScanCode, aIsKeyDown,
       
   754                 iModifiers)) //check if the key is multimedia key that needs to be sent as RawEvent and send it.
       
   755             {
       
   756             if (decodedKeys.iScanCode != EStdKeyNull)
       
   757                 {
       
   758                 TKeyEvent event =
       
   759                         TKeyEventFromScanCode(decodedKeys.iScanCode);
       
   760 
       
   761                 // remove other modifiers than autorepeat.
       
   762                 if (event.iScanCode == EStdKeyDevice3)
       
   763                     {
       
   764                     event.iModifiers &= EModifierAutorepeatable;
       
   765                     }
       
   766 
       
   767                     //Number key events to phone app are handled differently.
       
   768                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::KeyEvent: ScanCode: %d %c"), decodedKeys.iScanCode, decodedKeys.iScanCode));
       
   769                 TInt unikey = key.iUnicode;
       
   770                 //Send key codes differently to idle app
       
   771                 if ((IsDigitKey(decodedKeys.iScanCode) || IsSpecialHandleKey(
       
   772                         unikey) || decodedKeys.iScanCode == EStdKeyYes
       
   773                         || decodedKeys.iScanCode == EStdKeyBackspace)
       
   774                         && IsPhoneAppTopMost())
       
   775                     {
       
   776                         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::KeyEvent: Send event %c to idle editor"), unikey));
       
   777                     HandleTelephoneAppKeys(decodedKeys.iScanCode, unikey,
       
   778                             aIsKeyDown);
       
   779                     }
       
   780                 else
       
   781                     SendToWindowGroup(event, aIsKeyDown
       
   782                                                         ? EEventKeyDown
       
   783                                                            : EEventKeyUp);
       
   784                 }
       
   785 
       
   786             // Send any "key press" events to the system, if applicable:
       
   787             //
       
   788             for (TInt i = 0; i < decodedKeys.iCount; ++i)
       
   789                 {
       
   790                 TTranslatedKey & key = decodedKeys.iEvent[i];
       
   791 
       
   792                 SendKeyPress(key.iUnicode, key.iUsagePage, key.iScanCode,
       
   793                         key.iIsRepeatingKey);
       
   794                 }
       
   795             }
       
   796         }
       
   797     else
       
   798         {
       
   799             TRACE_FUNC
       
   800         ((_L("[HID]\tKeyboard event translation failed!")));
       
   801         }
       
   802     }
       
   803 
       
   804 //----------------------------------------------------------------------------
       
   805 // CHidKeyboardDriver::TKeyEventFromScanCode
       
   806 //----------------------------------------------------------------------------
       
   807 //
       
   808 TKeyEvent CHidKeyboardDriver::TKeyEventFromScanCode(TInt aScanCode) const
       
   809     {
       
   810     TKeyEvent event;
       
   811 
       
   812     event.iScanCode = aScanCode;
       
   813     event.iModifiers = KeyEventModifiers();
       
   814 
       
   815     // The following are always zero for a key down or key up event:
       
   816     event.iCode = 0;
       
   817     event.iRepeats = 0;
       
   818 
       
   819     return event;
       
   820     }
       
   821 
       
   822 //----------------------------------------------------------------------------
       
   823 // CHidKeyboardDriver::IsDigitKey
       
   824 //----------------------------------------------------------------------------
       
   825 //
       
   826 TBool CHidKeyboardDriver::IsDigitKey(TInt aScanCode)
       
   827     {
       
   828     TBool ret = EFalse;
       
   829 
       
   830     if (aScanCode >= '0' && aScanCode <= '9')
       
   831         {
       
   832         ret = ETrue;
       
   833         }
       
   834 
       
   835     return ret;
       
   836     }
       
   837 
       
   838 //----------------------------------------------------------------------------
       
   839 // CHidKeyboardDriver::IsDigit
       
   840 //----------------------------------------------------------------------------
       
   841 //
       
   842 TBool CHidKeyboardDriver::IsSpecialHandleKey(TInt aUniCode)
       
   843     {
       
   844     TBool ret = EFalse;
       
   845 
       
   846     if (aUniCode == '+' || aUniCode == '*' || aUniCode == '#' || aUniCode
       
   847             == 'w' || aUniCode == 'p')
       
   848         {
       
   849         ret = ETrue;
       
   850         }
       
   851 
       
   852     return ret;
       
   853     }
       
   854 
       
   855 //----------------------------------------------------------------------------
       
   856 // CHidKeyboardDriver::HandleTelephoneAppKeys
       
   857 //----------------------------------------------------------------------------
       
   858 //
       
   859 void CHidKeyboardDriver::HandleTelephoneAppKeys(TInt aScanCode,
       
   860         TInt aUniCode, TBool aIsKeyDown)
       
   861     {
       
   862     // Telephone view / idle view can't handle proper key events, but the key events must be sent as
       
   863     // raw events.
       
   864     TRawEvent rawEvent;
       
   865     TUint modifier = 0;
       
   866     TInt scancode = aScanCode;
       
   867     switch (aUniCode)
       
   868         {
       
   869         case '+':
       
   870         case EStdKeyNkpPlus:
       
   871             scancode = EStdKeyNkpPlus;
       
   872             modifier = EModifierLeftShift | EModifierShift;
       
   873             break;
       
   874         case '*':
       
   875             //case EStdKeyNkpAsterisk:
       
   876             scancode = EStdKeyNkpAsterisk;
       
   877             modifier = 0; //EModifierLeftShift | EModifierShift;
       
   878             break;
       
   879         case '#':
       
   880             //case EStdKeyHash:
       
   881             scancode = EStdKeyHash;
       
   882             modifier = EModifierLeftShift | EModifierShift;
       
   883             break;
       
   884         case 'w':
       
   885             modifier = EModifierLeftShift | EModifierShift;
       
   886             break;
       
   887         case 'p':
       
   888             modifier = EModifierLeftShift | EModifierShift;
       
   889             break;
       
   890         default:
       
   891             break;
       
   892         }
       
   893         TRACE_INFO( (_L("[HID]\tHIDKeyboard: HandleTelephoneAppKeys: Overridden Scancode: %d, Modifier: %d"), scancode, modifier));
       
   894         TRACE_INFO( (_L("[HID]\tHIDKeyboard: HandleTelephoneAppKeys: Original unicode: %d"), aUniCode));
       
   895 
       
   896     if (aIsKeyDown)
       
   897         rawEvent.Set(TRawEvent::EKeyDown, scancode);
       
   898     else
       
   899         rawEvent.Set(TRawEvent::EKeyUp, scancode); //This will never be called for +,* and #
       
   900 
       
   901     TEventModifier ab = (TEventModifier) -1; //all bits set to 1.
       
   902     TModifierState ba = (TModifierState) modifier;
       
   903         TRACE_INFO( (_L("[HID]\t   modifiers %d, modifierState: %d"), ab, (TUint)ba));
       
   904 
       
   905     iWsSession.SetModifierState(ab, ba);
       
   906     iWsSession.SimulateRawEvent(rawEvent);
       
   907     iWsSession.Flush();
       
   908         TRACE_FUNC
       
   909     ((_L("[HID]\tHIDKeyboard: HandleTelephoneAppKeys: Event sent!")));
       
   910     // Plus, Asterix and Hash keys need to send separate KeyUp event too.
       
   911     if (aUniCode == '+' || aUniCode == '*' || aUniCode == '#' || aUniCode
       
   912             == 'p' || aUniCode == 'w')
       
   913         {
       
   914         rawEvent.Set(TRawEvent::EKeyUp, scancode);
       
   915         iWsSession.SimulateRawEvent(rawEvent); //Key up event
       
   916         iWsSession.Flush();
       
   917             TRACE_FUNC
       
   918         ((_L("[HID]\tHIDKeyboard: HandleTelephoneAppKeys: Separate Key up event sent!")));
       
   919         }
       
   920     }
       
   921 
       
   922 //----------------------------------------------------------------------------
       
   923 // CHidKeyboardDriver::CancelKeysForField
       
   924 //----------------------------------------------------------------------------
       
   925 //
       
   926 void CHidKeyboardDriver::CancelKeysForField(TInt aFieldIndex)
       
   927     {
       
   928     //TRACE_FUNC((_L("[HID]\tCHidKeyboardDriver::CancelKeysForField(%d)"),
       
   929     if (iField[aFieldIndex])
       
   930         {
       
   931         for (TInt i = 0; i < iField[aFieldIndex]->Count(); ++i)
       
   932             {
       
   933             TInt key = iKeys[aFieldIndex][i];
       
   934             //TRACE_FUNC((_L("[HID]\t    Cancel key@%d=%02x (%d)"),
       
   935             //        i, key, key));
       
   936             if (key != 0)
       
   937                 {
       
   938                 KeyUp(key, iField[aFieldIndex]->UsagePage());
       
   939                 iKeys[aFieldIndex][i] = 0;
       
   940                 }
       
   941             }
       
   942         }
       
   943     }
       
   944 
       
   945 //----------------------------------------------------------------------------
       
   946 // CHidKeyboardDriver::CancelAllKeys
       
   947 //----------------------------------------------------------------------------
       
   948 //
       
   949 void CHidKeyboardDriver::CancelAllKeys()
       
   950     {
       
   951         TRACE_FUNC
       
   952     ((_L("[HID]\tCHidKeyboardDriver::CancelAllKeys()")));
       
   953 
       
   954     // Stop the key repeat timer:
       
   955     if (iRepeatTimer->IsActive())
       
   956         {
       
   957         iRepeatTimer->Cancel();
       
   958         }
       
   959 
       
   960     // Stop the key repeat safety timer:
       
   961     if (iRepeatEndTimer->IsActive())
       
   962         {
       
   963         iRepeatEndTimer->Cancel();
       
   964         }
       
   965 
       
   966     // Send key up events for any pressed keys:
       
   967     for (TInt i = 0; i < KNumInputFieldTypes; ++i)
       
   968         {
       
   969         CancelKeysForField(i);
       
   970         }
       
   971 
       
   972     // No modifier keys pressed:
       
   973     iModifiers = 0;
       
   974     }
       
   975 
       
   976 //----------------------------------------------------------------------------
       
   977 // CHidKeyboardDriver::UpdateModifiers
       
   978 //----------------------------------------------------------------------------
       
   979 //
       
   980 void CHidKeyboardDriver::UpdateModifiers(TInt aFieldIndex,
       
   981         const TDesC8& aReport)
       
   982     {
       
   983         TRACE_FUNC
       
   984     ((_L("[HID]\tCHidKeyboardDriver::UpdateModifiers()")));
       
   985         TRACE_INFO( (_L("[HID]\t  old iModifiers = %02x"), iModifiers));
       
   986 
       
   987     const TInt KLeftControl = 224; // => bit 0 of modifier bitmask
       
   988     const TInt KRightGui = 231; // => bit 7
       
   989 
       
   990     TUint8 newModifiers = 0;
       
   991 
       
   992     // Translate the HID usage values into a boot protocol style
       
   993     // modifier bitmask:
       
   994     //
       
   995     TReportTranslator report(aReport, iField[aFieldIndex]);
       
   996     for (TInt i = KLeftControl; i <= KRightGui; i++)
       
   997         {
       
   998         TInt value;
       
   999 
       
  1000         if (KErrNone == report.GetValue(value, i) && value)
       
  1001             {
       
  1002             newModifiers |= (1 << (i - KLeftControl));
       
  1003             }
       
  1004         }
       
  1005 
       
  1006     // Finally, record the new state:
       
  1007     //
       
  1008     iModifiers = newModifiers;
       
  1009 
       
  1010         TRACE_INFO( (_L("[HID]\t  new iModifiers = %02x"), iModifiers));
       
  1011     }
       
  1012 
       
  1013 //----------------------------------------------------------------------------
       
  1014 // CHidKeyboardDriver::UpdateLockState
       
  1015 //----------------------------------------------------------------------------
       
  1016 //
       
  1017 void CHidKeyboardDriver::UpdateLockState(TInt aHidKey)
       
  1018     {
       
  1019     const TInt KHidCapsLock = 57;
       
  1020     const TInt KHidScrollLock = 71;
       
  1021     const TInt KHidNumLock = 83;
       
  1022 
       
  1023     TUint oldLockState = iLockState;
       
  1024 
       
  1025     switch (aHidKey)
       
  1026         {
       
  1027         case KHidNumLock:
       
  1028             iLockState ^= ENumLock;
       
  1029             break;
       
  1030         case KHidCapsLock:
       
  1031             iLockState ^= ECapsLock;
       
  1032             break;
       
  1033         case KHidScrollLock:
       
  1034             iLockState ^= EScrollLock;
       
  1035             break;
       
  1036         }
       
  1037 
       
  1038     if (oldLockState != iLockState)
       
  1039         {
       
  1040             TRACE_INFO( (_L("[HID]\tChanged lock state: %d -> %d"),
       
  1041                             oldLockState, iLockState));
       
  1042         SetKeyboardLeds();
       
  1043         }
       
  1044     }
       
  1045 
       
  1046 //----------------------------------------------------------------------------
       
  1047 // CHidKeyboardDriver::KeyEventModifiers
       
  1048 //----------------------------------------------------------------------------
       
  1049 //
       
  1050 TUint32 CHidKeyboardDriver::KeyEventModifiers() const
       
  1051     {
       
  1052     // Modifier state:
       
  1053 
       
  1054     const TInt KNumModifierKeys = 8;
       
  1055 
       
  1056     const TUint32 KModifierMask[KNumModifierKeys] =
       
  1057         {
       
  1058         EModifierLeftCtrl | EModifierCtrl, // 0x  A0  (report bit 0)
       
  1059                 EModifierLeftShift | EModifierShift, // 0x 500
       
  1060                 EModifierLeftAlt | EModifierAlt, // 0x  14
       
  1061                 EModifierLeftFunc | EModifierFunc, // 0x2800
       
  1062                 EModifierRightCtrl | EModifierCtrl, // 0x  C0
       
  1063                 EModifierRightShift | EModifierShift, // 0x 600
       
  1064                 EModifierRightAlt | EModifierAlt, // 0x  18
       
  1065                 EModifierRightFunc | EModifierFunc
       
  1066         // 0x3000  (report bit 7)
       
  1067             };
       
  1068 
       
  1069     TUint32 result = 0;
       
  1070 
       
  1071     TUint bitPosn = 1;
       
  1072     for (TInt i = 0; i < KNumModifierKeys; ++i)
       
  1073         {
       
  1074         if (iModifiers & bitPosn)
       
  1075             {
       
  1076             result |= KModifierMask[i];
       
  1077             }
       
  1078         bitPosn <<= 1;
       
  1079         }
       
  1080 
       
  1081     // Lock state:
       
  1082 
       
  1083     if (iLockState & ECapsLock)
       
  1084         {
       
  1085         result |= EModifierCapsLock; // 0x 4000
       
  1086         }
       
  1087 
       
  1088     if (iLockState & ENumLock)
       
  1089         {
       
  1090         result |= EModifierNumLock; // 0x 8000
       
  1091         }
       
  1092 
       
  1093     if (iLockState & EScrollLock)
       
  1094         {
       
  1095         result |= EModifierScrollLock; // 0x10000
       
  1096         }
       
  1097 
       
  1098     // Flag used by the FEP to identify events from the HID keyboard
       
  1099     const TUint KHidKeyboardFepFlag = 0x00200000;
       
  1100     result |= KHidKeyboardFepFlag;
       
  1101 
       
  1102     return result;
       
  1103     }
       
  1104 
       
  1105 //----------------------------------------------------------------------------
       
  1106 // CHidKeyboardDriver::SetKeyboardLeds
       
  1107 //----------------------------------------------------------------------------
       
  1108 //
       
  1109 void CHidKeyboardDriver::SetKeyboardLeds() const
       
  1110     {
       
  1111     // Not supported at present
       
  1112     }
       
  1113 
       
  1114 // ----------------------------------------------------------------------
       
  1115 
       
  1116 //----------------------------------------------------------------------------
       
  1117 // CHidKeyboardDriver::OnKeyRepeat
       
  1118 // Key repeat call-back:
       
  1119 //----------------------------------------------------------------------------
       
  1120 //
       
  1121 TInt CHidKeyboardDriver::OnKeyRepeat()
       
  1122     {
       
  1123     // Send another key-press event:
       
  1124     iLastKey.iRepeats = 1;
       
  1125         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::OnKeyRepeat() event [%d, %d, 0x%06x, %d]"),
       
  1126                         iLastKey.iCode, iLastKey.iScanCode,
       
  1127                         iLastKey.iModifiers, iLastKey.iRepeats));
       
  1128     SendToWindowGroup(iLastKey, EEventKey);
       
  1129     return KErrNone;
       
  1130     }
       
  1131 
       
  1132 // -----------------------------------------------------------------------------
       
  1133 // CBTRCCVolumeLevelController::VolumePSChangeTimedoutCallback
       
  1134 // -----------------------------------------------------------------------------
       
  1135 //
       
  1136 TInt CHidKeyboardDriver::TimerFiredOnKeyRepeat(TAny* aThis)
       
  1137     {
       
  1138     return reinterpret_cast<CHidKeyboardDriver*> (aThis)->OnKeyRepeat();
       
  1139     }
       
  1140 
       
  1141 //----------------------------------------------------------------------------
       
  1142 // CHidKeyboardDriver::SendKeyPress
       
  1143 //----------------------------------------------------------------------------
       
  1144 //
       
  1145 void CHidKeyboardDriver::SendKeyPress(TUint16 aUnicodeKey, TInt aUsagePage,
       
  1146         TInt aScanCode, TBool aIsRepeatingKey)
       
  1147     {
       
  1148 
       
  1149         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::SendKeyPress([%d], %d, %d)"),
       
  1150                         aUnicodeKey, aScanCode, aIsRepeatingKey));
       
  1151 
       
  1152 #ifdef _DEBUG
       
  1153     //Please the compiler
       
  1154     //TBuf<256> winGroupName;
       
  1155     //iWsSession.GetWindowGroupNameFromIdentifier(iWsSession.GetFocusWindowGroup(), winGroupName);
       
  1156     //TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver: Focused Window group:<%S>"), winGroupName));
       
  1157 #endif
       
  1158 
       
  1159     //Number entry to Telephone app is handled differently.
       
  1160     if ((IsDigitKey(aScanCode) || IsSpecialHandleKey(aUnicodeKey))
       
  1161             && IsPhoneAppTopMost())
       
  1162         return;
       
  1163 
       
  1164     TKeyEvent event = TKeyEventFromScanCode(aScanCode);
       
  1165     event.iCode = aUnicodeKey;
       
  1166 
       
  1167     if (aIsRepeatingKey)
       
  1168         {
       
  1169         event.iModifiers |= EModifierAutorepeatable;
       
  1170         }
       
  1171 
       
  1172     // Cancel any current key repeat:
       
  1173     if (iRepeatTimer->IsActive())
       
  1174         {
       
  1175         iRepeatTimer->Cancel();
       
  1176         }
       
  1177 
       
  1178     // Send the key press event:
       
  1179 
       
  1180     const TInt KConsumerControlPage = 0x0c;
       
  1181 
       
  1182     // Number entry in telephony does not activate unless we send the key event through WindowServer.
       
  1183     if (aUsagePage == KConsumerControlPage)
       
  1184 
       
  1185         {
       
  1186         // Send media keys using RWsSession::SimulateKeyEvent() so
       
  1187         // that the window server "capture key" function will
       
  1188         // operate. Note that this means that media keys won't have
       
  1189         // standard repeat key functionality because we can't set
       
  1190         // the iRepeats member using SimulateKeyEvent().
       
  1191         SendToWindowServer(event);
       
  1192         }
       
  1193     else
       
  1194         {
       
  1195         //If Chr-key, send '*' to open Special Character Dialog, but not if idle app (telephone).
       
  1196         if (event.iCode == EKeyApplication2)
       
  1197             {
       
  1198                 TRACE_FUNC
       
  1199             ((_L("[HID]\tCHidKeyboardDriver::SendKeyPress, AltGr pressed")));
       
  1200             if (IsPhoneAppTopMost()) //If idle app top-most, don't send '*'.
       
  1201                 return;
       
  1202             event.iCode = '*';
       
  1203             event.iScanCode = EStdKeyNkpAsterisk;
       
  1204             event.iModifiers = 0;
       
  1205             }
       
  1206         //If Enter-key, check if AppMenu or Phone/Idle is topmost --> make it Selection key!
       
  1207         if (event.iCode == EKeyEnter)
       
  1208             {
       
  1209             if (IsApplicationMenuTopMost() || IsPhoneAppTopMost())
       
  1210                 {
       
  1211                     TRACE_FUNC
       
  1212                 ((_L("[HID]\tCHidKeyboardDriver::SendKeyPress, Change enter to selection")));
       
  1213                 event.iCode = EKeyDevice3;
       
  1214                 event.iScanCode = EStdKeyDevice3;
       
  1215                 }
       
  1216             }
       
  1217 
       
  1218         // remove other modifiers than autorepeat.
       
  1219         if (event.iScanCode == EStdKeyDevice3)
       
  1220             {
       
  1221             event.iModifiers &= EModifierAutorepeatable;
       
  1222             }
       
  1223 
       
  1224         // Send all other keys using RWsSession::SendEventToWindowGroup():
       
  1225         SendToWindowGroup(event, EEventKey);
       
  1226 
       
  1227         // Set up a key repeat timer, if necessary:
       
  1228         if (aIsRepeatingKey)
       
  1229             {
       
  1230             iLastKey = event;
       
  1231             TTimeIntervalMicroSeconds32 KDefaultDelay = KKeyRepeatDelay;
       
  1232             TTimeIntervalMicroSeconds32 KDefaultRate = KKeyRepeatInterval;
       
  1233             iRepeatTimer->Start(KDefaultDelay, KDefaultRate, TCallBack(
       
  1234                     CHidKeyboardDriver::TimerFiredOnKeyRepeat, this));
       
  1235             if (!iRepeatEndTimer->IsActive())
       
  1236                 {
       
  1237                 DBG(RDebug::Print(_L("[HID]\tCHidKeyboardDriver::SendKeyPress, start repeat ending timer")));
       
  1238                 iRepeatEndTimer->After(KRepeatEndTimeout);
       
  1239                 }
       
  1240             }
       
  1241         }
       
  1242     }
       
  1243 
       
  1244 //----------------------------------------------------------------------------
       
  1245 // CHidKeyboardDriver::IsPhoneAppTopMost
       
  1246 // Check if Application Menu is the active application receiving the key presses
       
  1247 //----------------------------------------------------------------------------
       
  1248 //
       
  1249 TBool CHidKeyboardDriver::IsApplicationMenuTopMost()
       
  1250     {
       
  1251     TBool ret = EFalse;
       
  1252     if (iAppMenuId == KErrNotFound) //was not found earlier in Constructor (WKB app launched at boot)
       
  1253         iAppMenuId = AppMenuId(); //if in constructor the AppMenu was not active, then ask is it now
       
  1254     TInt focusedId = iWsSession.GetFocusWindowGroup();
       
  1255     if (focusedId == iAppMenuId)
       
  1256         ret = ETrue;
       
  1257         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::IsApplicationMenuTopMost(): %d"), ret ));
       
  1258     return ret;
       
  1259     }
       
  1260 
       
  1261 //----------------------------------------------------------------------------
       
  1262 // CHidKeyboardDriver::IsPhoneAppTopMost
       
  1263 //----------------------------------------------------------------------------
       
  1264 //
       
  1265 TBool CHidKeyboardDriver::IsPhoneAppTopMost()
       
  1266     {
       
  1267     TBool ret = EFalse;
       
  1268     if (iPhoneAppId == KErrNotFound) //was not found earlier in Constructor (WKB app launched at boot)
       
  1269         iPhoneAppId = PhoneAppId(); //if in constructor the AppMenu was not active, then ask is it now
       
  1270     if (iIdleAppId == KErrNotFound)
       
  1271         iIdleAppId = IdleAppId();
       
  1272 
       
  1273     TInt focusedId = iWsSession.GetFocusWindowGroup();
       
  1274     if (focusedId == iPhoneAppId || focusedId == iIdleAppId) //KPhoneIdleViewUid || focusedId == KIdleAppUid)
       
  1275         ret = ETrue;
       
  1276         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::IsPhoneAppTopMost(): %d"), ret ));
       
  1277     return ret;
       
  1278     }
       
  1279 
       
  1280 //----------------------------------------------------------------------------
       
  1281 // CHidKeyboardDriver::AppMenuId
       
  1282 //----------------------------------------------------------------------------
       
  1283 //
       
  1284 TInt CHidKeyboardDriver::AppMenuId()
       
  1285     {
       
  1286     TApaTaskList taskList(iWsSession);
       
  1287     TApaTask task = taskList.FindApp(TUid::Uid(KMenuAppUid));
       
  1288     TInt Id = task.WgId();
       
  1289     DBG(if (KErrNotFound == Id) RDebug::Print(_L("[HID]\tCHidKeyboardDriver::AppMenuId(): Menu not found!")));
       
  1290 
       
  1291     return Id;
       
  1292     }
       
  1293 
       
  1294 //----------------------------------------------------------------------------
       
  1295 // CHidKeyboardDriver::PhoneAppId
       
  1296 //----------------------------------------------------------------------------
       
  1297 //
       
  1298 TInt CHidKeyboardDriver::PhoneAppId()
       
  1299     {
       
  1300 
       
  1301     TApaTaskList taskList(iWsSession);
       
  1302     TApaTask task = taskList.FindApp(TUid::Uid(KPhoneAppUid));
       
  1303     TInt Id = task.WgId();
       
  1304     DBG(if (KErrNotFound == Id) RDebug::Print(_L("[HID]\tCHidKeyboardDriver::PhoneAppId(): Phone not found!")));
       
  1305 
       
  1306     return Id;
       
  1307     }
       
  1308 
       
  1309 //----------------------------------------------------------------------------
       
  1310 // CHidKeyboardDriver::IdleAppId
       
  1311 //----------------------------------------------------------------------------
       
  1312 //
       
  1313 TInt CHidKeyboardDriver::IdleAppId()
       
  1314     {
       
  1315     TApaTaskList taskList(iWsSession);
       
  1316     TApaTask task = taskList.FindApp(TUid::Uid(KIdleAppUid));
       
  1317     TInt Id = task.WgId();
       
  1318     DBG(if (KErrNotFound == Id) RDebug::Print(_L("[HID]\tCHidKeyboardDriver::IdleAppId(): Idle not found!")));
       
  1319 
       
  1320     return Id;
       
  1321     }
       
  1322 
       
  1323 //----------------------------------------------------------------------------
       
  1324 // CHidKeyboardDriver::SendToWindowServer
       
  1325 //----------------------------------------------------------------------------
       
  1326 //
       
  1327 void CHidKeyboardDriver::SendToWindowServer(TKeyEvent aKeyEvent)
       
  1328     {
       
  1329         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::SendToWindowServer, event: kc 0x%08x, sc 0x%08x, mod 0x%06x, rep %d]"),
       
  1330                         aKeyEvent.iCode, aKeyEvent.iScanCode,
       
  1331                         aKeyEvent.iModifiers, aKeyEvent.iRepeats));
       
  1332 
       
  1333     // Prevent the window server generating key repeats as we do this ourselves
       
  1334     aKeyEvent.iModifiers &= ~EModifierAutorepeatable;
       
  1335     iWsSession.SimulateKeyEvent(aKeyEvent);
       
  1336     iWsSession.Flush();
       
  1337         TRACE_FUNC
       
  1338     ((_L("[HID]\tCHidKeyboardDriver::SendToWindowServer, Event sent!")));
       
  1339     }
       
  1340 
       
  1341 //----------------------------------------------------------------------------
       
  1342 // CHidKeyboardDriver::SendToWindowGroup
       
  1343 //----------------------------------------------------------------------------
       
  1344 //
       
  1345 void CHidKeyboardDriver::SendToWindowGroup(const TKeyEvent& aKeyEvent,
       
  1346         TEventCode aType)
       
  1347     {
       
  1348 
       
  1349         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::SendToWindowGroup, Event: type %d, kc 0x%08x, sc 0x%08x, mod 0x%06x, rep %d]"),
       
  1350                         aType, aKeyEvent.iCode, aKeyEvent.iScanCode,
       
  1351                         aKeyEvent.iModifiers, aKeyEvent.iRepeats));
       
  1352 
       
  1353     // Using RWsSession::SendEventToWindowGroup() bypasses the normal
       
  1354     // key handling in the window server, and so capture keys don't
       
  1355     // work.  Therefore we check for the known captured keys in
       
  1356     // WindowGroupForKeyEvent().
       
  1357 
       
  1358     TInt wGroup = WindowGroupForKeyEvent(aKeyEvent, aType);
       
  1359 
       
  1360     if (0 < wGroup)
       
  1361         {
       
  1362             TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::SendToWindowGroup: Send event to window group %d"), wGroup));
       
  1363 
       
  1364         TWsEvent event;
       
  1365 
       
  1366         event.SetType(aType);
       
  1367         event.SetHandle(0);
       
  1368 
       
  1369         *(event.Key()) = aKeyEvent;
       
  1370 
       
  1371         // Remove shift modifiers from call key events because
       
  1372         // the phone application ignores them otherwise
       
  1373         //
       
  1374         if (EStdKeyYes == aKeyEvent.iScanCode || EStdKeyNo
       
  1375                 == aKeyEvent.iScanCode)
       
  1376             {
       
  1377             event.Key()->iModifiers &= ~(EModifierLeftShift
       
  1378                     | EModifierRightShift | EModifierShift);
       
  1379             }
       
  1380 
       
  1381         // don't send ctrl and shift keys.
       
  1382         if (EStdKeyLeftShift != aKeyEvent.iScanCode && EStdKeyRightShift
       
  1383                 != aKeyEvent.iScanCode && EStdKeyLeftCtrl
       
  1384                 != aKeyEvent.iScanCode && EStdKeyRightCtrl
       
  1385                 != aKeyEvent.iScanCode)
       
  1386             {
       
  1387             iWsSession.SendEventToWindowGroup(wGroup, event);
       
  1388             iWsSession.Flush();
       
  1389                 TRACE_FUNC
       
  1390             ((_L("[HID]\tCHidKeyboardDriver::SendToWindowGroup: Event sent!")));
       
  1391             }
       
  1392         else
       
  1393             TRACE_FUNC
       
  1394         ((_L("[HID]\tCHidKeyboardDriver::SendToWindowGroup: Shift or ctrl not sent!")));
       
  1395 
       
  1396         }
       
  1397 
       
  1398     // Keypresses should reset the backlight timer:
       
  1399     User::ResetInactivityTime();
       
  1400     }
       
  1401 
       
  1402 //----------------------------------------------------------------------------
       
  1403 // CHidKeyboardDriver::WindowGroupForKeyEvent
       
  1404 // Determine which window group a key event should be sent to.
       
  1405 // Except for special cases this is the window group with the focus.
       
  1406 //----------------------------------------------------------------------------
       
  1407 //
       
  1408 TInt CHidKeyboardDriver::WindowGroupForKeyEvent(const TKeyEvent& aKeyEvent,
       
  1409         TEventCode aType)
       
  1410     {
       
  1411         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::WindowGroupForKeyEvent: type %d, kc 0x%08x, sc 0x%08x, mod 0x%06x, rep %d]"),
       
  1412                         aType, aKeyEvent.iCode, aKeyEvent.iScanCode,
       
  1413                         aKeyEvent.iModifiers, aKeyEvent.iRepeats));
       
  1414     _LIT(KBackDrop, "*EiksrvBackdrop*");
       
  1415 
       
  1416     if (EStdKeyApplication0 == aKeyEvent.iScanCode && (EEventKeyDown == aType
       
  1417             || EEventKeyUp == aType))
       
  1418         {
       
  1419         // Application key up/down events go to the Eikon server
       
  1420         // Use this old way for application key
       
  1421         TInt result = iWsSession.FindWindowGroupIdentifier(0, KBackDrop); //This was in A2.x __EIKON_SERVER_NAME
       
  1422         DBG(if (KErrNotFound == result) RDebug::Print(_L("[HID]\tCHidKeyboardDriver::WindowGroupForKeyEvent(): BackDropWindowGroup Name not found!")));
       
  1423         return result;
       
  1424         }
       
  1425 
       
  1426     if (EKeyDevice2 == aKeyEvent.iCode && EEventKey == aType)
       
  1427         {
       
  1428         // Power key press events go to SysAp
       
  1429         TApaTaskList taskList( iWsSession );
       
  1430         TApaTask task = taskList.FindApp( TUid::Uid( KSysApUid ) );
       
  1431         TInt result = task.WgId();
       
  1432         DBG(if (KErrNotFound == result) RDebug::Print(_L("[HID]\tCHidKeyboardDriver::WindowGroupForKeyEvent(): SysApWindowGroup Name not found!")))
       
  1433         ;
       
  1434         return result;
       
  1435         }
       
  1436 
       
  1437     if (EStdKeyNo == aKeyEvent.iScanCode
       
  1438             && (EEventKeyDown == aType || EEventKeyUp == aType))
       
  1439         {
       
  1440         // End key up/down events go to the phone app
       
  1441         TApaTaskList taskList( iWsSession );
       
  1442         TApaTask task = taskList.FindApp( TUid::Uid( KPhoneAppUid ) );
       
  1443         TInt result = task.WgId();
       
  1444         DBG(if (KErrNotFound == result) RDebug::Print(_L("[HID]\tCHidKeyboardDriver::WindowGroupForKeyEvent(): PhoneAppWindowGroup Name not found!")))
       
  1445         ;
       
  1446         return result;
       
  1447         }
       
  1448 
       
  1449     // All other key events go to the window group with the keyboard focus
       
  1450     return iWsSession.GetFocusWindowGroup();
       
  1451     }
       
  1452 
       
  1453 // ----------------------------------------------------------------------
       
  1454 
       
  1455 //----------------------------------------------------------------------------
       
  1456 // CHidKeyboardDriver::ResetArrayToSize
       
  1457 //----------------------------------------------------------------------------
       
  1458 //
       
  1459 TInt CHidKeyboardDriver::ResetArrayToSize(RArray<TInt>& aArray, TInt aSize)
       
  1460     {
       
  1461     TInt err = KErrNone;
       
  1462 
       
  1463     aArray.Reset();
       
  1464 
       
  1465     for (TInt i = 0; !err && (i < aSize); ++i)
       
  1466         {
       
  1467         err = aArray.Append(0);
       
  1468         }
       
  1469 
       
  1470     return err;
       
  1471     }
       
  1472 
       
  1473 //----------------------------------------------------------------------------
       
  1474 // CHidKeyboardDriver::CanHandleReportL
       
  1475 //----------------------------------------------------------------------------
       
  1476 //
       
  1477 TInt CHidKeyboardDriver::CanHandleReportL(CReportRoot* aReportRoot)
       
  1478     {
       
  1479         TRACE_INFO( (_L("[HID]\tCHidKeyboard::CanHandleReport(0x%08x)"),
       
  1480                         aReportRoot));
       
  1481     iSupportedFieldCount = 0;
       
  1482     // Look for keyboard reports:
       
  1483 
       
  1484     THidFieldSearch search;
       
  1485 
       
  1486     TKeyboardFinder finder;
       
  1487     search.SearchL(aReportRoot, &finder);
       
  1488     iField[EStandardKeys] = finder.StandardKeyField();
       
  1489     iField[EModifierKeys] = finder.ModifierKeyField();
       
  1490     iLedField = finder.LedField();
       
  1491 
       
  1492     TConsumerKeysFinder mmFinder;
       
  1493     search.SearchL(aReportRoot, &mmFinder);
       
  1494     iField[EMediaKeys] = mmFinder.ConsumerKeysField();
       
  1495 
       
  1496     TPowerKeysFinder pwrFinder;
       
  1497     search.SearchL(aReportRoot, &pwrFinder);
       
  1498     iField[EPowerKeys] = pwrFinder.PowerKeysField();
       
  1499 
       
  1500     for (TInt i = 0; i < KNumInputFieldTypes; ++i)
       
  1501         {
       
  1502         if (iField[i])
       
  1503             {
       
  1504             iSupportedFieldCount++;
       
  1505             User::LeaveIfError(ResetArrayToSize(iKeys[i], iField[i]->Count()));
       
  1506             }
       
  1507         }
       
  1508 
       
  1509     TInt valid = KErrHidUnrecognised;
       
  1510 
       
  1511     // We only require standard and modifier key reports; the
       
  1512     // LED and consumer keys are optional:
       
  1513 
       
  1514     if ((iField[EStandardKeys] != 0) && (iField[EModifierKeys] != 0))
       
  1515         {
       
  1516         valid = KErrNone;
       
  1517         }
       
  1518 
       
  1519     TMouseFinder mousefinder;
       
  1520     search.SearchL(aReportRoot, &mousefinder);
       
  1521     iMouseField[EMouseButtons] = mousefinder.ButtonsField();
       
  1522     iMouseField[EMouseXY] = mousefinder.XYField();
       
  1523     iMouseField[EMouseWheel] = mousefinder.WheelField();
       
  1524 
       
  1525     if ((iMouseField[EMouseButtons] != 0) && (iMouseField[EMouseXY] != 0))
       
  1526         {
       
  1527         iComboDevice = ETrue;
       
  1528         }
       
  1529 
       
  1530         TRACE_INFO( (
       
  1531                         _L("CHidKeyboard::CanHandleReport() returning %d"), valid));
       
  1532 
       
  1533     return valid;
       
  1534     }
       
  1535 
       
  1536 //----------------------------------------------------------------------------
       
  1537 // CHidKeyboardDriver::HandleApplicationLaunchKeysL
       
  1538 //----------------------------------------------------------------------------
       
  1539 //
       
  1540 void CHidKeyboardDriver::HandleApplicationLaunchKeysL(TUint16 aScancodeKey,
       
  1541         TBool aIsKeyDown, TUint8 aHIDModifiers)
       
  1542     {
       
  1543     // Note that aHIDModifier is not Symbian Modifier bits, but in below format: (from HID spec)
       
  1544     /*    const TUint32 KModifierMask[KNumModifierKeys] =
       
  1545      {
       
  1546      EModifierLeftCtrl   | EModifierCtrl,   // 0x  A0  (report bit 0)
       
  1547      EModifierLeftShift  | EModifierShift,  // 0x 500       
       
  1548      EModifierLeftAlt    | EModifierAlt,    // 0x  14
       
  1549      EModifierLeftFunc   | EModifierFunc,   // 0x2800
       
  1550      EModifierRightCtrl  | EModifierCtrl,   // 0x  C0
       
  1551      EModifierRightShift | EModifierShift,  // 0x 600
       
  1552      EModifierRightAlt   | EModifierAlt,    // 0x  18
       
  1553      EModifierRightFunc  | EModifierFunc    // 0x3000  (report bit 7)
       
  1554      };
       
  1555      */
       
  1556     const TUint KHIDModifierAlt = 0x04;
       
  1557 
       
  1558         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleApplicationLaunchKeys: scancode 0x%08x, HIDmodifiers 0x%08x"), aScancodeKey, aHIDModifiers));
       
  1559 
       
  1560     switch (aScancodeKey)
       
  1561         {
       
  1562         // Alt-m launches MultimediaMenu
       
  1563         case 'm':
       
  1564         case 'M':
       
  1565             {
       
  1566             if (aHIDModifiers & KHIDModifierAlt)
       
  1567                 {
       
  1568                     TRACE_FUNC
       
  1569                 ((_L("Launch multimediamenu")));
       
  1570                 //LaunchApplicationL( KMultimediaMenuUid );
       
  1571                 TInt err = SendRawEvent(EStdKeyApplication6, aIsKeyDown, 0);
       
  1572                 if (KErrNone != err)
       
  1573                     {
       
  1574                         TRACE_FUNC
       
  1575                     ((_L("[HID]\t    Event sending failed")));
       
  1576                     }
       
  1577                 }
       
  1578             break;
       
  1579             }
       
  1580 
       
  1581             // Alt-n launches ActiveNotes
       
  1582         case 'n':
       
  1583         case 'N':
       
  1584             {
       
  1585             if (aHIDModifiers & KHIDModifierAlt)
       
  1586                 {
       
  1587                     TRACE_FUNC
       
  1588                 ((_L("[HID]\t   Launch active notes")));
       
  1589                 LaunchApplicationL(KActiveNotesUid);
       
  1590                 }
       
  1591             break;
       
  1592             }
       
  1593         case EStdKeyF1:
       
  1594             {
       
  1595             DBG(RDebug::Print(_L("[HID]\t   Launch Web service")));
       
  1596             LaunchApplicationL(KServicesUid);
       
  1597             }
       
  1598             break;
       
  1599         case EStdKeyF2:
       
  1600             {
       
  1601             DBG(RDebug::Print(_L("[HID]\t   Launch messages")));
       
  1602             LaunchApplicationL(KMessagingUid);
       
  1603             }
       
  1604             break;
       
  1605         default:
       
  1606             break;
       
  1607         }
       
  1608     }
       
  1609 
       
  1610 //----------------------------------------------------------------------------
       
  1611 // CHidKeyboardDriver::LaunchApplicationL
       
  1612 //----------------------------------------------------------------------------
       
  1613 //
       
  1614 void CHidKeyboardDriver::LaunchApplicationL(TInt aAppUid)
       
  1615     {
       
  1616         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::LaunchApplication: UID 0x%08x"), aAppUid));
       
  1617 
       
  1618     TApaTaskList taskList(iWsSession);
       
  1619     TUid uid = TUid::Uid(aAppUid);
       
  1620     TApaTask task = taskList.FindApp(uid);
       
  1621     if (task.Exists())
       
  1622         {
       
  1623         // Application is active, so just bring to foreground
       
  1624         task.BringToForeground();
       
  1625         }
       
  1626     else
       
  1627         {
       
  1628         RApaLsSession appArcSession;
       
  1629         // connect to AppArc server
       
  1630         User::LeaveIfError(appArcSession.Connect());
       
  1631 
       
  1632         CleanupClosePushL(appArcSession);
       
  1633 
       
  1634         TThreadId threadID;
       
  1635 
       
  1636         // Launch the application with no params.
       
  1637         User::LeaveIfError(appArcSession.StartDocument(KNullDesC, uid,
       
  1638                 threadID));
       
  1639 
       
  1640         CleanupStack::Pop(1); // appArcSession
       
  1641 
       
  1642         appArcSession.Close();
       
  1643         }
       
  1644 
       
  1645     }
       
  1646 
       
  1647 //----------------------------------------------------------------------------
       
  1648 // CHidKeyboardDriver::HandleNokiaMultimediaKeys
       
  1649 // Takes some Multimedia keyevents from HID and converts them to Nokia raw events format
       
  1650 // to simulate as if the key presses came from phone keypad (volume +/-, play, pause, frwd, rewind)
       
  1651 //
       
  1652 // This is temporary solution that shall be replaced by "proper" RemCon Bearer solution.
       
  1653 // Because the keycodes used here may change in future terminal!
       
  1654 // Note that aHIDModifier is not Symbian Modifier bits, but in below format: (from HID spec)
       
  1655 //    const TUint32 KModifierMask[KNumModifierKeys] =
       
  1656 //        {
       
  1657 //        EModifierLeftCtrl   | EModifierCtrl,   // 0x  A0  (report bit 0)
       
  1658 //        EModifierLeftShift  | EModifierShift,  // 0x 500
       
  1659 //        EModifierLeftAlt    | EModifierAlt,    // 0x  14
       
  1660 //        EModifierLeftFunc   | EModifierFunc,   // 0x2800
       
  1661 //        EModifierRightCtrl  | EModifierCtrl,   // 0x  C0
       
  1662 //        EModifierRightShift | EModifierShift,  // 0x 600
       
  1663 //        EModifierRightAlt   | EModifierAlt,    // 0x  18
       
  1664 //        EModifierRightFunc  | EModifierFunc    // 0x3000  (report bit 7)
       
  1665 //        };
       
  1666 //----------------------------------------------------------------------------
       
  1667 //
       
  1668 
       
  1669 TBool CHidKeyboardDriver::HandleMultimediaKeys(TUint16 aScancodeKey,
       
  1670         TBool aIsKeyDown, TUint8 aHIDModifiers)
       
  1671     {
       
  1672     TBool ret = HandleMultimediaKeysForNokia(aScancodeKey, aIsKeyDown,
       
  1673             aHIDModifiers);
       
  1674 
       
  1675     if (!ret)
       
  1676         {
       
  1677         ret = HandleMultimediaKeysForStandard(aScancodeKey, aIsKeyDown,
       
  1678                 aHIDModifiers);
       
  1679         }
       
  1680     return ret;
       
  1681     }
       
  1682 
       
  1683 void CHidKeyboardDriver::ResetBitmap(TBool aIsKeyDown,
       
  1684         TMmKeyDown aBitmapToReset)
       
  1685     {
       
  1686     if (aIsKeyDown)
       
  1687         {
       
  1688         iMmKeyDown = (iMmKeyDown | aBitmapToReset);
       
  1689         }
       
  1690     else
       
  1691         {
       
  1692         iMmKeyDown = (iMmKeyDown & !aBitmapToReset);
       
  1693         }
       
  1694     }
       
  1695 
       
  1696 TBool CHidKeyboardDriver::HandleMultimediaKeysForNokia(TUint16 aScancodeKey,
       
  1697         TBool aIsKeyDown, TUint8 aHIDModifiers)
       
  1698     {
       
  1699     const TUint KHidModifierCtrl = 0x01;
       
  1700     const TUint KHidModifierCtrlRight = 0x10;
       
  1701     const TUint KHidModifierAlt = 0x04;
       
  1702 
       
  1703     //	const TUint KHidModifierAltGr = 0x64;
       
  1704     TInt scancode = 0;
       
  1705     TUint modifier = 0;
       
  1706     TBool isMmKey = EFalse;
       
  1707 
       
  1708     TMmKeyDown bitmapToReset;
       
  1709 
       
  1710         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: scancode 0x%08x, HIDmodifiers 0x%08x"), aScancodeKey, aHIDModifiers));
       
  1711 
       
  1712     switch (aScancodeKey)
       
  1713         {
       
  1714 
       
  1715         // Mappings for Nokia SU-8W
       
  1716         // Key down events are stored into bitmap in order to detect if keys are released in reverse order, which caused jamming.
       
  1717         // For example: control key released before arrow key.
       
  1718 
       
  1719         case EStdKeyUpArrow:
       
  1720             {
       
  1721             if (aHIDModifiers & (KHidModifierCtrl | KHidModifierCtrlRight)
       
  1722                     || iMmKeyDown & EVolUp)
       
  1723                 {
       
  1724                 scancode = EStdKeyIncVolume; //Volume Up = Ctrl + ArrowUp
       
  1725                 isMmKey = ETrue;
       
  1726                 // Set or reset flag bit
       
  1727 
       
  1728                 bitmapToReset = EVolUp;
       
  1729                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Volume up %d"), aIsKeyDown));
       
  1730                 }
       
  1731             break;
       
  1732             }
       
  1733 
       
  1734         case EStdKeyDownArrow:
       
  1735             {
       
  1736             if (aHIDModifiers & (KHidModifierCtrl | KHidModifierCtrlRight)
       
  1737                     || iMmKeyDown & EVolDown)
       
  1738                 {
       
  1739                 scancode = EStdKeyDecVolume; //Volume Down = Ctrl + ArrowDown
       
  1740                 isMmKey = ETrue;
       
  1741                 bitmapToReset = EVolDown;
       
  1742                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Volume down %d"), aIsKeyDown));
       
  1743                 }
       
  1744             break;
       
  1745             }
       
  1746 
       
  1747         case EStdKeyRightArrow:
       
  1748             {
       
  1749             if (aHIDModifiers & KHidModifierAlt || iMmKeyDown & EPlay)
       
  1750                 {
       
  1751                 scancode = EStdKeyApplication2; //Play = Alt + ArrowRight
       
  1752                 isMmKey = ETrue;
       
  1753                 bitmapToReset = EPlay;
       
  1754 
       
  1755                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Play %d"), aIsKeyDown));
       
  1756                 }
       
  1757             else if (aHIDModifiers & (KHidModifierCtrl
       
  1758                     | KHidModifierCtrlRight) || iMmKeyDown & ENext)
       
  1759                 {
       
  1760                 scancode = EStdKeyApplication4; //Next = Ctrl + ArrowRight
       
  1761                 isMmKey = ETrue;
       
  1762                 bitmapToReset = ENext;
       
  1763                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Next %d"), aIsKeyDown));
       
  1764                 }
       
  1765             break;
       
  1766             }
       
  1767 
       
  1768         case EStdKeyLeftArrow:
       
  1769             {
       
  1770             if (aHIDModifiers & KHidModifierAlt || iMmKeyDown & EStop)
       
  1771                 {
       
  1772                 scancode = EStdKeyApplication3; //Stop	= Alt + ArrowLeft
       
  1773                 isMmKey = ETrue;
       
  1774                 bitmapToReset = EStop;
       
  1775                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Stop %d"), aIsKeyDown));
       
  1776                 }
       
  1777             else if (aHIDModifiers & (KHidModifierCtrl
       
  1778                     | KHidModifierCtrlRight) || iMmKeyDown & EPrev)
       
  1779                 {
       
  1780                 scancode = EStdKeyApplication5; //Prev	= Ctrl + ArrowLeft
       
  1781                 isMmKey = ETrue;
       
  1782                 bitmapToReset = EPrev;
       
  1783                     TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Prev %d"), aIsKeyDown));
       
  1784                 }
       
  1785             break;
       
  1786             }
       
  1787 
       
  1788         default:
       
  1789             break;
       
  1790         }
       
  1791 
       
  1792     if (isMmKey)
       
  1793         {
       
  1794         ResetBitmap(aIsKeyDown, bitmapToReset);
       
  1795         SendRawEvent(scancode, aIsKeyDown, modifier);
       
  1796         }
       
  1797     return isMmKey;
       
  1798     }
       
  1799 
       
  1800 TBool CHidKeyboardDriver::HandleMultimediaKeysForStandard(
       
  1801         TUint16 aScancodeKey, TBool aIsKeyDown, TUint8 aHIDModifiers)
       
  1802     {
       
  1803     TInt scancode = 0;
       
  1804     TUint modifier = 0;
       
  1805     TBool isMmKey = EFalse;
       
  1806 
       
  1807         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: scancode 0x%08x, HIDmodifiers 0x%08x"), aScancodeKey, aHIDModifiers));
       
  1808     //please complier...
       
  1809     (void) aHIDModifiers;
       
  1810 
       
  1811     switch (aScancodeKey)
       
  1812         {
       
  1813         // Mappings for standard keyboards
       
  1814 
       
  1815         case EStdKeyApplication2: //Play
       
  1816             {
       
  1817             scancode = EStdKeyApplication2;
       
  1818             isMmKey = ETrue;
       
  1819                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Play %d"), aIsKeyDown));
       
  1820             break;
       
  1821             }
       
  1822 
       
  1823         case EStdKeyApplication3: //Stop
       
  1824             {
       
  1825             scancode = EStdKeyApplication3;
       
  1826             isMmKey = ETrue;
       
  1827                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Stop %d"), aIsKeyDown));
       
  1828             break;
       
  1829             }
       
  1830 
       
  1831         case EStdKeyApplication4: //Next
       
  1832             {
       
  1833             scancode = EStdKeyApplication4;
       
  1834             isMmKey = ETrue;
       
  1835                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Next %d"), aIsKeyDown));
       
  1836             break;
       
  1837             }
       
  1838 
       
  1839         case EStdKeyApplication5: //Prev
       
  1840             {
       
  1841             scancode = EStdKeyApplication5;
       
  1842             isMmKey = ETrue;
       
  1843                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Prev %d"), aIsKeyDown));
       
  1844             break;
       
  1845             }
       
  1846 
       
  1847         case EStdKeyIncVolume: //Volume up
       
  1848             {
       
  1849             scancode = EStdKeyIncVolume;
       
  1850             isMmKey = ETrue;
       
  1851                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Volume up %d"), aIsKeyDown));
       
  1852             break;
       
  1853             }
       
  1854 
       
  1855         case EStdKeyDecVolume: //Volume down
       
  1856             {
       
  1857             scancode = EStdKeyDecVolume;
       
  1858             isMmKey = ETrue;
       
  1859                 TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::HandleNokiaMultimediaKeys: Volume down %d"), aIsKeyDown));
       
  1860             break;
       
  1861             }
       
  1862 
       
  1863         default:
       
  1864             break;
       
  1865         }
       
  1866 
       
  1867     if (isMmKey)
       
  1868         {
       
  1869         SendRawEvent(scancode, aIsKeyDown, modifier);
       
  1870         }
       
  1871     return isMmKey;
       
  1872     }
       
  1873 
       
  1874 // ----------------------------------------------------------------------
       
  1875 // CHidKeyboardDriver::SendRawEvent
       
  1876 // Send raw key event to window server
       
  1877 // ----------------------------------------------------------------------
       
  1878 TInt CHidKeyboardDriver::SendRawEvent(TInt aScancode, TBool aIsKeyDown,
       
  1879         TUint aModifier)
       
  1880     {
       
  1881     TRawEvent rawEvent;
       
  1882     TInt err = KErrNone;
       
  1883 
       
  1884         TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::SendRawEvent: scancode %d, modifier: %d, keydown: %d"), aScancode, aModifier, aIsKeyDown ));
       
  1885     if (aScancode != 0)
       
  1886         {
       
  1887         if (aIsKeyDown)
       
  1888             rawEvent.Set(TRawEvent::EKeyDown, aScancode);
       
  1889         else
       
  1890             rawEvent.Set(TRawEvent::EKeyUp, aScancode); //This will never be called for +,* and #
       
  1891 
       
  1892         TEventModifier eventmodifier = (TEventModifier) -1; //all bits set to 1.
       
  1893         TModifierState modifierstate = (TModifierState) aModifier;
       
  1894             TRACE_INFO( (_L("[HID]\tCHidKeyboardDriver::SendRawEvents: modifiers %d, modifierState: %d"), aModifier, (TUint)modifierstate));
       
  1895 
       
  1896         err = iWsSession.SetModifierState(eventmodifier, modifierstate);
       
  1897         iWsSession.SimulateRawEvent(rawEvent);
       
  1898         iWsSession.Flush();
       
  1899         }
       
  1900     return err;
       
  1901     }
       
  1902 
       
  1903 //----------------------------------------------------------------------------
       
  1904 // CHidKeyboardDriver::SupportedFieldCount
       
  1905 //----------------------------------------------------------------------------
       
  1906 //
       
  1907 TInt CHidKeyboardDriver::SupportedFieldCount()
       
  1908     {
       
  1909     return iSupportedFieldCount;
       
  1910     }
       
  1911 
       
  1912 //----------------------------------------------------------------------------
       
  1913 // CHidKeyboardDriver::SetInputHandlingReg
       
  1914 //----------------------------------------------------------------------------
       
  1915 //
       
  1916 void CHidKeyboardDriver::SetInputHandlingReg(
       
  1917         CHidInputDataHandlingReg* aHandlingReg)
       
  1918     {
       
  1919     iInputHandlingReg = aHandlingReg;
       
  1920     }
       
  1921 
       
  1922 // ----------------------------------------------------------------------
       
  1923 // CHidKeyboardDriver::TimerExpired
       
  1924 // Callback function from CTimeOutTimer
       
  1925 // ----------------------------------------------------------------------
       
  1926 void CHidKeyboardDriver::TimerExpired()
       
  1927     {
       
  1928     DBG(RDebug::Print(_L("[HID]\tCHidKeyboardDriver::TimerExpired, cancel all key presses")));
       
  1929     CancelAllKeys();
       
  1930     }
       
  1931 
       
  1932 // End of file