bluetoothengine/bthid/mouse/hidmousedriver/src/mouse.cpp
changeset 0 f63038272f30
child 16 b23265fb36da
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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 <apacmdln.h>
       
    26 #include <apgtask.h>
       
    27 #include <coemain.h>
       
    28 
       
    29 #include <e32property.h>
       
    30 #include "bthidPsKey.h"
       
    31 
       
    32 #include "hidtranslate.h"
       
    33 #include "finder.h"
       
    34 #include "mouse.h"
       
    35 #include "debug.h"
       
    36 
       
    37 
       
    38 #ifndef DBG
       
    39 #ifdef _DEBUG
       
    40 #define DBG(a) a
       
    41 #else
       
    42 #define DBG(a)
       
    43 #endif
       
    44 #endif
       
    45 
       
    46 // Application UIDs for PaintCursor app.
       
    47 _LIT(KAppName, "PaintCursor.exe");
       
    48 // ----------------------------------------------------------------------
       
    49 
       
    50 CHidMouseDriver::CHidMouseDriver(MDriverAccess* aGenericHid)
       
    51         : iDriverState(EUninitialised), iGenericHid(aGenericHid),
       
    52         iButtonDown (EFalse), iButton2Down(EFalse)
       
    53     {
       
    54     DBG(RDebug::Print(
       
    55             _L("[HID]\tCHidMouseDriver::CHidMouseDriver ENTER")));
       
    56     DBG(RDebug::Print(
       
    57             _L("[HID]\tCHidMouseDriver::CHidMouseDriver(0x%08x)"), aGenericHid));
       
    58     }
       
    59 
       
    60 CHidMouseDriver* CHidMouseDriver::NewLC(MDriverAccess* aGenericHid)
       
    61     {
       
    62     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::NewLC(0x%08x)"), aGenericHid));
       
    63     CHidMouseDriver* self =
       
    64         new (ELeave) CHidMouseDriver(aGenericHid);
       
    65     CleanupStack::PushL(self);
       
    66     self->ConstructL();
       
    67 
       
    68     return self;
       
    69     }
       
    70 
       
    71 CHidMouseDriver* CHidMouseDriver::NewL(MDriverAccess* aGenericHid)
       
    72     {
       
    73     CHidMouseDriver* self =
       
    74         CHidMouseDriver::NewLC(aGenericHid);
       
    75     CleanupStack::Pop();
       
    76     return self;
       
    77     }
       
    78 
       
    79 void CHidMouseDriver::ConstructL()
       
    80     {
       
    81     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver{0x%08x}::ConstructL() BEGIN"), this));
       
    82 
       
    83     User::LeaveIfNull(iGenericHid);
       
    84 
       
    85     TInt err = iPointBufQueue.OpenGlobal(KMsgBTMouseBufferQueue);   
       
    86     if (err == KErrNotFound)
       
    87         {
       
    88         User::LeaveIfError(iPointBufQueue.CreateGlobal(KMsgBTMouseBufferQueue, KPointQueueLen));    
       
    89         }
       
    90     else
       
    91         {
       
    92         User::LeaveIfError( err );
       
    93         } 
       
    94     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver{0x%08x}::ConstructL() END"), this));
       
    95     // Create a session with the window server:
       
    96     User::LeaveIfError(iWsSession.Connect());
       
    97     }
       
    98 
       
    99 
       
   100 
       
   101 
       
   102 CHidMouseDriver::~CHidMouseDriver()
       
   103     {
       
   104     DBG(RDebug::Print(_L("[HID]\t~CHidMouseDriver() 0x%08x"), this));
       
   105 
       
   106     iPointBufQueue.Close();
       
   107 
       
   108     if (iDriverState == EInitialised || iDriverState == EDisabled )
       
   109         {
       
   110         RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorHide );
       
   111         }
       
   112 
       
   113     iWsSession.Close();
       
   114     }
       
   115 
       
   116 void CHidMouseDriver::MoveCursor(const TPoint& aPoint)
       
   117     {
       
   118     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::MoveCursor()")));
       
   119     PostPointer(aPoint);
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // CHidMouseDriver::PostPointer
       
   124 // Save the event to the buffer
       
   125 // ---------------------------------------------------------------------------
       
   126 //
       
   127 TInt CHidMouseDriver::PostPointer(const TPoint& aPoint)
       
   128     {
       
   129     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::PostPointer()")));
       
   130     iPointerBuffer.iPoint[iPointerBuffer.iNum] = aPoint;
       
   131     iPointerBuffer.iType[iPointerBuffer.iNum]  = KBufferPlainPointer;
       
   132     iPointerBuffer.iNum++;
       
   133     TInt ret = KErrNone;
       
   134 
       
   135     if(iPointerBuffer.iNum > KPMaxEvent)
       
   136         {
       
   137         ret = iPointBufQueue.Send(iPointerBuffer);
       
   138         iPointerBuffer.iNum = 0;
       
   139         }
       
   140     return ret;
       
   141     }
       
   142 
       
   143 TInt CHidMouseDriver::SendButtonEvent(TBool aButtonDown)
       
   144     {
       
   145 
       
   146     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::SendButtonEvent() %d"), aButtonDown));
       
   147     iPointerBuffer.iPoint[iPointerBuffer.iNum] = TPoint (0,0);
       
   148     iPointerBuffer.iType[iPointerBuffer.iNum]  = aButtonDown ? KBufferPenDown : KBufferPenUp;
       
   149     iPointerBuffer.iNum++;
       
   150     TInt ret = iPointBufQueue.Send(iPointerBuffer);
       
   151     iPointerBuffer.iNum = 0;
       
   152     return ret;
       
   153     }
       
   154 
       
   155 void CHidMouseDriver::StartL(TInt /*aConnectionId*/)
       
   156     {
       
   157     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::StartL()")));
       
   158 
       
   159     // Ready to process mouse events:
       
   160     iDriverState = EInitialised;
       
   161     LaunchApplicationL(KAppName);
       
   162     RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorShow );
       
   163     }
       
   164 
       
   165 
       
   166 
       
   167 void CHidMouseDriver::InitialiseL(TInt aConnectionId)
       
   168     {
       
   169     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::InitialiseL(%d)"),
       
   170                       aConnectionId));
       
   171 
       
   172     // Store the connection ID:
       
   173     iConnectionId = aConnectionId;
       
   174     }
       
   175 
       
   176 void CHidMouseDriver::Stop()
       
   177     {
       
   178     iDriverState = EDisabled;
       
   179     RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorHide );
       
   180     }
       
   181 
       
   182 //----------------------------------------------------------------------------
       
   183 // CHidMouseDriver::LaunchApplicationL
       
   184 //----------------------------------------------------------------------------
       
   185 //
       
   186 void CHidMouseDriver::LaunchApplicationL(const TDesC& aName)
       
   187     {
       
   188     //Check if application is already running in the background
       
   189     TApaTaskList tasks( iWsSession );
       
   190     TApaTask task = tasks.FindApp( aName );
       
   191 
       
   192     if ( task.Exists() )
       
   193         {
       
   194         // Application is active, so just bring to foreground
       
   195         }
       
   196     else
       
   197         {
       
   198         // If application is not running, then create a new one
       
   199         CApaCommandLine* cmd = CApaCommandLine::NewLC();
       
   200 
       
   201         cmd->SetExecutableNameL(aName);
       
   202         cmd->SetCommandL(EApaCommandBackground); // EApaCommandRun
       
   203 
       
   204         RApaLsSession arcSession;
       
   205         //connect to AppArc server
       
   206         User::LeaveIfError(arcSession.Connect());
       
   207         CleanupClosePushL(arcSession);
       
   208         User::LeaveIfError( arcSession.StartApp(*cmd) );
       
   209         arcSession.Close();
       
   210 
       
   211         CleanupStack::PopAndDestroy(2);
       
   212         }
       
   213     }
       
   214 // ----------------------------------------------------------------------
       
   215 // CHidDriver mandatory functions:
       
   216 
       
   217 TInt CHidMouseDriver::DataIn(
       
   218     CHidTransport::THidChannelType aChannel, const TDesC8& aPayload)
       
   219     {
       
   220     TInt err = KErrNone;
       
   221     switch (aChannel)
       
   222         {
       
   223         case CHidTransport::EHidChannelInt:
       
   224         if (EInitialised == iDriverState)
       
   225             {
       
   226             TInt mouseStatus;
       
   227             TInt err = RProperty::Get( KPSUidBthidSrv, KBTMouseCursorState, mouseStatus );
       
   228             if ( !err && (static_cast<THidMouseCursorState>(mouseStatus) == ECursorHide) )
       
   229                 {
       
   230                 err = RProperty::Set( KPSUidBthidSrv, KBTMouseCursorState, ECursorShow );
       
   231                 }
       
   232             InterruptData(aPayload);
       
   233             }
       
   234         break;
       
   235 
       
   236         case CHidTransport::EHidChannelCtrl:
       
   237         break;
       
   238 
       
   239         default:
       
   240         break;
       
   241         }
       
   242     return err;
       
   243     }
       
   244 
       
   245 void CHidMouseDriver::CommandResult(TInt /*aCmdAck*/)
       
   246     {
       
   247     // No implementation as we don't issue any requests to be acknowledged
       
   248     }
       
   249 
       
   250 void CHidMouseDriver::Disconnected(TInt aReason)
       
   251     {
       
   252     RDebug::Print(_L("[HID]\tCHidMouseDriver::Disconnected(%d)"), aReason);
       
   253     Stop();
       
   254     }
       
   255 
       
   256 // ----------------------------------------------------------------------
       
   257 
       
   258 void CHidMouseDriver::InterruptData(const TDesC8& aPayload)
       
   259     {
       
   260     // If the report has a report ID, it is in the first byte.
       
   261     // If not, this value is ignored (see CField::IsInReport()).
       
   262     //
       
   263     TInt firstByte = aPayload[0];
       
   264 
       
   265     DBG(for (TInt ii = 0; ii < aPayload.Length(); ii++)
       
   266         {
       
   267         TInt nextByte = aPayload[ii];
       
   268         DBG(RDebug::Print(
       
   269                 _L("[HID]\tCHidKeyboardDriver::InterruptData()  report[%d] =  %d"),
       
   270                 ii, nextByte));
       
   271         })
       
   272 
       
   273     DBG(RDebug::Print(
       
   274             _L("[HID]\tCHidMouseDriver::InterruptData(), report %d, length %d"),
       
   275             firstByte, aPayload.Length()));
       
   276 
       
   277     if (iField[EXY] && iField[EXY]->IsInReport(firstByte))
       
   278         {
       
   279         UpdateXY(EXY, aPayload);
       
   280         }
       
   281 
       
   282     if (iField[EButtons] && iField[EButtons]->IsInReport(firstByte))
       
   283         {
       
   284         UpdateButtons(EButtons, aPayload);
       
   285         }
       
   286     if (iField[EXY] && iField[EXY]->IsInReport(firstByte))
       
   287         {
       
   288         UpdateWheel(EWheel, aPayload);
       
   289         }
       
   290     }
       
   291 
       
   292 // ----------------------------------------------------------------------
       
   293 
       
   294 void CHidMouseDriver::UpdateXY(TInt aFieldIndex,
       
   295                                const TDesC8& aReport)
       
   296     {
       
   297     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateModifiers()")));
       
   298 
       
   299     // Translate the HID usage values into a boot protocol style
       
   300     // modifier bitmask:
       
   301     //
       
   302     TReportTranslator report(aReport, iField[aFieldIndex]);
       
   303 
       
   304     TInt Xvalue = 0;
       
   305     TInt Yvalue = 0;
       
   306 
       
   307     TInt errX = report.GetValue( Xvalue, EGenericDesktopUsageX);
       
   308     TInt errY = report.GetValue( Yvalue, EGenericDesktopUsageY);
       
   309 
       
   310     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateXY (%d,%d)"), Xvalue, Yvalue));
       
   311     if ( ( Xvalue != 0 ) || (Yvalue != 0))
       
   312         {
       
   313         MoveCursor(TPoint(Xvalue, Yvalue));
       
   314         }
       
   315 
       
   316     }
       
   317 
       
   318 void CHidMouseDriver::UpdateWheel(TInt aFieldIndex,
       
   319                                   const TDesC8& aReport)
       
   320     {
       
   321     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateModifiers()")));
       
   322 
       
   323     // Translate the HID usage values into a boot protocol style
       
   324     // modifier bitmask:
       
   325     //
       
   326     TReportTranslator report(aReport, iField[aFieldIndex]);
       
   327 
       
   328     TInt Yvalue = 0;
       
   329 
       
   330     TInt errY = report.GetValue( Yvalue, EGenericDesktopUsageWheel);
       
   331     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateWheel (%d)"), Yvalue));
       
   332 
       
   333     TInt absValue(Abs(Yvalue));
       
   334     if ( (errY == KErrNone) && (absValue >= 1) )
       
   335         {
       
   336         TRawEvent rawEvent;
       
   337         for (TInt ii = 0; ii < absValue; ii++)
       
   338             {
       
   339             rawEvent.Set(TRawEvent::EKeyDown, (Yvalue > 0) ? EStdKeyUpArrow : EStdKeyDownArrow);
       
   340             UserSvr::AddEvent(rawEvent);
       
   341             rawEvent.Set(TRawEvent::EKeyUp, (Yvalue > 0) ? EStdKeyUpArrow : EStdKeyDownArrow);
       
   342             UserSvr::AddEvent(rawEvent);
       
   343             }
       
   344         }
       
   345     }
       
   346 
       
   347 void CHidMouseDriver::UpdateButtons(TInt aFieldIndex,
       
   348                                     const TDesC8& aReport)
       
   349     {
       
   350     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons()")));
       
   351 
       
   352     // Translate the HID usage values into a boot protocol style
       
   353     // modifier bitmask:
       
   354     //
       
   355     TReportTranslator report(aReport, iField[aFieldIndex]);
       
   356 
       
   357     TInt button1 = 0;
       
   358     TInt button2 = 0;
       
   359     TInt button3 = 0;
       
   360 
       
   361     const TInt KButton1 = 1;
       
   362     const TInt KButton2 = 2;
       
   363     const TInt KButton3 = 3;
       
   364     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() %d, %d, %d"),
       
   365                       iField[aFieldIndex]->UsagePage(),
       
   366                       iField[aFieldIndex]->UsageMin(),
       
   367                       iField[aFieldIndex]->UsageMax()));
       
   368 
       
   369     TBool buttonPressed(EFalse);
       
   370     if (report.GetValue( button1, KButton1) == KErrNone && button1)
       
   371         {
       
   372         DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() Button1")));
       
   373         buttonPressed = ETrue;
       
   374         }
       
   375 
       
   376     if (report.GetValue( button2, KButton2) == KErrNone && button2)
       
   377         {
       
   378         DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() Button2")));
       
   379         if (! iButton2Down )
       
   380             {
       
   381             iButton2Down = ETrue;
       
   382             TRawEvent rawEvent;
       
   383             rawEvent.Set(TRawEvent::EKeyDown, EStdKeyApplication0);
       
   384             UserSvr::AddEvent(rawEvent);
       
   385             }
       
   386         }
       
   387     else
       
   388         {
       
   389         if (iButton2Down )
       
   390             {
       
   391             iButton2Down = EFalse;
       
   392             TRawEvent rawEvent;
       
   393             rawEvent.Set(TRawEvent::EKeyUp, EStdKeyApplication0);
       
   394             UserSvr::AddEvent(rawEvent);
       
   395             }
       
   396         }
       
   397 
       
   398     if (report.GetValue( button3, KButton3) == KErrNone && button3)
       
   399         {
       
   400         DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::UpdateButtons() Button3")));
       
   401         buttonPressed = ETrue;
       
   402         }
       
   403 
       
   404     if (buttonPressed)
       
   405         {
       
   406         if ( !iButtonDown )
       
   407             {
       
   408             iButtonDown = ETrue;
       
   409             SendButtonEvent(ETrue);//Send Mouse Button Down
       
   410             }
       
   411         }
       
   412     else
       
   413         {
       
   414         if ( iButtonDown )
       
   415             {
       
   416             iButtonDown = EFalse;
       
   417             SendButtonEvent(EFalse);//Send Mouse Button Up
       
   418             }
       
   419         }
       
   420     }
       
   421 
       
   422 TInt CHidMouseDriver::CanHandleReportL(CReportRoot* aReportRoot)
       
   423     {
       
   424     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::CanHandleReport(0x%08x)"),
       
   425                       aReportRoot));
       
   426     iSupportedFieldCount = 0;
       
   427     // Look for mouse reports:
       
   428 
       
   429     THidFieldSearch search;
       
   430 
       
   431     TMouseFinder finder;
       
   432     search.SearchL(aReportRoot, &finder);
       
   433     DBG(RDebug::Print(_L("[HID]\tCHidMouseDriver::CanHandleReport(): root parsed")));
       
   434     iField[EButtons] = finder.ButtonsField();
       
   435     iField[EXY] = finder.XYField();
       
   436     iField[EWheel] = finder.WheelField();
       
   437 
       
   438     for (TInt i=0; i<KNumInputFieldTypes; ++i)
       
   439         {
       
   440         if (iField[i])
       
   441             {
       
   442             iSupportedFieldCount++;
       
   443             }
       
   444         }
       
   445     
       
   446     TInt valid = KErrHidUnrecognised;
       
   447 
       
   448     // We only require buttons and xy field reports; the
       
   449     // Wheel, LED and consumer keys are optional:
       
   450 
       
   451     if ((iField[EButtons] != 0) && (iField[EXY] != 0))
       
   452         {
       
   453         valid = KErrNone;
       
   454         }
       
   455 
       
   456     DBG(RDebug::Print(
       
   457             _L("[HID]\tCHidMouseDriver::CanHandleReport() returning %d"), valid));
       
   458 
       
   459     return valid;
       
   460     }
       
   461 
       
   462 
       
   463 //----------------------------------------------------------------------------
       
   464 // CHidMouseDriver::SupportedFieldCount
       
   465 //----------------------------------------------------------------------------
       
   466 //
       
   467 TInt CHidMouseDriver::SupportedFieldCount()
       
   468     {
       
   469     return iSupportedFieldCount;
       
   470     }
       
   471 //----------------------------------------------------------------------------
       
   472 // CHidMouseDriver::SetInputHandlingReg
       
   473 //----------------------------------------------------------------------------
       
   474 //
       
   475 void CHidMouseDriver::SetInputHandlingReg(CHidInputDataHandlingReg* aHandlingReg)
       
   476     {
       
   477     iInputHandlingReg = aHandlingReg;
       
   478     }
       
   479 // ----------------------------------------------------------------------