hidparse.sys: Precompute collection node list on the parser side.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2c677b1fea
commit
75e74b3a73
|
@ -997,7 +997,7 @@ NTSTATUS WINAPI HidP_GetData( HIDP_REPORT_TYPE report_type, HIDP_DATA *data, ULO
|
|||
NTSTATUS WINAPI HidP_GetLinkCollectionNodes( HIDP_LINK_COLLECTION_NODE *nodes, ULONG *nodes_len, PHIDP_PREPARSED_DATA preparsed_data )
|
||||
{
|
||||
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
|
||||
struct hid_value_caps *caps = HID_COLLECTION_VALUE_CAPS( preparsed );
|
||||
struct hid_collection_node *collections = HID_COLLECTION_NODES( preparsed );
|
||||
ULONG i, count, capacity = *nodes_len;
|
||||
|
||||
TRACE( "nodes %p, nodes_len %p, preparsed_data %p.\n", nodes, nodes_len, preparsed_data );
|
||||
|
@ -1009,21 +1009,14 @@ NTSTATUS WINAPI HidP_GetLinkCollectionNodes( HIDP_LINK_COLLECTION_NODE *nodes, U
|
|||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
nodes[i].LinkUsagePage = caps[i].usage_page;
|
||||
nodes[i].LinkUsage = caps[i].usage_min;
|
||||
nodes[i].Parent = caps[i].link_collection;
|
||||
nodes[i].CollectionType = caps[i].bit_field;
|
||||
nodes[i].LinkUsagePage = collections[i].usage_page;
|
||||
nodes[i].LinkUsage = collections[i].usage;
|
||||
nodes[i].Parent = collections[i].parent;
|
||||
nodes[i].CollectionType = collections[i].collection_type;
|
||||
nodes[i].FirstChild = collections[i].first_child;
|
||||
nodes[i].NextSibling = collections[i].next_sibling;
|
||||
nodes[i].NumberOfChildren = collections[i].number_of_children;
|
||||
nodes[i].IsAlias = 0;
|
||||
nodes[i].FirstChild = 0;
|
||||
nodes[i].NextSibling = 0;
|
||||
nodes[i].NumberOfChildren = 0;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
nodes[i].NextSibling = nodes[nodes[i].Parent].FirstChild;
|
||||
nodes[nodes[i].Parent].FirstChild = i;
|
||||
nodes[nodes[i].Parent].NumberOfChildren++;
|
||||
}
|
||||
}
|
||||
|
||||
return HIDP_STATUS_SUCCESS;
|
||||
|
|
|
@ -110,6 +110,14 @@ static inline const char *debugstr_hid_value_caps( struct hid_value_caps *caps )
|
|||
caps->units, caps->units_exp, caps->logical_min, caps->logical_max, caps->physical_min, caps->physical_max );
|
||||
}
|
||||
|
||||
static inline const char *debugstr_hid_collection_node( struct hid_collection_node *node )
|
||||
{
|
||||
if (!node) return "(null)";
|
||||
return wine_dbg_sprintf( "Usg %02x:%02x, Parent %u, Next %u, NbChild %u, Child %u, Type %02x",
|
||||
node->usage_page, node->usage, node->parent, node->next_sibling,
|
||||
node->number_of_children, node->first_child, node->collection_type );
|
||||
}
|
||||
|
||||
static void debug_print_preparsed( struct hid_preparsed_data *data )
|
||||
{
|
||||
unsigned int i, end;
|
||||
|
@ -129,7 +137,7 @@ static void debug_print_preparsed( struct hid_preparsed_data *data )
|
|||
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 ) );
|
||||
for (i = 0; i < end; i++) TRACE( "collection %d: %s\n", i, debugstr_hid_collection_node( HID_COLLECTION_NODES( data ) + i ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,16 +401,20 @@ static void free_parser_state( struct hid_parser_state *state )
|
|||
|
||||
static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state *state, POOL_TYPE pool_type )
|
||||
{
|
||||
struct hid_collection_node *nodes;
|
||||
struct hid_preparsed_data *data;
|
||||
struct hid_value_caps *caps;
|
||||
DWORD caps_len, size;
|
||||
DWORD i, size, caps_size;
|
||||
|
||||
caps_len = state->caps_count[HidP_Input] + state->caps_count[HidP_Output] +
|
||||
state->caps_count[HidP_Feature] + state->number_link_collection_nodes;
|
||||
size = FIELD_OFFSET( struct hid_preparsed_data, value_caps[caps_len] );
|
||||
caps_size = state->caps_count[HidP_Input] + state->caps_count[HidP_Output] +
|
||||
state->caps_count[HidP_Feature];
|
||||
caps_size *= sizeof(struct hid_value_caps);
|
||||
|
||||
size = caps_size + FIELD_OFFSET(struct hid_preparsed_data, value_caps[0]) +
|
||||
state->number_link_collection_nodes * sizeof(struct hid_collection_node);
|
||||
if (!(data = ExAllocatePool( pool_type, size ))) return NULL;
|
||||
memset( data, 0, size );
|
||||
|
||||
data->magic = HID_MAGIC;
|
||||
data->size = size;
|
||||
data->usage = state->usage;
|
||||
|
@ -419,6 +431,7 @@ static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state
|
|||
data->feature_caps_count = state->caps_count[HidP_Feature];
|
||||
data->feature_caps_end = data->feature_caps_start + data->feature_caps_count;
|
||||
data->feature_report_byte_length = state->byte_length[HidP_Feature];
|
||||
data->caps_size = caps_size;
|
||||
data->number_link_collection_nodes = state->number_link_collection_nodes;
|
||||
|
||||
caps = HID_INPUT_VALUE_CAPS( data );
|
||||
|
@ -427,8 +440,25 @@ static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state
|
|||
memcpy( caps, state->values[1], data->output_caps_count * sizeof(*caps) );
|
||||
caps = HID_FEATURE_VALUE_CAPS( data );
|
||||
memcpy( caps, state->values[2], data->feature_caps_count * sizeof(*caps) );
|
||||
caps = HID_COLLECTION_VALUE_CAPS( data );
|
||||
memcpy( caps, state->collections, data->number_link_collection_nodes * sizeof(*caps) );
|
||||
|
||||
nodes = HID_COLLECTION_NODES( data );
|
||||
for (i = 0; i < data->number_link_collection_nodes; ++i)
|
||||
{
|
||||
nodes[i].usage_page = state->collections[i].usage_page;
|
||||
nodes[i].usage = state->collections[i].usage_min;
|
||||
nodes[i].parent = state->collections[i].link_collection;
|
||||
nodes[i].collection_type = state->collections[i].bit_field;
|
||||
nodes[i].first_child = 0;
|
||||
nodes[i].next_sibling = 0;
|
||||
nodes[i].number_of_children = 0;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
nodes[i].next_sibling = nodes[nodes[i].parent].first_child;
|
||||
nodes[nodes[i].parent].first_child = i;
|
||||
nodes[nodes[i].parent].number_of_children++;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,17 @@
|
|||
|
||||
#define HID_MAGIC 0x8491759
|
||||
|
||||
struct hid_collection_node
|
||||
{
|
||||
USAGE usage;
|
||||
USAGE usage_page;
|
||||
USHORT parent;
|
||||
USHORT number_of_children;
|
||||
USHORT next_sibling;
|
||||
USHORT first_child;
|
||||
ULONG collection_type;
|
||||
};
|
||||
|
||||
struct hid_value_caps
|
||||
{
|
||||
USAGE usage_page;
|
||||
|
@ -90,13 +101,15 @@ struct hid_preparsed_data
|
|||
USHORT feature_caps_count;
|
||||
USHORT feature_caps_end;
|
||||
USHORT feature_report_byte_length;
|
||||
USHORT caps_size;
|
||||
USHORT number_link_collection_nodes;
|
||||
struct hid_value_caps value_caps[1];
|
||||
/* struct hid_collection_node nodes[1] */
|
||||
};
|
||||
|
||||
#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)
|
||||
#define HID_COLLECTION_NODES(d) (struct hid_collection_node *)((char *)(d)->value_caps + (d)->caps_size)
|
||||
|
||||
#endif /* __WINE_PARSE_H */
|
||||
|
|
Loading…
Reference in New Issue