Author: janderwald Date: Mon Oct 22 21:18:30 2012 New Revision: 57595
URL: http://svn.reactos.org/svn/reactos?rev=57595&view=rev Log: [HIDPARSE][HIDPARSER] - Implement HidP_GetUsageValue - Add hack to HidParser_GetScaledUsageValueWithReport [MOUHID] - Add partial support for absolute pointing devices - Tested in VBOX 4.1.22 with absolute pointing devices - Needs more work in win32k - Core 6553
Modified: trunk/reactos/drivers/hid/hidparse/hidparse.c trunk/reactos/drivers/hid/mouhid/mouhid.c trunk/reactos/drivers/hid/mouhid/mouhid.h trunk/reactos/lib/drivers/hidparser/api.c trunk/reactos/lib/drivers/hidparser/hidparser.c trunk/reactos/lib/drivers/hidparser/hidparser.h trunk/reactos/lib/drivers/hidparser/parser.h
Modified: trunk/reactos/drivers/hid/hidparse/hidparse.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidparse/hidpar... ============================================================================== --- trunk/reactos/drivers/hid/hidparse/hidparse.c [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/hidparse/hidparse.c [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -309,6 +309,38 @@ HIDAPI NTSTATUS NTAPI +HidP_GetUsageValue( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, + IN USAGE Usage, + OUT PULONG UsageValue, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength) +{ + HID_PARSER Parser; + + // + // sanity check + // + ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature); + + // + // init parser + // + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); + + // + // get scaled usage value + // + return HidParser_GetUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength); +} + + +HIDAPI +NTSTATUS +NTAPI HidP_TranslateUsageAndPagesToI8042ScanCodes( IN PUSAGE_AND_PAGE ChangedUsageList, IN ULONG UsageListLength, @@ -405,24 +437,6 @@ return STATUS_NOT_IMPLEMENTED; }
-HIDAPI -NTSTATUS -NTAPI -HidP_GetUsageValue( - IN HIDP_REPORT_TYPE ReportType, - IN USAGE UsagePage, - IN USHORT LinkCollection, - IN USAGE Usage, - OUT PULONG UsageValue, - IN PHIDP_PREPARSED_DATA PreparsedData, - IN PCHAR Report, - IN ULONG ReportLength) -{ - UNIMPLEMENTED - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS NTAPI HidP_SysPowerEvent (
Modified: trunk/reactos/drivers/hid/mouhid/mouhid.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/mouhid/mouhid.c... ============================================================================== --- trunk/reactos/drivers/hid/mouhid/mouhid.c [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/mouhid/mouhid.c [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -37,6 +37,7 @@ OUT PLONG LastY) { NTSTATUS Status; + ULONG ValueX, ValueY;
/* init result */ *LastX = 0; @@ -44,16 +45,49 @@
/* get scaled usage value x */ Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PLONG)LastX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength); - /* FIXME handle error */ - ASSERT(Status == HIDP_STATUS_SUCCESS); + if (Status != HIDP_STATUS_SUCCESS) + { + /* FIXME: handle more errors */ + if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES) + { + /* FIXME: assume it operates in absolute mode */ + DeviceExtension->MouseAbsolute = TRUE; + + /* get unscaled value */ + Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PULONG)&ValueX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength); + + /* FIXME handle error */ + ASSERT(Status == HIDP_STATUS_SUCCESS); + + /* absolute pointing devices values need be in range 0 - 0xffff */ + ASSERT(DeviceExtension->ValueCapsX.LogicalMax > 0); + + *LastX = (ValueX * 0xFFFF) / DeviceExtension->ValueCapsX.LogicalMax; + } + }
/* get scaled usage value y */ Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PLONG)LastY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength); - /* FIXME handle error */ - ASSERT(Status == HIDP_STATUS_SUCCESS); - -} - + if (Status != HIDP_STATUS_SUCCESS) + { + // FIXME: handle more errors + if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES) + { + // assume it operates in absolute mode + DeviceExtension->MouseAbsolute = TRUE; + + // get unscaled value + Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PULONG)&ValueY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength); + + /* FIXME handle error */ + ASSERT(Status == HIDP_STATUS_SUCCESS); + + /* absolute pointing devices values need be in range 0 - 0xffff */ + ASSERT(DeviceExtension->ValueCapsY.LogicalMax); + *LastY = (ValueY * 0xFFFF) / DeviceExtension->ValueCapsY.LogicalMax; + } + } +}
VOID MouHid_GetButtonFlags( @@ -132,6 +166,12 @@ TempList = DeviceExtension->CurrentUsageList; DeviceExtension->CurrentUsageList = DeviceExtension->PreviousUsageList; DeviceExtension->PreviousUsageList = TempList; + + if (DeviceExtension->MouseAbsolute) + { + // mouse operates absolute + *ButtonFlags |= MOUSE_MOVE_ABSOLUTE; + } }
VOID @@ -195,11 +235,11 @@ return STATUS_MORE_PROCESSING_REQUIRED; }
+ /* get mouse change */ + MouHid_GetButtonMove(DeviceExtension, &LastX, &LastY); + /* get mouse change flags */ MouHid_GetButtonFlags(DeviceExtension, &ButtonFlags); - - /* get mouse change */ - MouHid_GetButtonMove(DeviceExtension, &LastX, &LastY);
/* init input data */ RtlZeroMemory(&MouseInputData, sizeof(MOUSE_INPUT_DATA)); @@ -227,6 +267,12 @@ } }
+ DPRINT("[MOUHID] ReportData %02x %02x %02x %02x %02x %02x %02x\n", + DeviceExtension->Report[0] & 0xFF, + DeviceExtension->Report[1] & 0xFF, DeviceExtension->Report[2] & 0xFF, + DeviceExtension->Report[3] & 0xFF, DeviceExtension->Report[4] & 0xFF, + DeviceExtension->Report[5] & 0xFF, DeviceExtension->Report[6] & 0xFF); + DPRINT("[MOUHID] LastX %ld LastY %ld Flags %x ButtonData %x\n", MouseInputData.LastX, MouseInputData.LastY, MouseInputData.ButtonFlags, MouseInputData.ButtonData);
/* dispatch mouse action */ @@ -700,10 +746,10 @@ DeviceExtension->PreparsedData = PreparsedData;
ValueCapsLength = 1; - HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, &ValueCaps, &ValueCapsLength, PreparsedData); + HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, &DeviceExtension->ValueCapsX, &ValueCapsLength, PreparsedData);
ValueCapsLength = 1; - HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, &ValueCaps, &ValueCapsLength, PreparsedData); + HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, &DeviceExtension->ValueCapsY, &ValueCapsLength, PreparsedData);
/* now check for wheel mouse support */ ValueCapsLength = 1;
Modified: trunk/reactos/drivers/hid/mouhid/mouhid.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/mouhid/mouhid.h... ============================================================================== --- trunk/reactos/drivers/hid/mouhid/mouhid.h [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/mouhid/mouhid.h [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -109,6 +109,22 @@ // UCHAR StopReadReport;
+ // + // mouse absolute + // + UCHAR MouseAbsolute; + + // + // value caps x + // + HIDP_VALUE_CAPS ValueCapsX; + + // + // value caps y button + // + HIDP_VALUE_CAPS ValueCapsY; + + }MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
#define WHEEL_DELTA 120
Modified: trunk/reactos/lib/drivers/hidparser/api.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/hidparser/api.c... ============================================================================== --- trunk/reactos/lib/drivers/hidparser/api.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/hidparser/api.c [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -563,6 +563,103 @@
}
+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))); + //Data = ReportDescriptor[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( @@ -652,10 +749,17 @@ // // logical boundaries are signed values // + + // FIXME: scale with physical min/max if ((Data & ~(ReportItem->Mask >> 1)) != 0) { Data |= ~ReportItem->Mask; } + } + else + { + // HACK: logical boundaries are absolute values + return HIDPARSER_STATUS_BAD_LOG_PHY_VALUES; }
//
Modified: trunk/reactos/lib/drivers/hidparser/hidparser.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/hidparser/hidpa... ============================================================================== --- trunk/reactos/lib/drivers/hidparser/hidparser.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/hidparser/hidparser.c [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -34,6 +34,8 @@ return HIDP_STATUS_I8042_TRANS_UNKNOWN; case HIDPARSER_STATUS_COLLECTION_NOT_FOUND: return HIDP_STATUS_NOT_IMPLEMENTED; //FIXME + case HIDPARSER_STATUS_BAD_LOG_PHY_VALUES: + return HIDP_STATUS_BAD_LOG_PHY_VALUES; } DPRINT1("TranslateHidParserStatus Status %ld not implemented\n", Status); return HIDP_STATUS_NOT_IMPLEMENTED; @@ -952,9 +954,54 @@ IN PCHAR Report, IN ULONG ReportLength) { - UNIMPLEMENTED - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; + HIDPARSER_STATUS ParserStatus; + + // + // FIXME: implement searching in specific collection + // + ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED); + + if (ReportType == HidP_Input) + { + // + // input report + // + ParserStatus = HidParser_GetUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_INPUT, UsagePage, Usage, UsageValue, Report, ReportLength); + } + else if (ReportType == HidP_Output) + { + // + // input report + // + ParserStatus = HidParser_GetUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_OUTPUT, UsagePage, Usage, UsageValue, Report, ReportLength); + } + else if (ReportType == HidP_Feature) + { + // + // input report + // + ParserStatus = HidParser_GetUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_FEATURE, UsagePage, Usage, UsageValue, Report, ReportLength); + } + else + { + // + // invalid report type + // + return HIDP_STATUS_INVALID_REPORT_TYPE; + } + + if (ParserStatus == HIDPARSER_STATUS_SUCCESS) + { + // + // success + // + return HIDP_STATUS_SUCCESS; + } + + // + // translate error + // + return TranslateHidParserStatus(ParserStatus); }
NTSTATUS
Modified: trunk/reactos/lib/drivers/hidparser/hidparser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/hidparser/hidpa... ============================================================================== --- trunk/reactos/lib/drivers/hidparser/hidparser.h [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/hidparser/hidparser.h [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -48,7 +48,8 @@ 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_I8042_TRANS_UNKNOWN = -9, + HIDPARSER_STATUS_BAD_LOG_PHY_VALUES = -10 }HIDPARSER_STATUS_CODES;
typedef struct @@ -200,6 +201,7 @@ OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes, IN OUT PULONG LinkCollectionNodesLength);
+ HIDAPI NTSTATUS NTAPI
Modified: trunk/reactos/lib/drivers/hidparser/parser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/hidparser/parse... ============================================================================== --- trunk/reactos/lib/drivers/hidparser/parser.h [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/hidparser/parser.h [iso-8859-1] Mon Oct 22 21:18:30 2012 @@ -327,6 +327,17 @@ 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