Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

View file

@ -0,0 +1,13 @@
add_definitions(-DUNICODE -D_UNICODE)
list(APPEND SOURCE
context.c
hidparser.c
parser.c
api.c
parser.h)
add_library(hidparser ${SOURCE})
add_dependencies(hidparser bugcodes xdk)
add_pch(hidparser parser.h SOURCE)

View file

@ -0,0 +1,975 @@
/*
* PROJECT: ReactOS HID Parser Library
* LICENSE: GPL - See COPYING in the top level directory
* FILE: lib/drivers/hidparser/api.c
* PURPOSE: HID Parser
* PROGRAMMERS:
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "parser.h"
#define NDEBUG
#include <debug.h>
static ULONG KeyboardScanCodes[256] =
{ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x001e, 0x0030, 0x002e, 0x0020, 0x0012, 0x0021, 0x0022, 0x0023, 0x0017, 0x0024, 0x0025, 0x0026,
/* 1 */ 0x0032, 0x0031, 0x0018, 0x0019, 0x0010, 0x0013, 0x001f, 0x0014, 0x0016, 0x002f, 0x0011, 0x002d, 0x0015, 0x002c, 0x0002, 0x0003,
/* 2 */ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x001c, 0x0001, 0x000e, 0x000f, 0x0039, 0x000c, 0x000d, 0x001a,
/* 3 */ 0x001b, 0x002b, 0x002b, 0x0027, 0x0028, 0x0029, 0x0033, 0x0034, 0x0035, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
/* 4 */ 0x0041, 0x0042, 0x0043, 0x0044, 0x0057, 0x0058, 0xE037, 0x0046, 0x0045, 0xE052, 0xE047, 0xE049, 0xE053, 0xE04F, 0xE051, 0xE04D,
/* 5 */ 0xE04B, 0xE050, 0xE048, 0x0045, 0xE035, 0x0037, 0x004a, 0x004e, 0xE01C, 0x004f, 0x0050, 0x0051, 0x004b, 0x004c, 0x004d, 0x0047,
/* 6 */ 0x0048, 0x0049, 0x0052, 0x0053, 0x0056, 0xE05D, 0xE05E, 0x0075, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be,
/* 7 */ 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x0086, 0x008a, 0x0082, 0x0084, 0x0080, 0x0081, 0x0083, 0x0089, 0x0085, 0x0087, 0x0088, 0x0071,
/* 8 */ 0x0073, 0x0072, 0x0000, 0x0000, 0x0000, 0x0079, 0x0000, 0x0059, 0x005d, 0x007c, 0x005c, 0x005e, 0x005f, 0x0000, 0x0000, 0x0000,
/* 9 */ 0x007a, 0x007b, 0x005a, 0x005b, 0x0055, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* E */ 0x001D, 0x002A, 0x0038, 0xE05B, 0xE01D, 0x0036, 0xE038, 0xE05C, 0x00a4, 0x00a6, 0x00a5, 0x00a3, 0x00a1, 0x0073, 0x0072, 0x0071,
/* F */ 0x0096, 0x009e, 0x009f, 0x0080, 0x0088, 0x00b1, 0x00b2, 0x00b0, 0x008e, 0x0098, 0x00ad, 0x008c, 0x0000, 0x0000, 0x0000, 0x0000,
};
static struct
{
USAGE Usage;
ULONG ScanCode;
} CustomerScanCodes[] =
{
{ 0x00B5, 0xE019 },
{ 0x00B6, 0xE010 },
{ 0x00B7, 0xE024 },
{ 0x00CD, 0xE022 },
{ 0x00E2, 0xE020 },
{ 0x00E9, 0xE030 },
{ 0x00EA, 0xE02E },
{ 0x0183, 0xE06D },
{ 0x018A, 0xE06C },
{ 0x0192, 0xE021 },
{ 0x0194, 0xE06B },
{ 0x0221, 0xE065 },
{ 0x0223, 0xE032 },
{ 0x0224, 0xE06A },
{ 0x0225, 0xE069 },
{ 0x0226, 0xE068 },
{ 0x0227, 0xE067 },
{ 0x022A, 0xE066 },
};
#define NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
HIDPARSER_STATUS
HidParser_GetCollectionUsagePage(
IN PVOID CollectionContext,
OUT PUSHORT Usage,
OUT PUSHORT UsagePage)
{
PHID_COLLECTION Collection;
//
// find collection
//
Collection = HidParser_GetCollectionFromContext(CollectionContext);
if (!Collection)
{
//
// collection not found
//
return HIDPARSER_STATUS_COLLECTION_NOT_FOUND;
}
//
// store result
//
*UsagePage = (Collection->Usage >> 16);
*Usage = (Collection->Usage & 0xFFFF);
return HIDPARSER_STATUS_SUCCESS;
}
ULONG
HidParser_GetReportLength(
IN PVOID CollectionContext,
IN UCHAR ReportType)
{
PHID_REPORT Report;
ULONG ReportLength;
//
// get first report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no report found
//
return 0;
}
//
// get report length
//
ReportLength = Report->ReportSize;
//
// done
//
if (ReportLength)
{
//
// byte aligned length
//
ASSERT(ReportLength % 8 == 0);
return ReportLength / 8;
}
return ReportLength;
}
ULONG
HidParser_GetReportItemCountFromReportType(
IN PVOID CollectionContext,
IN UCHAR ReportType)
{
PHID_REPORT Report;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return 0;
}
//
// return report item count
//
return Report->ItemCount;
}
ULONG
HidParser_GetReportItemTypeCountFromReportType(
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN ULONG bData)
{
ULONG Index;
PHID_REPORT Report;
ULONG ItemCount = 0;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return 0;
}
//
// enumerate all items
//
for(Index = 0; Index < Report->ItemCount; Index++)
{
//
// check item type
//
if (Report->Items[Index].HasData && bData)
{
//
// found data item
//
ItemCount++;
}
else if (Report->Items[Index].HasData == FALSE && bData == FALSE)
{
//
// found value item
//
ItemCount++;
}
}
//
// no report items
//
return ItemCount;
}
VOID
HidParser_InitParser(
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 Parser)
{
Parser->Alloc = AllocFunction;
Parser->Free = FreeFunction;
Parser->Zero = ZeroFunction;
Parser->Copy = CopyFunction;
Parser->Debug = DebugFunction;
}
ULONG
HidParser_GetMaxUsageListLengthWithReportAndPage(
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage OPTIONAL)
{
ULONG Index;
PHID_REPORT Report;
ULONG ItemCount = 0;
USHORT CurrentUsagePage;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return 0;
}
for(Index = 0; Index < Report->ItemCount; Index++)
{
//
// check usage page
//
CurrentUsagePage = (Report->Items[Index].UsageMinimum >> 16);
if (CurrentUsagePage == UsagePage && Report->Items[Index].HasData)
{
//
// found item
//
ItemCount++;
}
}
//
// done
//
return ItemCount;
}
HIDPARSER_STATUS
HidParser_GetSpecificValueCapsWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USHORT UsagePage,
IN USHORT Usage,
OUT PHIDP_VALUE_CAPS ValueCaps,
IN OUT PUSHORT ValueCapsLength)
{
ULONG Index;
PHID_REPORT Report;
USHORT ItemCount = 0;
USHORT CurrentUsagePage;
USHORT CurrentUsage;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return HIDPARSER_STATUS_REPORT_NOT_FOUND;
}
for(Index = 0; Index < Report->ItemCount; Index++)
{
//
// check usage page
//
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))
{
//
// check if there is enough place for the caps
//
if (ItemCount < *ValueCapsLength)
{
//
// zero caps
//
Parser->Zero(&ValueCaps[ItemCount], sizeof(HIDP_VALUE_CAPS));
//
// init caps
//
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;
//
// FIXME: FILLMEIN
//
}
//
// found item
//
ItemCount++;
}
}
//
// store result
//
*ValueCapsLength = ItemCount;
if (ItemCount)
{
//
// success
//
return HIDPARSER_STATUS_SUCCESS;
}
//
// item not found
//
return HIDPARSER_STATUS_USAGE_NOT_FOUND;
}
HIDPARSER_STATUS
HidParser_GetUsagesWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage,
OUT USAGE *UsageList,
IN OUT PULONG UsageLength,
IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength)
{
ULONG Index;
PHID_REPORT Report;
ULONG ItemCount = 0;
USHORT CurrentUsagePage;
PHID_REPORT_ITEM ReportItem;
UCHAR Activated;
ULONG Data;
PUSAGE_AND_PAGE UsageAndPage = NULL;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return HIDPARSER_STATUS_REPORT_NOT_FOUND;
}
if (Report->ReportSize / 8 != (ReportDescriptorLength - 1))
{
//
// invalid report descriptor length
//
return HIDPARSER_STATUS_INVALID_REPORT_LENGTH;
}
//
// cast to usage and page
//
if (UsagePage == HID_USAGE_PAGE_UNDEFINED)
{
//
// the caller requested any set usages
//
UsageAndPage = (PUSAGE_AND_PAGE)UsageList;
}
for(Index = 0; Index < Report->ItemCount; Index++)
{
//
// get report item
//
ReportItem = &Report->Items[Index];
//
// does it have data
//
if (!ReportItem->HasData)
continue;
//
// check usage page
//
CurrentUsagePage = (ReportItem->UsageMinimum >> 16);
if (UsagePage != HID_USAGE_PAGE_UNDEFINED)
{
//
// does usage match
//
if (UsagePage != CurrentUsagePage)
continue;
}
//
// check if the specified usage is activated
//
ASSERT(ReportItem->ByteOffset < ReportDescriptorLength);
ASSERT(ReportItem->BitCount <= 8);
//
// one extra shift for skipping the prepended report id
//
Data = ReportDescriptor[ReportItem->ByteOffset + 1];
//
// shift data
//
Data >>= ReportItem->Shift;
//
// clear unwanted bits
//
Data &= ReportItem->Mask;
//
// is it activated
//
Activated = (Data != 0);
if (!Activated)
continue;
//
// is there enough space for the usage
//
if (ItemCount >= *UsageLength)
{
ItemCount++;
continue;
}
if (UsagePage != HID_USAGE_PAGE_UNDEFINED)
{
//
// store item
//
UsageList[ItemCount] = (ReportItem->UsageMinimum & 0xFFFF);
}
else
{
//
// store usage and page
//
if (ReportItem->BitCount == 1)
{
//
// use usage minimum
//
UsageAndPage[ItemCount].Usage =(ReportItem->UsageMinimum & 0xFFFF);
}
else
{
//
// use value from control
//
UsageAndPage[ItemCount].Usage = (USHORT)Data;
}
UsageAndPage[ItemCount].UsagePage = CurrentUsagePage;
}
ItemCount++;
}
if (ItemCount > *UsageLength)
{
//
// list too small
//
return HIDPARSER_STATUS_BUFFER_TOO_SMALL;
}
if (UsagePage == HID_USAGE_PAGE_UNDEFINED)
{
//
// success, clear rest of array
//
Parser->Zero(&UsageAndPage[ItemCount], (*UsageLength - ItemCount) * sizeof(USAGE_AND_PAGE));
}
else
{
//
// success, clear rest of array
//
Parser->Zero(&UsageList[ItemCount], (*UsageLength - ItemCount) * sizeof(USAGE));
}
//
// store result size
//
*UsageLength = ItemCount;
//
// done
//
return HIDPARSER_STATUS_SUCCESS;
}
ULONG
HidParser_UsesReportId(
IN PVOID CollectionContext,
IN UCHAR ReportType)
{
PHID_REPORT Report;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return 0;
}
//
// returns true when report id != 0
//
return (Report->ReportID != 0);
}
HIDPARSER_STATUS
HidParser_GetUsageValueWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage,
IN USAGE Usage,
OUT PULONG UsageValue,
IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength)
{
ULONG Index;
PHID_REPORT Report;
USHORT CurrentUsagePage;
PHID_REPORT_ITEM ReportItem;
ULONG Data;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return HIDPARSER_STATUS_REPORT_NOT_FOUND;
}
if (Report->ReportSize / 8 != (ReportDescriptorLength - 1))
{
//
// invalid report descriptor length
//
return HIDPARSER_STATUS_INVALID_REPORT_LENGTH;
}
for (Index = 0; Index < Report->ItemCount; Index++)
{
//
// get report item
//
ReportItem = &Report->Items[Index];
//
// check usage page
//
CurrentUsagePage = (ReportItem->UsageMinimum >> 16);
//
// does usage page match
//
if (UsagePage != CurrentUsagePage)
continue;
//
// does the usage match
//
if (Usage != (ReportItem->UsageMinimum & 0xFFFF))
continue;
//
// check if the specified usage is activated
//
ASSERT(ReportItem->ByteOffset < ReportDescriptorLength);
//
// one extra shift for skipping the prepended report id
//
Data = 0;
Parser->Copy(&Data, &ReportDescriptor[ReportItem->ByteOffset + 1], min(sizeof(ULONG), ReportDescriptorLength - (ReportItem->ByteOffset + 1)));
//
// shift data
//
Data >>= ReportItem->Shift;
//
// clear unwanted bits
//
Data &= ReportItem->Mask;
//
// store result
//
*UsageValue = Data;
return HIDPARSER_STATUS_SUCCESS;
}
//
// usage not found
//
return HIDPARSER_STATUS_USAGE_NOT_FOUND;
}
HIDPARSER_STATUS
HidParser_GetScaledUsageValueWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage,
IN USAGE Usage,
OUT PLONG UsageValue,
IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength)
{
ULONG Index;
PHID_REPORT Report;
USHORT CurrentUsagePage;
PHID_REPORT_ITEM ReportItem;
ULONG Data;
//
// get report
//
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
if (!Report)
{
//
// no such report
//
return HIDPARSER_STATUS_REPORT_NOT_FOUND;
}
if (Report->ReportSize / 8 != (ReportDescriptorLength - 1))
{
//
// invalid report descriptor length
//
return HIDPARSER_STATUS_INVALID_REPORT_LENGTH;
}
for (Index = 0; Index < Report->ItemCount; Index++)
{
//
// get report item
//
ReportItem = &Report->Items[Index];
//
// check usage page
//
CurrentUsagePage = (ReportItem->UsageMinimum >> 16);
//
// does usage page match
//
if (UsagePage != CurrentUsagePage)
continue;
//
// does the usage match
//
if (Usage != (ReportItem->UsageMinimum & 0xFFFF))
continue;
//
// check if the specified usage is activated
//
ASSERT(ReportItem->ByteOffset < ReportDescriptorLength);
//
// one extra shift for skipping the prepended report id
//
Data = 0;
Parser->Copy(&Data, &ReportDescriptor[ReportItem->ByteOffset + 1], min(sizeof(ULONG), ReportDescriptorLength - (ReportItem->ByteOffset + 1)));
//
// shift data
//
Data >>= ReportItem->Shift;
//
// clear unwanted bits
//
Data &= ReportItem->Mask;
if (ReportItem->Minimum > ReportItem->Maximum)
{
//
// logical boundaries are signed values
//
// FIXME: scale with physical min/max
if ((Data & ~(ReportItem->Mask >> 1)) != 0)
{
Data |= ~ReportItem->Mask;
}
}
else
{
// logical boundaries are absolute values
return HIDPARSER_STATUS_BAD_LOG_PHY_VALUES;
}
//
// store result
//
*UsageValue = Data;
return HIDPARSER_STATUS_SUCCESS;
}
//
// usage not found
//
return HIDPARSER_STATUS_USAGE_NOT_FOUND;
}
ULONG
HidParser_GetScanCodeFromKbdUsage(
IN USAGE Usage)
{
if (Usage < sizeof(KeyboardScanCodes) / sizeof(KeyboardScanCodes[0]))
{
//
// valid usage
//
return KeyboardScanCodes[Usage];
}
//
// invalid usage
//
return 0;
}
ULONG
HidParser_GetScanCodeFromCustUsage(
IN USAGE Usage)
{
ULONG i;
//
// find usage in array
//
for (i = 0; i < sizeof(CustomerScanCodes) / sizeof(CustomerScanCodes[0]); ++i)
{
if (CustomerScanCodes[i].Usage == Usage)
{
//
// valid usage
//
return CustomerScanCodes[i].ScanCode;
}
}
//
// 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 - see USB HID to PS/2 Scan Code Translation Table
//
ScanCodes[Index] |= 0x80;
}
//
// more scan counts
//
Length++;
}
if (Length > 0)
{
//
// dispatch scan codes
//
InsertCodesProcedure(InsertCodesContext, ScanCodes, Length);
}
}
HIDPARSER_STATUS
HidParser_TranslateKbdUsage(
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;
CHAR FakeShift[] = {0xE0, 0x2A, 0x00};
CHAR FakeCtrl[] = {0xE1, 0x1D, 0x00};
//
// get scan code
//
ScanCode = HidParser_GetScanCodeFromKbdUsage(Usage);
if (!ScanCode)
{
//
// invalid lookup or no scan code available
//
DPRINT1("No Scan code for Usage %x\n", Usage);
return HIDPARSER_STATUS_I8042_TRANS_UNKNOWN;
}
if (ScanCode & 0xFF00)
{
//
// swap scan code
//
ScanCode = NTOHS(ScanCode);
}
if (Usage == 0x46 && KeyAction == HidP_Keyboard_Make)
{
// Print Screen generates additional FakeShift
HidParser_DispatchKey(FakeShift, KeyAction, InsertCodesProcedure, InsertCodesContext);
}
if (Usage == 0x48)
{
// Pause/Break generates additional FakeCtrl. Note: it's always before key press/release.
HidParser_DispatchKey(FakeCtrl, KeyAction, InsertCodesProcedure, InsertCodesContext);
}
//
// FIXME: translate modifier states
//
HidParser_DispatchKey((PCHAR)&ScanCode, KeyAction, InsertCodesProcedure, InsertCodesContext);
if (Usage == 0x46 && KeyAction == HidP_Keyboard_Break)
{
// Print Screen generates additional FakeShift
HidParser_DispatchKey(FakeShift, KeyAction, InsertCodesProcedure, InsertCodesContext);
}
//
// done
//
return HIDPARSER_STATUS_SUCCESS;
}
HIDPARSER_STATUS
HidParser_TranslateCustUsage(
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_GetScanCodeFromCustUsage(Usage);
if (!ScanCode)
{
//
// invalid lookup or no scan code available
//
DPRINT1("No Scan code for Usage %x\n", Usage);
return HIDPARSER_STATUS_I8042_TRANS_UNKNOWN;
}
if (ScanCode & 0xFF00)
{
//
// swap scan code
//
ScanCode = NTOHS(ScanCode);
}
//
// FIXME: translate modifier states
//
HidParser_DispatchKey((PCHAR)&ScanCode, KeyAction, InsertCodesProcedure, InsertCodesContext);
//
// done
//
return HIDPARSER_STATUS_SUCCESS;
}

View file

@ -0,0 +1,346 @@
/*
* PROJECT: ReactOS HID Parser Library
* LICENSE: GPL - See COPYING in the top level directory
* FILE: lib/drivers/hidparser/context.c
* PURPOSE: HID Parser
* PROGRAMMERS:
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "parser.h"
#define NDEBUG
#include <debug.h>
typedef struct
{
ULONG Size;
union
{
UCHAR RawData[1];
};
}HID_COLLECTION_CONTEXT, *PHID_COLLECTION_CONTEXT;
ULONG
HidParser_CalculateCollectionSize(
IN PHID_COLLECTION Collection)
{
ULONG Size = 0, Index;
Size = sizeof(HID_COLLECTION);
//
// add size required for the number of report items
//
for(Index = 0; Index < Collection->ReportCount; Index++)
{
//
// get report size
//
ASSERT(Collection->Reports[Index]->ItemCount);
Size += sizeof(HID_REPORT) + Collection->Reports[Index]->ItemCount * sizeof(HID_REPORT_ITEM);
}
//
// calculate size for sub collections
//
for(Index = 0; Index < Collection->NodeCount; Index++)
{
Size += HidParser_CalculateCollectionSize(Collection->Nodes[Index]);
}
//
// append size for the offset
//
Size += (Collection->ReportCount + Collection->NodeCount) * sizeof(ULONG);
//
// done
//
return Size;
}
ULONG
HidParser_CalculateContextSize(
IN PHID_COLLECTION Collection)
{
ULONG Size;
//
// minimum size is the size of the collection
//
Size = HidParser_CalculateCollectionSize(Collection);
//
// append collection context size
//
Size += sizeof(HID_COLLECTION_CONTEXT);
return Size;
}
ULONG
HidParser_StoreCollection(
IN PHID_PARSER Parser,
IN PHID_COLLECTION Collection,
IN PHID_COLLECTION_CONTEXT CollectionContext,
IN ULONG CurrentOffset)
{
ULONG Index;
ULONG ReportSize;
ULONG InitialOffset;
ULONG CollectionSize;
PHID_COLLECTION TargetCollection;
//
// backup initial offset
//
InitialOffset = CurrentOffset;
//
// get target collection
//
TargetCollection = (PHID_COLLECTION)(&CollectionContext->RawData[CurrentOffset]);
//
// first copy the collection details
//
Parser->Copy(TargetCollection, Collection, sizeof(HID_COLLECTION));
//
// calulcate collection size
//
CollectionSize = sizeof(HID_COLLECTION) + sizeof(ULONG) * (Collection->ReportCount + Collection->NodeCount);
//
// increase offset
//
CurrentOffset += CollectionSize;
//
// sanity check
//
ASSERT(CurrentOffset < CollectionContext->Size);
//
// first store the report items
//
for(Index = 0; Index < Collection->ReportCount; Index++)
{
//
// calculate report size
//
ReportSize = sizeof(HID_REPORT) + Collection->Reports[Index]->ItemCount * sizeof(HID_REPORT_ITEM);
//
// sanity check
//
ASSERT(CurrentOffset + ReportSize < CollectionContext->Size);
//
// copy report item
//
Parser->Copy(&CollectionContext->RawData[CurrentOffset], Collection->Reports[Index], ReportSize);
//
// store offset to report item
//
TargetCollection->Offsets[Index] = CurrentOffset;
//
// move to next offset
//
CurrentOffset += ReportSize;
}
ASSERT(CurrentOffset <= CollectionContext->Size);
//
// now store the sub collections
//
for(Index = 0; Index < Collection->NodeCount; Index++)
{
//
// store offset
//
TargetCollection->Offsets[Collection->ReportCount + Index] = CurrentOffset;
//
// store sub collections
//
CurrentOffset += HidParser_StoreCollection(Parser, Collection->Nodes[Index], CollectionContext, CurrentOffset);
//
// sanity check
//
ASSERT(CurrentOffset < CollectionContext->Size);
}
//
// return size of collection
//
return CurrentOffset - InitialOffset;
}
HIDPARSER_STATUS
HidParser_BuildCollectionContext(
IN PHID_PARSER Parser,
IN PHID_COLLECTION RootCollection,
IN PVOID Context,
IN ULONG ContextSize)
{
PHID_COLLECTION_CONTEXT CollectionContext;
ULONG CollectionSize;
//
// init context
//
CollectionContext = (PHID_COLLECTION_CONTEXT)Context;
CollectionContext->Size = ContextSize;
//
// store collections
//
CollectionSize = HidParser_StoreCollection(Parser, RootCollection, CollectionContext, 0);
//
// sanity check
//
ASSERT(CollectionSize + sizeof(HID_COLLECTION_CONTEXT) == ContextSize);
DPRINT("CollectionContext %p\n", CollectionContext);
DPRINT("CollectionContext RawData %p\n", CollectionContext->RawData);
DPRINT("CollectionContext Size %lu\n", CollectionContext->Size);
//
// done
//
return HIDPARSER_STATUS_SUCCESS;
}
PHID_REPORT
HidParser_SearchReportInCollection(
IN PHID_COLLECTION_CONTEXT CollectionContext,
IN PHID_COLLECTION Collection,
IN UCHAR ReportType)
{
ULONG Index;
PHID_REPORT Report;
PHID_COLLECTION SubCollection;
//
// search first in local array
//
for(Index = 0; Index < Collection->ReportCount; Index++)
{
//
// get report
//
Report = (PHID_REPORT)(CollectionContext->RawData + Collection->Offsets[Index]);
if (Report->Type == ReportType)
{
//
// found report
//
return Report;
}
}
//
// now search in sub collections
//
for(Index = 0; Index < Collection->NodeCount; Index++)
{
//
// get collection
//
SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->ReportCount + Index]);
//
// recursively search collection
//
Report = HidParser_SearchReportInCollection(CollectionContext, SubCollection, ReportType);
if (Report)
{
//
// found report
//
return Report;
}
}
//
// not found
//
return NULL;
}
PHID_REPORT
HidParser_GetReportInCollection(
IN PVOID Context,
IN UCHAR ReportType)
{
PHID_COLLECTION_CONTEXT CollectionContext = (PHID_COLLECTION_CONTEXT)Context;
//
// done
//
return HidParser_SearchReportInCollection(CollectionContext, (PHID_COLLECTION)&CollectionContext->RawData, ReportType);
}
PHID_COLLECTION
HidParser_GetCollectionFromContext(
IN PVOID Context)
{
PHID_COLLECTION_CONTEXT CollectionContext = (PHID_COLLECTION_CONTEXT)Context;
//
// return root collection
//
return (PHID_COLLECTION)CollectionContext->RawData;
}
ULONG
HidParser_GetCollectionCount(
IN PHID_COLLECTION_CONTEXT CollectionContext,
IN PHID_COLLECTION Collection)
{
ULONG Index;
ULONG Count = Collection->NodeCount;
PHID_COLLECTION SubCollection;
for(Index = 0; Index < Collection->NodeCount; Index++)
{
//
// get offset to sub collection
//
SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->ReportCount + Index]);
//
// count collection for sub nodes
//
Count += HidParser_GetCollectionCount(CollectionContext, SubCollection);
}
//
// done
//
return Count;
}
ULONG
HidParser_GetTotalCollectionCount(
IN PVOID Context)
{
PHID_COLLECTION_CONTEXT CollectionContext;
//
// get parser context
//
CollectionContext = (PHID_COLLECTION_CONTEXT)Context;
//
// count collections
//
return HidParser_GetCollectionCount(CollectionContext, (PHID_COLLECTION)CollectionContext->RawData);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,450 @@
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
* LICENSE: GPL - See COPYING in the top level directory
* FILE: lib/drivers/hidparser/hidparser.c
* PURPOSE: HID Parser
* PROGRAMMERS:
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#pragma once
//
// function prototypes
//
typedef PVOID (NTAPI *PHIDPARSER_ALLOC_FUNCTION)(ULONG Size);
typedef VOID (NTAPI *PHIDPARSER_FREE_FUNCTION)(PVOID Item);
typedef VOID (NTAPI *PHIDPARSER_ZERO_FUNCTION)(PVOID Item, ULONG Size);
typedef VOID (NTAPI *PHIDPARSER_COPY_FUNCTION)(PVOID Target, PVOID Source, ULONG Size);
typedef VOID (__cdecl *PHIDPARSER_DEBUG_FUNCTION)(LPCSTR Src, ...);
//
// status code
//
typedef long HIDPARSER_STATUS;
//
// result codes
//
typedef enum
{
HIDPARSER_STATUS_SUCCESS = 0,
HIDPARSER_STATUS_INSUFFICIENT_RESOURCES = -1,
HIDPARSER_STATUS_NOT_IMPLEMENTED = -2,
HIDPARSER_STATUS_REPORT_NOT_FOUND = -3,
HIDPARSER_STATUS_COLLECTION_NOT_FOUND = -4,
HIDPARSER_STATUS_INVALID_REPORT_LENGTH = -5,
HIDPARSER_STATUS_INVALID_REPORT_TYPE = -6,
HIDPARSER_STATUS_BUFFER_TOO_SMALL = -7,
HIDPARSER_STATUS_USAGE_NOT_FOUND = -8,
HIDPARSER_STATUS_I8042_TRANS_UNKNOWN = -9,
HIDPARSER_STATUS_BAD_LOG_PHY_VALUES = -10
}HIDPARSER_STATUS_CODES;
typedef struct
{
//
// size of struct
//
unsigned long Size;
//
// allocation function
//
PHIDPARSER_ALLOC_FUNCTION Alloc;
//
// free function
//
PFREE_FUNCTION Free;
//
// zero function
//
PHIDPARSER_ZERO_FUNCTION Zero;
//
// copy function
//
PHIDPARSER_COPY_FUNCTION Copy;
//
// debug function
//
PHIDPARSER_DEBUG_FUNCTION Debug;
}HID_PARSER, *PHID_PARSER;
VOID
HidParser_InitParser(
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 Parser);
NTSTATUS
NTAPI
HidParser_GetCollectionDescription(
IN PHID_PARSER Parser,
IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
IN ULONG DescLength,
IN POOL_TYPE PoolType,
OUT PHIDP_DEVICE_DESC DeviceDescription);
VOID
NTAPI
HidParser_FreeCollectionDescription(
IN PHID_PARSER Parser,
IN PHIDP_DEVICE_DESC DeviceDescription);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetCaps(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
OUT PHIDP_CAPS Capabilities);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetSpecificValueCaps(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection,
IN USAGE Usage,
OUT PHIDP_VALUE_CAPS ValueCaps,
IN OUT PUSHORT ValueCapsLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetButtonCaps(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
HIDP_REPORT_TYPE ReportType,
PHIDP_BUTTON_CAPS ButtonCaps,
PUSHORT ButtonCapsLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetSpecificButtonCaps(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection,
IN USAGE Usage,
OUT PHIDP_BUTTON_CAPS ButtonCaps,
IN OUT PULONG ButtonCapsLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetScaledUsageValue(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection OPTIONAL,
IN USAGE Usage,
OUT PLONG UsageValue,
IN PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetData(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
OUT PHIDP_DATA DataList,
IN OUT PULONG DataLength,
IN PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetExtendedAttributes(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USHORT DataIndex,
OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
IN OUT PULONG LengthAttributes);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetLinkCollectionNodes(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
IN OUT PULONG LinkCollectionNodesLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetUsageValue(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection,
IN USAGE Usage,
OUT PULONG UsageValue,
IN PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_UsageListDifference(
IN PUSAGE PreviousUsageList,
IN PUSAGE CurrentUsageList,
OUT PUSAGE BreakUsageList,
OUT PUSAGE MakeUsageList,
IN ULONG UsageListLength);
HIDAPI
ULONG
NTAPI
HidParser_MaxUsageListLength(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage OPTIONAL);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetUsages(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection OPTIONAL,
OUT USAGE *UsageList,
IN OUT ULONG *UsageLength,
IN PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetUsagesEx(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USHORT LinkCollection,
OUT PUSAGE_AND_PAGE ButtonList,
IN OUT ULONG *UsageLength,
IN PCHAR Report,
IN ULONG ReportLength);
NTSTATUS
NTAPI
HidParser_SysPowerEvent (
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN PCHAR HidPacket,
IN USHORT HidPacketLength,
OUT PULONG OutputBuffer);
NTSTATUS
NTAPI
HidParser_SysPowerCaps (
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
OUT PULONG OutputBuffer);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetUsageValueArray(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection OPTIONAL,
IN USAGE Usage,
OUT PCHAR UsageValue,
IN USHORT UsageValueByteLength,
IN PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_UsageAndPageListDifference(
IN PUSAGE_AND_PAGE PreviousUsageList,
IN PUSAGE_AND_PAGE CurrentUsageList,
OUT PUSAGE_AND_PAGE BreakUsageList,
OUT PUSAGE_AND_PAGE MakeUsageList,
IN ULONG UsageListLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_UnsetUsages(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection,
IN PUSAGE UsageList,
IN OUT PULONG UsageLength,
IN OUT PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_TranslateUsagesToI8042ScanCodes(
IN PUSAGE ChangedUsageList,
IN ULONG UsageListLength,
IN HIDP_KEYBOARD_DIRECTION KeyAction,
IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
IN PVOID InsertCodesContext);
HIDAPI
NTSTATUS
NTAPI
HidParser_TranslateUsageAndPagesToI8042ScanCodes(
IN PHID_PARSER Parser,
IN PUSAGE_AND_PAGE ChangedUsageList,
IN ULONG UsageListLength,
IN HIDP_KEYBOARD_DIRECTION KeyAction,
IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
IN PVOID InsertCodesContext);
HIDAPI
NTSTATUS
NTAPI
HidParser_SetUsages(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection,
IN PUSAGE UsageList,
IN OUT PULONG UsageLength,
IN OUT PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_SetUsageValueArray(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection OPTIONAL,
IN USAGE Usage,
IN PCHAR UsageValue,
IN USHORT UsageValueByteLength,
OUT PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_SetUsageValue(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection,
IN USAGE Usage,
IN ULONG UsageValue,
IN OUT PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_SetScaledUsageValue(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
IN USHORT LinkCollection OPTIONAL,
IN USAGE Usage,
IN LONG UsageValue,
IN OUT PCHAR Report,
IN ULONG ReportLength);
HIDAPI
NTSTATUS
NTAPI
HidParser_SetData(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN PHIDP_DATA DataList,
IN OUT PULONG DataLength,
IN OUT PCHAR Report,
IN ULONG ReportLength);
HIDAPI
ULONG
NTAPI
HidParser_MaxDataListLength(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType);
HIDAPI
NTSTATUS
NTAPI
HidParser_InitializeReportForID(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN HIDP_REPORT_TYPE ReportType,
IN UCHAR ReportID,
IN OUT PCHAR Report,
IN ULONG ReportLength);
HIDPARSER_STATUS
HidParser_TranslateKbdUsage(
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);
HIDPARSER_STATUS
HidParser_TranslateCustUsage(
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);
HIDAPI
NTSTATUS
NTAPI
HidParser_GetValueCaps(
PHID_PARSER Parser,
IN PVOID CollectionContext,
HIDP_REPORT_TYPE ReportType,
PHIDP_VALUE_CAPS ValueCaps,
PULONG ValueCapsLength);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,398 @@
#ifndef _HIDPARSER_H_
#define _HIDPARSER_H_
#include <wdm.h>
#include <pshpack1.h>
#define _HIDPI_
#define _HIDPI_NO_FUNCTION_MACROS_
#include <hidpddi.h>
#include "hidparser.h"
/*
* Copyright 2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#define HID_REPORT_TYPE_ANY 0x07
#define ITEM_TYPE_MAIN 0x0
#define ITEM_TYPE_GLOBAL 0x1
#define ITEM_TYPE_LOCAL 0x2
#define ITEM_TYPE_LONG 0x3
#define ITEM_TAG_MAIN_INPUT 0x8
#define ITEM_TAG_MAIN_OUTPUT 0x9
#define ITEM_TAG_MAIN_FEATURE 0xb
#define ITEM_TAG_MAIN_COLLECTION 0xa
#define ITEM_TAG_MAIN_END_COLLECTION 0xc
#define ITEM_TAG_GLOBAL_USAGE_PAGE 0x0
#define ITEM_TAG_GLOBAL_LOGICAL_MINIMUM 0x1
#define ITEM_TAG_GLOBAL_LOGICAL_MAXIMUM 0x2
#define ITEM_TAG_GLOBAL_PHYSICAL_MINIMUM 0x3
#define ITEM_TAG_GLOBAL_PHYSICAL_MAXIMUM 0x4
#define ITEM_TAG_GLOBAL_UNIT_EXPONENT 0x5
#define ITEM_TAG_GLOBAL_UNIT 0x6
#define ITEM_TAG_GLOBAL_REPORT_SIZE 0x7
#define ITEM_TAG_GLOBAL_REPORT_ID 0x8
#define ITEM_TAG_GLOBAL_REPORT_COUNT 0x9
#define ITEM_TAG_GLOBAL_PUSH 0xa
#define ITEM_TAG_GLOBAL_POP 0xb
#define ITEM_TAG_LOCAL_USAGE 0x0
#define ITEM_TAG_LOCAL_USAGE_MINIMUM 0x1
#define ITEM_TAG_LOCAL_USAGE_MAXIMUM 0x2
#define ITEM_TAG_LOCAL_DESIGNATOR_INDEX 0x3
#define ITEM_TAG_LOCAL_DESIGNATOR_MINIMUM 0x4
#define ITEM_TAG_LOCAL_DESIGNATOR_MAXIMUM 0x5
#define ITEM_TAG_LOCAL_STRING_INDEX 0x7
#define ITEM_TAG_LOCAL_STRING_MINIMUM 0x8
#define ITEM_TAG_LOCAL_STRING_MAXIMUM 0x9
#define ITEM_TAG_LOCAL_DELIMITER 0xa
#define ITEM_TAG_LONG 0xf
#define COLLECTION_PHYSICAL 0x00
#define COLLECTION_APPLICATION 0x01
#define COLLECTION_LOGICAL 0x02
#define COLLECTION_REPORT 0x03
#define COLLECTION_NAMED_ARRAY 0x04
#define COLLECTION_USAGE_SWITCH 0x05
#define COLLECTION_USAGE_MODIFIER 0x06
#define COLLECTION_ALL 0xff
#define UNIT_SYSTEM 0x0
#define UNIT_LENGTH 0x1
#define UNIT_MASS 0x2
#define UNIT_TIME 0x3
#define UNIT_TEMPERATURE 0x4
#define UNIT_CURRENT 0x5
#define UNIT_LUMINOUS_INTENSITY 0x6
#define USAGE_PAGE_SHIFT 16
#define USAGE_PAGE_MASK 0xffff
#define USAGE_ID_SHIFT 0
#define USAGE_ID_MASK 0xffff
typedef struct
{
UCHAR Size:2;
UCHAR Type:2;
UCHAR Tag:4;
}ITEM_PREFIX, *PITEM_PREFIX;
typedef struct
{
ITEM_PREFIX Prefix;
union
{
UCHAR UData8[4];
CHAR SData8[4];
USHORT UData16[2];
SHORT SData16[2];
ULONG UData32;
LONG SData32;
}Data;
}SHORT_ITEM, *PSHORT_ITEM;
typedef struct
{
ITEM_PREFIX Prefix;
UCHAR DataSize;
UCHAR LongItemTag;
UCHAR Data[0];
}LONG_ITEM,*PLONG_ITEM;
#define LBITFIELD9(b1,b2,b3,b4,b5,b6,b7,b8,b9) USHORT b9,b8,b7,b6,b5,b4,b3,b2,b1
typedef struct
{
USHORT DataConstant:1;
USHORT ArrayVariable:1;
USHORT Relative:1;
USHORT Wrap:1;
USHORT NonLinear:1;
USHORT NoPreferred:1;
USHORT NullState:1;
USHORT IsVolatile:1;
USHORT BitsBytes:1;
UCHAR reserved[2];
}MAIN_ITEM_DATA, *PMAIN_ITEM_DATA;
typedef struct __GLOBAL_ITEM_STATE_
{
USHORT UsagePage;
ULONG LogicalMinimum;
ULONG LogicialMaximum;
ULONG PhysicalMinimum;
ULONG PhysicalMaximum;
UCHAR UnitExponent;
UCHAR Unit;
ULONG ReportSize;
ULONG ReportCount;
UCHAR ReportId;
struct __GLOBAL_ITEM_STATE__ * Next;
}GLOBAL_ITEM_STATE, *PGLOBAL_ITEM_STATE;
typedef struct usage_value
{
union
{
struct {
USHORT UsageId;
USHORT UsagePage;
}s;
ULONG Extended;
}u;
UCHAR IsExtended;
}USAGE_VALUE, *PUSAGE_VALUE;
typedef struct
{
PUSAGE_VALUE UsageStack;
ULONG UsageStackUsed;
ULONG UsageStackAllocated;
USAGE_VALUE UsageMinimum;
USAGE_VALUE UsageMaximum;
UCHAR UsageMinimumSet;
UCHAR UsageMaximumSet;
ULONG DesignatorIndex;
UCHAR DesignatorIndexSet;
ULONG DesignatorMinimum;
ULONG DesignatorMaximum;
UCHAR StringIndex;
UCHAR StringIndexSet;
UCHAR StringMinimum;
UCHAR StringMaximum;
}LOCAL_ITEM_STATE, *PLOCAL_ITEM_STATE;
typedef struct
{
ULONG ByteOffset;
UCHAR Shift;
ULONG Mask;
UCHAR BitCount;
UCHAR HasData;
UCHAR Array;
UCHAR Relative;
ULONG Minimum;
ULONG Maximum;
ULONG UsageMinimum;
ULONG UsageMaximum;
ULONG Data;
UCHAR Valid;
}HID_REPORT_ITEM, *PHID_REPORT_ITEM;
struct _HID_REPORT;
typedef struct __HID_COLLECTION__
{
UCHAR Type;
ULONG Usage;
UCHAR StringID;
UCHAR PhysicalID;
ULONG ReportCount;
ULONG NodeCount;
struct __HID_COLLECTION__ ** Nodes;
struct __HID_COLLECTION__ * Root;
struct _HID_REPORT ** Reports;
ULONG Offsets[1];
}HID_COLLECTION, *PHID_COLLECTION;
typedef struct _HID_REPORT
{
UCHAR Type;
UCHAR ReportID;
ULONG ReportSize;
ULONG ItemCount;
ULONG ItemAllocated;
HID_REPORT_ITEM Items[1];
}HID_REPORT, *PHID_REPORT;
typedef struct
{
//
// global item state
//
GLOBAL_ITEM_STATE GlobalItemState;
//
// local item state
//
LOCAL_ITEM_STATE LocalItemState;
//
// root collection
//
PHID_COLLECTION RootCollection;
//
// uses report ids
//
UCHAR UseReportIDs;
//
// collection index
//
ULONG CollectionIndex;
}HID_PARSER_CONTEXT, *PHID_PARSER_CONTEXT;
#define HID_REPORT_TYPE_INPUT 0x01
#define HID_REPORT_TYPE_OUTPUT 0x02
#define HID_REPORT_TYPE_FEATURE 0x04
ULONG
HidParser_UsesReportId(
IN PVOID CollectionContext,
IN UCHAR ReportType);
HIDPARSER_STATUS
HidParser_GetCollectionUsagePage(
IN PVOID CollectionContext,
OUT PUSHORT Usage,
OUT PUSHORT UsagePage);
ULONG
HidParser_GetReportLength(
IN PVOID CollectionContext,
IN UCHAR ReportType);
UCHAR
HidParser_IsReportIDUsed(
IN PHID_PARSER Parser);
ULONG
HidParser_GetReportItemCountFromReportType(
IN PVOID CollectionContext,
IN UCHAR ReportType);
ULONG
HidParser_GetReportItemTypeCountFromReportType(
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN ULONG bData);
ULONG
HidParser_GetMaxUsageListLengthWithReportAndPage(
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage OPTIONAL);
HIDPARSER_STATUS
HidParser_GetSpecificValueCapsWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USHORT UsagePage,
IN USHORT Usage,
OUT PHIDP_VALUE_CAPS ValueCaps,
IN OUT PUSHORT ValueCapsLength);
HIDPARSER_STATUS
HidParser_GetUsagesWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage,
OUT USAGE *UsageList,
IN OUT PULONG UsageLength,
IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength);
HIDPARSER_STATUS
HidParser_GetScaledUsageValueWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage,
IN USAGE Usage,
OUT PLONG UsageValue,
IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength);
HIDPARSER_STATUS
HidParser_GetUsageValueWithReport(
IN PHID_PARSER Parser,
IN PVOID CollectionContext,
IN UCHAR ReportType,
IN USAGE UsagePage,
IN USAGE Usage,
OUT PULONG UsageValue,
IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength);
/* parser.c */
HIDPARSER_STATUS
HidParser_BuildContext(
IN PHID_PARSER Parser,
IN PVOID ParserContext,
IN ULONG CollectionIndex,
IN ULONG ContextSize,
OUT PVOID *CollectionContext);
ULONG
HidParser_CalculateContextSize(
IN PHID_COLLECTION Collection);
HIDPARSER_STATUS
HidParser_ParseReportDescriptor(
PHID_PARSER Parser,
PUCHAR Report,
ULONG ReportSize,
OUT PVOID *ParserContext);
ULONG
HidParser_NumberOfTopCollections(
IN PVOID ParserContext);
ULONG
HidParser_GetContextSize(
IN PHID_PARSER Parser,
IN PVOID ParserContext,
IN ULONG CollectionNumber);
/* context.c */
PHID_COLLECTION
HidParser_GetCollectionFromContext(
IN PVOID Context);
ULONG
HidParser_GetTotalCollectionCount(
IN PVOID CollectionContext);
HIDPARSER_STATUS
HidParser_BuildCollectionContext(
IN PHID_PARSER Parser,
IN PHID_COLLECTION RootCollection,
IN PVOID Context,
IN ULONG ContextSize);
PHID_REPORT
HidParser_GetReportInCollection(
IN PVOID Context,
IN UCHAR ReportType);
#endif /* _HIDPARSER_H_ */