[HIDPARSER]
[reactos.git] / lib / drivers / hidparser / api.c
index 45765f0..a3abc9f 100644 (file)
 
 #include "parser.h"
 
-
-ULONG
-HidParser_NumberOfTopCollections(
-    IN PHID_PARSER Parser)
-{
-    PHID_PARSER_CONTEXT ParserContext;
-
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-    ASSERT(ParserContext->RootCollection);
-    ASSERT(ParserContext->RootCollection->NodeCount);
-
-    //
-    // number of top collections
-    //
-    return ParserContext->RootCollection->NodeCount;
-}
-
-PHID_COLLECTION
-HidParser_GetCollection(
-    IN PHID_PARSER Parser,
-    IN ULONG CollectionNumber)
-{
-    PHID_PARSER_CONTEXT ParserContext;
-
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-    ASSERT(ParserContext->RootCollection);
-    ASSERT(ParserContext->RootCollection->NodeCount);
-
-    //
-    // is collection index out of bounds
-    //
-    if (CollectionNumber < ParserContext->RootCollection->NodeCount)
-    {
-        //
-        // valid collection
-        //
-        return ParserContext->RootCollection->Nodes[CollectionNumber];
-    }
-
-    //
-    // no such collection
-    //
-    Parser->Debug("HIDPARSE] No such collection %lu\n", CollectionNumber);
-    return NULL;
-}
-
-PHID_REPORT
-HidParser_GetReportByType(
-    IN PHID_PARSER Parser,
-    IN ULONG ReportType)
-{
-    PHID_PARSER_CONTEXT ParserContext;
-    ULONG Index;
-    ULONG ReportCount = 0;
-
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-    for(Index = 0; Index < ParserContext->ReportCount; Index++)
-    {
-        //
-        // check if the report type match
-        //
-        if (ParserContext->Reports[Index]->Type == ReportType)
-        {
-            //
-            // found report
-            //
-            return ParserContext->Reports[Index];
-        }
-    }
-
-    //
-    // report not found
-    //
-    return NULL;
-}
-
-
-ULONG
-HidParser_NumberOfReports(
-    IN PHID_PARSER Parser,
-    IN ULONG ReportType)
+static ULONG KeyboardScanCodes[256] =
 {
-    PHID_PARSER_CONTEXT ParserContext;
-    ULONG Index;
-    ULONG ReportCount = 0;
-
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-    for(Index = 0; Index < ParserContext->ReportCount; Index++)
-    {
-        //
-        // check if the report type match
-        //
-        if (ParserContext->Reports[Index]->Type == ReportType)
-        {
-            //
-            // found report
-            //
-            ReportCount++;
-        }
-    }
-
-    //
-    // done
-    //
-    return ReportCount;
-}
+    0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
+    50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
+    4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
+    27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
+    65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
+    105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
+    72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
+    191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
+    115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
+    122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
+    150,158,159,128,136,177,178,176,142,152,173,140
+};
 
 HIDPARSER_STATUS
 HidParser_GetCollectionUsagePage(
-    IN PHID_PARSER Parser,
-    IN ULONG CollectionIndex,
+    IN PVOID CollectionContext,
     OUT PUSHORT Usage,
     OUT PUSHORT UsagePage)
 {
@@ -172,7 +42,7 @@ HidParser_GetCollectionUsagePage(
     //
     // find collection
     //
-    Collection = HidParser_GetCollection(Parser, CollectionIndex);
+    Collection = HidParser_GetCollectionFromContext(CollectionContext);
     if (!Collection)
     {
         //
@@ -191,32 +61,16 @@ HidParser_GetCollectionUsagePage(
 
 ULONG
 HidParser_GetReportLength(
-    IN PHID_PARSER Parser,
-    IN ULONG ReportType)
+    IN PVOID CollectionContext,
+    IN UCHAR ReportType)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     PHID_REPORT Report;
     ULONG ReportLength;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get first report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -244,55 +98,17 @@ HidParser_GetReportLength(
     return ReportLength;
 }
 
-UCHAR
-HidParser_IsReportIDUsed(
-    IN PHID_PARSER Parser)
-{
-    PHID_PARSER_CONTEXT ParserContext;
-
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // return flag
-    //
-    return ParserContext->UseReportIDs;
-}
-
 ULONG
 HidParser_GetReportItemCountFromReportType(
-    IN PHID_PARSER Parser,
-    IN ULONG ReportType)
+    IN PVOID CollectionContext,
+    IN UCHAR ReportType)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     PHID_REPORT Report;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -310,34 +126,18 @@ HidParser_GetReportItemCountFromReportType(
 
 ULONG
 HidParser_GetReportItemTypeCountFromReportType(
-    IN PHID_PARSER Parser,
-    IN ULONG ReportType,
+    IN PVOID CollectionContext,
+    IN UCHAR ReportType,
     IN ULONG bData)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     ULONG Index;
     PHID_REPORT Report;
     ULONG ItemCount = 0;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -354,14 +154,14 @@ HidParser_GetReportItemTypeCountFromReportType(
         //
         // check item type
         //
-        if (Report->Items[Index]->HasData && bData == TRUE)
+        if (Report->Items[Index].HasData && bData == TRUE)
         {
             //
             // found data item
             //
             ItemCount++;
         }
-        else if (Report->Items[Index]->HasData == FALSE && bData == FALSE)
+        else if (Report->Items[Index].HasData == FALSE && bData == FALSE)
         {
             //
             // found value item
@@ -376,84 +176,6 @@ HidParser_GetReportItemTypeCountFromReportType(
     return ItemCount;
 }
 
-ULONG
-HidParser_GetContextSize(
-    IN PHID_PARSER Parser)
-{
-    //
-    // FIXME the context must contain all parsed info
-    //
-    return sizeof(HID_PARSER_CONTEXT);
-}
-
-VOID
-HidParser_FreeContext(
-    IN PHID_PARSER Parser,
-    IN PUCHAR Context,
-    IN ULONG ContextLength)
-{
-    //
-    // FIXME implement freeing of parsed info
-    //
-}
-
-HIDPARSER_STATUS
-HidParser_AllocateParser(
-    IN PHIDPARSER_ALLOC_FUNCTION AllocFunction,
-    IN PHIDPARSER_FREE_FUNCTION FreeFunction,
-    IN PHIDPARSER_ZERO_FUNCTION ZeroFunction,
-    IN PHIDPARSER_COPY_FUNCTION CopyFunction,
-    IN PHIDPARSER_DEBUG_FUNCTION DebugFunction,
-    OUT PHID_PARSER *OutParser)
-{
-    PHID_PARSER Parser;
-    PHID_PARSER_CONTEXT ParserContext;
-
-    //
-    // allocate 
-    //
-    Parser = (PHID_PARSER)AllocFunction(sizeof(HID_PARSER));
-    if (!Parser)
-    {
-        //
-        // no memory
-        //
-        return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // allocate parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)AllocFunction(sizeof(HID_PARSER_CONTEXT));
-    if (!ParserContext)
-    {
-        //
-        // no memory
-        //
-        FreeFunction(Parser);
-        return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-
-    //
-    // init parser
-    //
-    Parser->Alloc = AllocFunction;
-    Parser->Free = FreeFunction;
-    Parser->Zero = ZeroFunction;
-    Parser->Copy = CopyFunction;
-    Parser->Debug = DebugFunction;
-    Parser->ParserContext = ParserContext;
-
-    //
-    // store result
-    //
-    *OutParser = Parser;
-    //
-    // success
-    //
-    return HIDPARSER_STATUS_SUCCESS;
-}
 
 VOID
 HidParser_InitParser(
@@ -462,7 +184,6 @@ HidParser_InitParser(
     IN PHIDPARSER_ZERO_FUNCTION ZeroFunction,
     IN PHIDPARSER_COPY_FUNCTION CopyFunction,
     IN PHIDPARSER_DEBUG_FUNCTION DebugFunction,
-    IN PVOID ParserContext,
     OUT PHID_PARSER Parser)
 {
     Parser->Alloc = AllocFunction;
@@ -470,84 +191,23 @@ HidParser_InitParser(
     Parser->Zero = ZeroFunction;
     Parser->Copy = CopyFunction;
     Parser->Debug = DebugFunction;
-    Parser->ParserContext = ParserContext;
-}
-
-ULONG
-HidParser_GetCollectionCount(
-    IN PHID_COLLECTION Collection)
-{
-    ULONG Index;
-    ULONG Count = Collection->NodeCount;
-
-    for(Index = 0; Index < Collection->NodeCount; Index++)
-    {
-        //
-        // count collection for sub nodes
-        //
-        Count += HidParser_GetCollectionCount(Collection->Nodes[Index]);
-    }
-
-    //
-    // done
-    //
-    return Count;
-}
-
-ULONG
-HidParser_GetTotalCollectionCount(
-    IN PHID_PARSER Parser)
-{
-    PHID_PARSER_CONTEXT ParserContext;
-
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity check
-    //
-    ASSERT(ParserContext);
-    ASSERT(ParserContext->RootCollection);
-
-    //
-    // count collections
-    //
-    return HidParser_GetCollectionCount(ParserContext->RootCollection);
 }
 
 ULONG
 HidParser_GetMaxUsageListLengthWithReportAndPage(
-    IN PHID_PARSER Parser,
-    IN ULONG ReportType,
+    IN PVOID CollectionContext,
+    IN UCHAR ReportType,
     IN USAGE  UsagePage  OPTIONAL)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     ULONG Index;
     PHID_REPORT Report;
     ULONG ItemCount = 0;
     USHORT CurrentUsagePage;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -561,8 +221,8 @@ HidParser_GetMaxUsageListLengthWithReportAndPage(
         //
         // check usage page
         //
-        CurrentUsagePage = (Report->Items[Index]->UsageMinimum >> 16);
-        if (CurrentUsagePage == UsagePage && Report->Items[Index]->HasData)
+        CurrentUsagePage = (Report->Items[Index].UsageMinimum >> 16);
+        if (CurrentUsagePage == UsagePage && Report->Items[Index].HasData)
         {
             //
             // found item
@@ -580,38 +240,23 @@ HidParser_GetMaxUsageListLengthWithReportAndPage(
 HIDPARSER_STATUS
 HidParser_GetSpecificValueCapsWithReport(
     IN PHID_PARSER Parser,
-    IN ULONG ReportType,
+    IN PVOID CollectionContext,
+    IN UCHAR ReportType,
     IN USHORT UsagePage,
     IN USHORT Usage,
     OUT PHIDP_VALUE_CAPS  ValueCaps,
     IN OUT PULONG  ValueCapsLength)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     ULONG Index;
     PHID_REPORT Report;
     ULONG ItemCount = 0;
     USHORT CurrentUsagePage;
     USHORT CurrentUsage;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -625,8 +270,8 @@ HidParser_GetSpecificValueCapsWithReport(
         //
         // check usage page
         //
-        CurrentUsagePage = (Report->Items[Index]->UsageMinimum >> 16);
-        CurrentUsage = (Report->Items[Index]->UsageMinimum & 0xFFFF);
+        CurrentUsagePage = (Report->Items[Index].UsageMinimum >> 16);
+        CurrentUsage = (Report->Items[Index].UsageMinimum & 0xFFFF);
 
         if ((Usage == CurrentUsage && UsagePage == CurrentUsagePage) || (Usage == 0 && UsagePage == CurrentUsagePage) || (Usage == CurrentUsage && UsagePage == 0) || (Usage == 0 && UsagePage == 0))
         {
@@ -645,10 +290,10 @@ HidParser_GetSpecificValueCapsWithReport(
                 //
                 ValueCaps[ItemCount].UsagePage = CurrentUsagePage;
                 ValueCaps[ItemCount].ReportID = Report->ReportID;
-                ValueCaps[ItemCount].LogicalMin = Report->Items[Index]->Minimum;
-                ValueCaps[ItemCount].LogicalMax = Report->Items[Index]->Maximum;
-                ValueCaps[ItemCount].IsAbsolute = !Report->Items[Index]->Relative;
-                ValueCaps[ItemCount].BitSize = Report->Items[Index]->BitCount;
+                ValueCaps[ItemCount].LogicalMin = Report->Items[Index].Minimum;
+                ValueCaps[ItemCount].LogicalMax = Report->Items[Index].Maximum;
+                ValueCaps[ItemCount].IsAbsolute = !Report->Items[Index].Relative;
+                ValueCaps[ItemCount].BitSize = Report->Items[Index].BitCount;
 
                 //
                 // FIXME: FILLMEIN
@@ -685,14 +330,14 @@ HidParser_GetSpecificValueCapsWithReport(
 HIDPARSER_STATUS
 HidParser_GetUsagesWithReport(
     IN PHID_PARSER Parser,
-    IN ULONG  ReportType,
+    IN PVOID CollectionContext,
+    IN UCHAR  ReportType,
     IN USAGE  UsagePage,
     OUT USAGE  *UsageList,
     IN OUT PULONG UsageLength,
     IN PCHAR  ReportDescriptor,
     IN ULONG  ReportDescriptorLength)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     ULONG Index;
     PHID_REPORT Report;
     ULONG ItemCount = 0;
@@ -701,25 +346,10 @@ HidParser_GetUsagesWithReport(
     UCHAR Activated;
     ULONG Data;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -741,7 +371,7 @@ HidParser_GetUsagesWithReport(
         //
         // get report item
         //
-        ReportItem = Report->Items[Index];
+        ReportItem = &Report->Items[Index];
 
         //
         // does it have data
@@ -832,40 +462,24 @@ HidParser_GetUsagesWithReport(
 HIDPARSER_STATUS
 HidParser_GetScaledUsageValueWithReport(
     IN PHID_PARSER Parser,
-    IN ULONG ReportType,
+    IN PVOID CollectionContext,
+    IN UCHAR ReportType,
     IN USAGE UsagePage,
     IN USAGE  Usage,
     OUT PLONG UsageValue,
     IN PCHAR ReportDescriptor,
     IN ULONG ReportDescriptorLength)
 {
-    PHID_PARSER_CONTEXT ParserContext;
     ULONG Index;
     PHID_REPORT Report;
-    ULONG ItemCount = 0;
     USHORT CurrentUsagePage;
     PHID_REPORT_ITEM ReportItem;
     ULONG Data;
 
-    //
-    // get parser context
-    //
-    ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
-
-    //
-    // sanity checks
-    //
-    ASSERT(ParserContext);
-
-    //
-    // FIXME support multiple top collecions
-    //
-    ASSERT(ParserContext->RootCollection->NodeCount == 1);
-
     //
     // get report
     //
-    Report = HidParser_GetReportByType(Parser, ReportType);
+    Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
     if (!Report)
     {
         //
@@ -887,7 +501,7 @@ HidParser_GetScaledUsageValueWithReport(
         //
         // get report item
         //
-        ReportItem = Report->Items[Index];
+        ReportItem = &Report->Items[Index];
 
         //
         // check usage page
@@ -951,3 +565,106 @@ HidParser_GetScaledUsageValueWithReport(
     //
     return HIDPARSER_STATUS_USAGE_NOT_FOUND;
 }
+
+ULONG
+HidParser_GetScanCode(
+    IN USAGE Usage)
+{
+    if (Usage < sizeof(KeyboardScanCodes) / sizeof(KeyboardScanCodes[0]))
+    {
+        //
+        // valid usage
+        //
+        return KeyboardScanCodes[Usage];
+    }
+
+    //
+    // invalid usage
+    //
+    return 0;
+}
+
+VOID
+HidParser_DispatchKey(
+    IN PCHAR ScanCodes,
+    IN HIDP_KEYBOARD_DIRECTION KeyAction,
+    IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
+    IN PVOID InsertCodesContext)
+{
+    ULONG Index;
+    ULONG Length = 0;
+
+    //
+    // count code length
+    //
+    for(Index = 0; Index < sizeof(ULONG); Index++)
+    {
+        if (ScanCodes[Index] == 0)
+        {
+            //
+            // last scan code
+            //
+            break;
+        }
+
+        //
+        // is this a key break
+        //
+        if (KeyAction == HidP_Keyboard_Break)
+        {
+            //
+            // add break
+            //
+            ScanCodes[Index] |= KEY_BREAK;
+        }
+
+        //
+        // more scan counts
+        //
+        Length++;
+    }
+
+    if (Length > 0)
+    {
+         //
+         // dispatch scan codes
+         //
+         InsertCodesProcedure(InsertCodesContext, ScanCodes, Length);
+    }
+}
+
+
+HIDPARSER_STATUS
+HidParser_TranslateUsage(
+    IN PHID_PARSER Parser,
+    IN USAGE Usage,
+    IN HIDP_KEYBOARD_DIRECTION  KeyAction,
+    IN OUT PHIDP_KEYBOARD_MODIFIER_STATE  ModifierState,
+    IN PHIDP_INSERT_SCANCODES  InsertCodesProcedure,
+    IN PVOID  InsertCodesContext)
+{
+    ULONG ScanCode;
+
+    //
+    // get scan code
+    //
+    ScanCode = HidParser_GetScanCode(Usage);
+    if (!ScanCode)
+    {
+        //
+        // invalid lookup or no scan code available
+        //
+        return HIDPARSER_STATUS_I8042_TRANS_UNKNOWN;
+    }
+
+    //
+    // FIXME: translate modifier states
+    //
+
+    HidParser_DispatchKey((PCHAR)&ScanCode, KeyAction, InsertCodesProcedure, InsertCodesContext);
+
+    //
+    // done
+    //
+    return HIDPARSER_STATUS_SUCCESS;
+}