#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)
{
//
// find collection
//
- Collection = HidParser_GetCollection(Parser, CollectionIndex);
+ Collection = HidParser_GetCollectionFromContext(CollectionContext);
if (!Collection)
{
//
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)
{
//
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)
{
//
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)
{
//
//
// 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
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(
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;
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)
{
//
//
// 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
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)
{
//
//
// 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))
{
//
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
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;
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)
{
//
//
// get report item
//
- ReportItem = Report->Items[Index];
+ ReportItem = &Report->Items[Index];
//
// does it have data
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)
{
//
//
// get report item
//
- ReportItem = Report->Items[Index];
+ ReportItem = &Report->Items[Index];
//
// check usage page
//
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;
+}