Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/hidp.c | 60 ++++++++++++++++++--- dlls/hidparse.sys/main.c | 111 +++++++++++++++------------------------ include/wine/hid.h | 25 ++++++--- 3 files changed, 115 insertions(+), 81 deletions(-)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index a1cdb951fd4..acb02246523 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -44,25 +44,27 @@ static NTSTATUS get_value_caps_range( struct hid_preparsed_data *preparsed, HIDP switch (report_type) { case HidP_Input: - if (report_len && report_len != preparsed->caps.InputReportByteLength) + if (report_len && report_len != preparsed->input_report_byte_length) return HIDP_STATUS_INVALID_REPORT_LENGTH; *caps = HID_INPUT_VALUE_CAPS( preparsed ); + *caps_end = *caps + preparsed->input_caps_count; break; case HidP_Output: - if (report_len && report_len != preparsed->caps.OutputReportByteLength) + if (report_len && report_len != preparsed->output_report_byte_length) return HIDP_STATUS_INVALID_REPORT_LENGTH; *caps = HID_OUTPUT_VALUE_CAPS( preparsed ); + *caps_end = *caps + preparsed->output_caps_count; break; case HidP_Feature: - if (report_len && report_len != preparsed->caps.FeatureReportByteLength) + if (report_len && report_len != preparsed->feature_report_byte_length) return HIDP_STATUS_INVALID_REPORT_LENGTH; *caps = HID_FEATURE_VALUE_CAPS( preparsed ); + *caps_end = *caps + preparsed->feature_caps_count; break; default: return HIDP_STATUS_INVALID_REPORT_TYPE; }
- *caps_end = *caps + preparsed->value_caps_count[report_type]; return HIDP_STATUS_SUCCESS; }
@@ -165,12 +167,58 @@ NTSTATUS WINAPI HidP_GetButtonCaps( HIDP_REPORT_TYPE report_type, HIDP_BUTTON_CA NTSTATUS WINAPI HidP_GetCaps( PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps ) { struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data; + struct hid_value_caps *it, *end;
TRACE( "preparsed_data %p, caps %p.\n", preparsed_data, caps );
if (!preparsed || preparsed->magic != HID_MAGIC) return HIDP_STATUS_INVALID_PREPARSED_DATA;
- *caps = preparsed->caps; + caps->Usage = preparsed->usage; + caps->UsagePage = preparsed->usage_page; + caps->InputReportByteLength = preparsed->input_report_byte_length; + caps->OutputReportByteLength = preparsed->output_report_byte_length; + caps->FeatureReportByteLength = preparsed->feature_report_byte_length; + caps->NumberLinkCollectionNodes = preparsed->number_link_collection_nodes; + caps->NumberInputButtonCaps = 0; + caps->NumberInputValueCaps = 0; + caps->NumberInputDataIndices = 0; + caps->NumberOutputButtonCaps = 0; + caps->NumberOutputValueCaps = 0; + caps->NumberOutputDataIndices = 0; + caps->NumberFeatureButtonCaps = 0; + caps->NumberFeatureValueCaps = 0; + caps->NumberFeatureDataIndices = 0; + + for (it = HID_INPUT_VALUE_CAPS( preparsed ), end = it + preparsed->input_caps_count; + it != end; ++it) + { + if (!it->usage_min && !it->usage_max) continue; + if (it->flags & HID_VALUE_CAPS_IS_BUTTON) caps->NumberInputButtonCaps++; + else caps->NumberInputValueCaps++; + if (!(it->flags & HID_VALUE_CAPS_IS_RANGE)) caps->NumberInputDataIndices++; + else caps->NumberInputDataIndices += it->data_index_max - it->data_index_min + 1; + } + + for (it = HID_OUTPUT_VALUE_CAPS( preparsed ), end = it + preparsed->output_caps_count; + it != end; ++it) + { + if (!it->usage_min && !it->usage_max) continue; + if (it->flags & HID_VALUE_CAPS_IS_BUTTON) caps->NumberOutputButtonCaps++; + else caps->NumberOutputValueCaps++; + if (!(it->flags & HID_VALUE_CAPS_IS_RANGE)) caps->NumberOutputDataIndices++; + else caps->NumberOutputDataIndices += it->data_index_max - it->data_index_min + 1; + } + + for (it = HID_FEATURE_VALUE_CAPS( preparsed ), end = it + preparsed->feature_caps_count; + it != end; ++it) + { + if (!it->usage_min && !it->usage_max) continue; + if (it->flags & HID_VALUE_CAPS_IS_BUTTON) caps->NumberFeatureButtonCaps++; + else caps->NumberFeatureValueCaps++; + if (!(it->flags & HID_VALUE_CAPS_IS_RANGE)) caps->NumberFeatureDataIndices++; + else caps->NumberFeatureDataIndices += it->data_index_max - it->data_index_min + 1; + } + return HIDP_STATUS_SUCCESS; }
@@ -956,7 +1004,7 @@ NTSTATUS WINAPI HidP_GetLinkCollectionNodes( HIDP_LINK_COLLECTION_NODE *nodes, U
if (!preparsed || preparsed->magic != HID_MAGIC) return HIDP_STATUS_INVALID_PREPARSED_DATA;
- count = *nodes_len = preparsed->caps.NumberLinkCollectionNodes; + count = *nodes_len = preparsed->number_link_collection_nodes; if (capacity < count) return HIDP_STATUS_BUFFER_TOO_SMALL;
for (i = 0; i < count; ++i) diff --git a/dlls/hidparse.sys/main.c b/dlls/hidparse.sys/main.c index 3170abc50b5..d1191a20789 100644 --- a/dlls/hidparse.sys/main.c +++ b/dlls/hidparse.sys/main.c @@ -116,30 +116,20 @@ static void debug_print_preparsed( struct hid_preparsed_data *data )
if (TRACE_ON( hidp )) { - TRACE( "START PREPARSED Data <<< Usage: %i, UsagePage: %i, " - "InputReportByteLength: %i, tOutputReportByteLength: %i, " - "FeatureReportByteLength: %i, NumberLinkCollectionNodes: %i, " - "NumberInputButtonCaps: %i, NumberInputValueCaps: %i, " - "NumberInputDataIndices: %i, NumberOutputButtonCaps: %i, " - "NumberOutputValueCaps: %i, NumberOutputDataIndices: %i, " - "NumberFeatureButtonCaps: %i, NumberFeatureValueCaps: %i, " - "NumberFeatureDataIndices: %i\n", - data->caps.Usage, data->caps.UsagePage, data->caps.InputReportByteLength, - data->caps.OutputReportByteLength, data->caps.FeatureReportByteLength, - data->caps.NumberLinkCollectionNodes, data->caps.NumberInputButtonCaps, - data->caps.NumberInputValueCaps, data->caps.NumberInputDataIndices, - data->caps.NumberOutputButtonCaps, data->caps.NumberOutputValueCaps, - data->caps.NumberOutputDataIndices, data->caps.NumberFeatureButtonCaps, - data->caps.NumberFeatureValueCaps, data->caps.NumberFeatureDataIndices ); - end = data->value_caps_count[HidP_Input]; - for (i = 0; i < end; i++) TRACE( "INPUT: %s\n", debugstr_hid_value_caps( HID_INPUT_VALUE_CAPS( data ) + i ) ); - end = data->value_caps_count[HidP_Output]; - for (i = 0; i < end; i++) TRACE( "OUTPUT: %s\n", debugstr_hid_value_caps( HID_OUTPUT_VALUE_CAPS( data ) + i ) ); - end = data->value_caps_count[HidP_Feature]; - for (i = 0; i < end; i++) TRACE( "FEATURE: %s\n", debugstr_hid_value_caps( HID_FEATURE_VALUE_CAPS( data ) + i ) ); - end = data->caps.NumberLinkCollectionNodes; - for (i = 0; i < end; i++) TRACE( "COLLECTION: %s\n", debugstr_hid_value_caps( HID_COLLECTION_VALUE_CAPS( data ) + i ) ); - TRACE(">>> END Preparsed Data\n"); + TRACE( "usage %02x:%02x input %u-(%u)-%u, report len %u output %u-(%u)-%u, report len %u " + "feature %u-(%u)-%u, report len %u collections %u\n", data->usage_page, data->usage, + data->input_caps_start, data->input_caps_count, data->input_caps_end, data->input_report_byte_length, + data->output_caps_start, data->output_caps_count, data->output_caps_end, data->output_report_byte_length, + data->feature_caps_start, data->feature_caps_count, data->feature_caps_end, data->feature_report_byte_length, + data->number_link_collection_nodes ); + end = data->input_caps_count; + for (i = 0; i < end; i++) TRACE( "input %d: %s\n", i, debugstr_hid_value_caps( HID_INPUT_VALUE_CAPS( data ) + i ) ); + end = data->output_caps_count; + for (i = 0; i < end; i++) TRACE( "output %d: %s\n", i, debugstr_hid_value_caps( HID_OUTPUT_VALUE_CAPS( data ) + i ) ); + end = data->feature_caps_count; + for (i = 0; i < end; i++) TRACE( "feature %d: %s\n", i, debugstr_hid_value_caps( HID_FEATURE_VALUE_CAPS( data ) + i ) ); + end = data->number_link_collection_nodes; + for (i = 0; i < end; i++) TRACE( "collection %d: %s\n", i, debugstr_hid_value_caps( HID_COLLECTION_VALUE_CAPS( data ) + i ) ); } }
@@ -416,7 +406,7 @@ static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state { struct hid_preparsed_data *data; struct hid_value_caps *caps; - DWORD i, button, filler, caps_len, size; + DWORD caps_len, size;
caps_len = state->caps.NumberInputValueCaps + state->caps.NumberOutputValueCaps + state->caps.NumberFeatureValueCaps + state->caps.NumberLinkCollectionNodes; @@ -426,47 +416,30 @@ static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state memset( data, 0, size ); data->magic = HID_MAGIC; data->size = size; - data->caps = state->caps; - data->value_caps_count[HidP_Input] = state->caps.NumberInputValueCaps; - data->value_caps_count[HidP_Output] = state->caps.NumberOutputValueCaps; - data->value_caps_count[HidP_Feature] = state->caps.NumberFeatureValueCaps; - - /* fixup value vs button vs filler counts */ + data->usage = state->caps.Usage; + data->usage_page = state->caps.UsagePage; + data->input_caps_start = 0; + data->input_caps_count = state->caps.NumberInputValueCaps; + data->input_caps_end = data->input_caps_start + data->input_caps_count; + data->input_report_byte_length = state->caps.InputReportByteLength; + data->output_caps_start = data->input_caps_end; + data->output_caps_count = state->caps.NumberOutputValueCaps; + data->output_caps_end = data->output_caps_start + data->output_caps_count; + data->output_report_byte_length = state->caps.OutputReportByteLength; + data->feature_caps_start = data->output_caps_end; + data->feature_caps_count = state->caps.NumberFeatureValueCaps; + data->feature_caps_end = data->feature_caps_start + data->feature_caps_count; + data->feature_report_byte_length = state->caps.FeatureReportByteLength; + data->number_link_collection_nodes = state->caps.NumberLinkCollectionNodes;
caps = HID_INPUT_VALUE_CAPS( data ); - memcpy( caps, state->values[0], data->caps.NumberInputValueCaps * sizeof(*caps) ); - for (i = 0, button = 0, filler = 0; i < data->caps.NumberInputValueCaps; ++i) - { - if (!caps[i].usage_min && !caps[i].usage_max) filler++; - else if (caps[i].flags & HID_VALUE_CAPS_IS_BUTTON) button++; - } - data->caps.NumberInputButtonCaps = button; - data->caps.NumberInputValueCaps -= filler + button; - + memcpy( caps, state->values[0], data->input_caps_count * sizeof(*caps) ); caps = HID_OUTPUT_VALUE_CAPS( data ); - memcpy( caps, state->values[1], data->caps.NumberOutputValueCaps * sizeof(*caps) ); - for (i = 0, button = 0, filler = 0; i < data->caps.NumberOutputValueCaps; ++i) - { - if (!caps[i].usage_min && !caps[i].usage_max) filler++; - else if (caps[i].flags & HID_VALUE_CAPS_IS_BUTTON) button++; - } - caps += data->caps.NumberOutputValueCaps; - data->caps.NumberOutputButtonCaps = button; - data->caps.NumberOutputValueCaps -= filler + button; - + memcpy( caps, state->values[1], data->output_caps_count * sizeof(*caps) ); caps = HID_FEATURE_VALUE_CAPS( data ); - memcpy( caps, state->values[2], data->caps.NumberFeatureValueCaps * sizeof(*caps) ); - for (i = 0, button = 0, filler = 0; i < data->caps.NumberFeatureValueCaps; ++i) - { - if (!caps[i].usage_min && !caps[i].usage_max) filler++; - else if (caps[i].flags & HID_VALUE_CAPS_IS_BUTTON) button++; - } - caps += data->caps.NumberFeatureValueCaps; - data->caps.NumberFeatureButtonCaps = button; - data->caps.NumberFeatureValueCaps -= filler + button; - + memcpy( caps, state->values[2], data->feature_caps_count * sizeof(*caps) ); caps = HID_COLLECTION_VALUE_CAPS( data ); - memcpy( caps, state->collections, data->caps.NumberLinkCollectionNodes * sizeof(*caps) ); + memcpy( caps, state->collections, data->number_link_collection_nodes * sizeof(*caps) );
return data; } @@ -645,17 +618,17 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de }
device_desc->CollectionDescLength = 1; - device_desc->CollectionDesc[0].UsagePage = preparsed->caps.UsagePage; - device_desc->CollectionDesc[0].Usage = preparsed->caps.Usage; + device_desc->CollectionDesc[0].UsagePage = preparsed->usage_page; + device_desc->CollectionDesc[0].Usage = preparsed->usage; device_desc->CollectionDesc[0].CollectionNumber = 1; - device_desc->CollectionDesc[0].InputLength = preparsed->caps.InputReportByteLength; - device_desc->CollectionDesc[0].OutputLength = preparsed->caps.OutputReportByteLength; - device_desc->CollectionDesc[0].FeatureLength = preparsed->caps.FeatureReportByteLength; + device_desc->CollectionDesc[0].InputLength = preparsed->input_report_byte_length; + device_desc->CollectionDesc[0].OutputLength = preparsed->output_report_byte_length; + device_desc->CollectionDesc[0].FeatureLength = preparsed->feature_report_byte_length; device_desc->CollectionDesc[0].PreparsedDataLength = preparsed->size; device_desc->CollectionDesc[0].PreparsedData = (PHIDP_PREPARSED_DATA)preparsed;
caps = HID_INPUT_VALUE_CAPS( preparsed ); - caps_end = caps + preparsed->value_caps_count[HidP_Input]; + caps_end = caps + preparsed->input_caps_count; for (; caps != caps_end; ++caps) { len = caps->start_byte * 8 + caps->start_bit + caps->bit_size * caps->report_count; @@ -664,7 +637,7 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de }
caps = HID_OUTPUT_VALUE_CAPS( preparsed ); - caps_end = caps + preparsed->value_caps_count[HidP_Output]; + caps_end = caps + preparsed->output_caps_count; for (; caps != caps_end; ++caps) { len = caps->start_byte * 8 + caps->start_bit + caps->bit_size * caps->report_count; @@ -673,7 +646,7 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de }
caps = HID_FEATURE_VALUE_CAPS( preparsed ); - caps_end = caps + preparsed->value_caps_count[HidP_Feature]; + caps_end = caps + preparsed->feature_caps_count; for (; caps != caps_end; ++caps) { len = caps->start_byte * 8 + caps->start_bit + caps->bit_size * caps->report_count; diff --git a/include/wine/hid.h b/include/wine/hid.h index 43f881bcc52..10fccda07cc 100644 --- a/include/wine/hid.h +++ b/include/wine/hid.h @@ -76,14 +76,27 @@ struct hid_preparsed_data { DWORD magic; DWORD size; - HIDP_CAPS caps; - USHORT value_caps_count[3]; + USAGE usage; + USAGE usage_page; + USHORT input_caps_start; + USHORT input_caps_count; + USHORT input_caps_end; + USHORT input_report_byte_length; + USHORT output_caps_start; + USHORT output_caps_count; + USHORT output_caps_end; + USHORT output_report_byte_length; + USHORT feature_caps_start; + USHORT feature_caps_count; + USHORT feature_caps_end; + USHORT feature_report_byte_length; + USHORT number_link_collection_nodes; struct hid_value_caps value_caps[1]; };
-#define HID_INPUT_VALUE_CAPS(d) ((d)->value_caps) -#define HID_OUTPUT_VALUE_CAPS(d) (HID_INPUT_VALUE_CAPS(d) + (d)->value_caps_count[0]) -#define HID_FEATURE_VALUE_CAPS(d) (HID_OUTPUT_VALUE_CAPS(d) + (d)->value_caps_count[1]) -#define HID_COLLECTION_VALUE_CAPS(d) (HID_FEATURE_VALUE_CAPS(d) + (d)->value_caps_count[2]) +#define HID_INPUT_VALUE_CAPS(d) ((d)->value_caps + (d)->input_caps_start) +#define HID_OUTPUT_VALUE_CAPS(d) ((d)->value_caps + (d)->output_caps_start) +#define HID_FEATURE_VALUE_CAPS(d) ((d)->value_caps + (d)->feature_caps_start) +#define HID_COLLECTION_VALUE_CAPS(d) ((d)->value_caps + (d)->feature_caps_end)
#endif /* __WINE_PARSE_H */