2 * HID descriptor parsing
4 * Copyright (C) 2015 Aric Stewart
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/debug.h"
27 #include "wine/list.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(hid
);
31 /* Flags that are defined in the document
32 "Device Class Definition for Human Interface Devices" */
34 INPUT_DATA_CONST
= 0x01, /* Data (0) | Constant (1) */
35 INPUT_ARRAY_VAR
= 0x02, /* Array (0) | Variable (1) */
36 INPUT_ABS_REL
= 0x04, /* Absolute (0) | Relative (1) */
37 INPUT_WRAP
= 0x08, /* No Wrap (0) | Wrap (1) */
38 INPUT_LINEAR
= 0x10, /* Linear (0) | Non Linear (1) */
39 INPUT_PREFSTATE
= 0x20, /* Preferred State (0) | No Preferred (1) */
40 INPUT_NULL
= 0x40, /* No Null position (0) | Null state(1) */
41 INPUT_VOLATILE
= 0x80, /* Non Volatile (0) | Volatile (1) */
42 INPUT_BITFIELD
= 0x100 /* Bit Field (0) | Buffered Bytes (1) */
53 TAG_MAIN_INPUT
= 0x08,
54 TAG_MAIN_OUTPUT
= 0x09,
55 TAG_MAIN_FEATURE
= 0x0B,
56 TAG_MAIN_COLLECTION
= 0x0A,
57 TAG_MAIN_END_COLLECTION
= 0x0C
61 TAG_GLOBAL_USAGE_PAGE
= 0x0,
62 TAG_GLOBAL_LOGICAL_MINIMUM
,
63 TAG_GLOBAL_LOGICAL_MAXIMUM
,
64 TAG_GLOBAL_PHYSICAL_MINIMUM
,
65 TAG_GLOBAL_PHYSICAL_MAXIMUM
,
66 TAG_GLOBAL_UNIT_EXPONENT
,
68 TAG_GLOBAL_REPORT_SIZE
,
70 TAG_GLOBAL_REPORT_COUNT
,
76 TAG_LOCAL_USAGE
= 0x0,
77 TAG_LOCAL_USAGE_MINIMUM
,
78 TAG_LOCAL_USAGE_MAXIMUM
,
79 TAG_LOCAL_DESIGNATOR_INDEX
,
80 TAG_LOCAL_DESIGNATOR_MINIMUM
,
81 TAG_LOCAL_DESIGNATOR_MAXIMUM
,
82 TAG_LOCAL_STRING_INDEX
,
83 TAG_LOCAL_STRING_MINIMUM
,
84 TAG_LOCAL_STRING_MAXIMUM
,
89 static const char* const feature_string
[] =
90 { "Input", "Output", "Feature" };
96 HIDP_REPORT_TYPE type
;
100 static const char* const collection_string
[] = {
113 struct collection
*parent
;
114 struct list features
;
115 struct list collections
;
118 static inline const char *debugstr_hidp_value_caps( HIDP_VALUE_CAPS
*caps
)
120 if (!caps
) return "(null)";
121 return wine_dbg_sprintf( "RId %d, Usg %02x:%02x-%02x Dat %02x-%02x (%d), Str %d-%d (%d), Des %d-%d (%d), "
122 "Bits %02x, Als %d, Abs %d, Nul %d, LCol %d LUsg %02x:%02x, BitSz %d, RCnt %d, "
123 "Unit %x E%+d, Log %+d-%+d, Phy %+d-%+d",
124 caps
->ReportID
, caps
->UsagePage
, caps
->Range
.UsageMin
, caps
->Range
.UsageMax
, caps
->Range
.DataIndexMin
, caps
->Range
.DataIndexMax
, caps
->IsRange
,
125 caps
->Range
.StringMin
, caps
->Range
.StringMax
, caps
->IsStringRange
, caps
->Range
.DesignatorMin
, caps
->Range
.DesignatorMax
, caps
->IsDesignatorRange
,
126 caps
->BitField
, caps
->IsAlias
, caps
->IsAbsolute
, caps
->HasNull
, caps
->LinkCollection
, caps
->LinkUsagePage
, caps
->LinkUsage
, caps
->BitSize
, caps
->ReportCount
,
127 caps
->Units
, caps
->UnitsExp
, caps
->LogicalMin
, caps
->LogicalMax
, caps
->PhysicalMin
, caps
->PhysicalMax
);
130 static void copy_hidp_value_caps( HIDP_VALUE_CAPS
*out
, const struct hid_value_caps
*in
)
132 out
->UsagePage
= in
->usage_page
;
133 out
->ReportID
= in
->report_id
;
134 out
->LinkCollection
= in
->link_collection
;
135 out
->LinkUsagePage
= in
->link_usage_page
;
136 out
->LinkUsage
= in
->link_usage
;
137 out
->BitField
= in
->bit_field
;
138 out
->IsAlias
= FALSE
;
139 out
->IsAbsolute
= HID_VALUE_CAPS_IS_ABSOLUTE( in
);
140 out
->HasNull
= HID_VALUE_CAPS_HAS_NULL( in
);
141 out
->BitSize
= in
->bit_size
;
142 out
->ReportCount
= in
->report_count
;
143 out
->UnitsExp
= in
->units_exp
;
144 out
->Units
= in
->units
;
145 out
->LogicalMin
= in
->logical_min
;
146 out
->LogicalMax
= in
->logical_max
;
147 out
->PhysicalMin
= in
->physical_min
;
148 out
->PhysicalMax
= in
->physical_max
;
149 if (!(out
->IsRange
= in
->is_range
))
150 out
->NotRange
.Usage
= in
->usage_min
;
153 out
->Range
.UsageMin
= in
->usage_min
;
154 out
->Range
.UsageMax
= in
->usage_max
;
156 if (!(out
->IsStringRange
= in
->is_string_range
))
157 out
->NotRange
.StringIndex
= in
->string_min
;
160 out
->Range
.StringMin
= in
->string_min
;
161 out
->Range
.StringMax
= in
->string_max
;
163 if ((out
->IsDesignatorRange
= in
->is_designator_range
))
164 out
->NotRange
.DesignatorIndex
= in
->designator_min
;
167 out
->Range
.DesignatorMin
= in
->designator_min
;
168 out
->Range
.DesignatorMax
= in
->designator_max
;
172 static void debug_feature(struct feature
*feature
)
176 TRACE( "[Feature type %s %s]\n", feature_string
[feature
->type
], (feature
->isData
) ? "Data" : "Const" );
178 TRACE("Feature %s\n", debugstr_hidp_value_caps(&feature
->caps
));
181 static void debug_collection(struct collection
*collection
)
183 struct feature
*fentry
;
184 struct collection
*centry
;
187 TRACE( "START Collection <<< %s, parent: %p, %i features, %i collections\n",
188 collection_string
[collection
->type
], collection
->parent
,
189 list_count( &collection
->features
), list_count( &collection
->collections
) );
190 LIST_FOR_EACH_ENTRY(fentry
, &collection
->features
, struct feature
, entry
)
191 debug_feature(fentry
);
192 LIST_FOR_EACH_ENTRY(centry
, &collection
->collections
, struct collection
, entry
)
193 debug_collection(centry
);
194 TRACE( ">>> END Collection\n" );
198 static void debug_print_report(const char* type
, WINE_HIDP_PREPARSED_DATA
*data
,
199 WINE_HID_REPORT
*report
)
201 WINE_HID_ELEMENT
*elems
= HID_ELEMS(data
);
203 TRACE("START Report %i <<< %s report : bitSize: %i elementCount: %i\n",
207 report
->elementCount
);
208 for (i
= 0; i
< report
->elementCount
; i
++)
210 WINE_HID_ELEMENT
*elem
= elems
+ report
->elementIdx
+ i
;
211 TRACE("%s: %s, StartBit %d, BitCount %d\n", type
, debugstr_hidp_value_caps(&elem
->caps
), elem
->valueStartBit
, elem
->bitCount
);
213 TRACE(">>> END Report %i\n",report
->reportID
);
216 static void debug_print_preparsed(WINE_HIDP_PREPARSED_DATA
*data
)
221 TRACE("START PREPARSED Data <<< dwSize: %i Usage: %i, UsagePage: %i, "
222 "InputReportByteLength: %i, tOutputReportByteLength: %i, "
223 "FeatureReportByteLength: %i, NumberLinkCollectionNodes: %i, "
224 "NumberInputButtonCaps: %i, NumberInputValueCaps: %i, "
225 "NumberInputDataIndices: %i, NumberOutputButtonCaps: %i, "
226 "NumberOutputValueCaps: %i, NumberOutputDataIndices: %i, "
227 "NumberFeatureButtonCaps: %i, NumberFeatureValueCaps: %i, "
228 "NumberFeatureDataIndices: %i, reportCount[HidP_Input]: %i, "
229 "reportCount[HidP_Output]: %i, reportCount[HidP_Feature]: %i, "
230 "elementOffset: %i\n",
233 data
->caps
.UsagePage
,
234 data
->caps
.InputReportByteLength
,
235 data
->caps
.OutputReportByteLength
,
236 data
->caps
.FeatureReportByteLength
,
237 data
->caps
.NumberLinkCollectionNodes
,
238 data
->caps
.NumberInputButtonCaps
,
239 data
->caps
.NumberInputValueCaps
,
240 data
->caps
.NumberInputDataIndices
,
241 data
->caps
.NumberOutputButtonCaps
,
242 data
->caps
.NumberOutputValueCaps
,
243 data
->caps
.NumberOutputDataIndices
,
244 data
->caps
.NumberFeatureButtonCaps
,
245 data
->caps
.NumberFeatureValueCaps
,
246 data
->caps
.NumberFeatureDataIndices
,
247 data
->reportCount
[HidP_Input
],
248 data
->reportCount
[HidP_Output
],
249 data
->reportCount
[HidP_Feature
],
250 data
->elementOffset
);
252 end
= data
->reportCount
[HidP_Input
];
253 for (i
= 0; i
< end
; i
++)
255 debug_print_report("INPUT", data
, &data
->reports
[i
]);
257 end
+= data
->reportCount
[HidP_Output
];
260 debug_print_report("OUTPUT", data
, &data
->reports
[i
]);
262 end
+= data
->reportCount
[HidP_Feature
];
265 debug_print_report("FEATURE", data
, &data
->reports
[i
]);
267 TRACE(">>> END Preparsed Data\n");
271 struct hid_parser_state
278 struct hid_value_caps items
;
280 struct hid_value_caps
*stack
;
283 DWORD collection_idx
;
285 struct hid_value_caps
*collections
;
286 DWORD collections_size
;
289 static BOOL
array_reserve( struct hid_value_caps
**array
, DWORD
*array_size
, DWORD index
)
291 if (index
< *array_size
) return TRUE
;
292 if ((*array_size
= *array_size
? (*array_size
* 3 / 2) : 32) <= index
) return FALSE
;
293 if (!(*array
= realloc( *array
, *array_size
* sizeof(**array
) ))) return FALSE
;
297 static void copy_global_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
299 dst
->usage_page
= src
->usage_page
;
300 dst
->logical_min
= src
->logical_min
;
301 dst
->logical_max
= src
->logical_max
;
302 dst
->physical_min
= src
->physical_min
;
303 dst
->physical_max
= src
->physical_max
;
304 dst
->units_exp
= src
->units_exp
;
305 dst
->units
= src
->units
;
306 dst
->bit_size
= src
->bit_size
;
307 dst
->report_id
= src
->report_id
;
308 dst
->report_count
= src
->report_count
;
311 static void copy_collection_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
313 dst
->link_collection
= src
->link_collection
;
314 dst
->link_usage_page
= src
->link_usage_page
;
315 dst
->link_usage
= src
->link_usage
;
318 static void reset_local_items( struct hid_parser_state
*state
)
320 struct hid_value_caps tmp
;
321 copy_global_items( &tmp
, &state
->items
);
322 copy_collection_items( &tmp
, &state
->items
);
323 memset( &state
->items
, 0, sizeof(state
->items
) );
324 copy_global_items( &state
->items
, &tmp
);
325 copy_collection_items( &state
->items
, &tmp
);
326 state
->usages_size
= 0;
329 static BOOL
parse_global_push( struct hid_parser_state
*state
)
331 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->global_idx
))
333 ERR( "HID parser stack overflow!\n" );
337 copy_global_items( state
->stack
+ state
->global_idx
, &state
->items
);
342 static BOOL
parse_global_pop( struct hid_parser_state
*state
)
344 if (!state
->global_idx
)
346 ERR( "HID parser global stack underflow!\n" );
351 copy_global_items( &state
->items
, state
->stack
+ state
->global_idx
);
355 static BOOL
parse_local_usage( struct hid_parser_state
*state
, USAGE usage
)
357 state
->usages
[state
->usages_size
] = usage
;
358 state
->items
.is_range
= FALSE
;
359 if (state
->usages_size
++ == 255) ERR( "HID parser usages stack overflow!\n" );
360 return state
->usages_size
<= 255;
363 static BOOL
parse_new_collection( struct hid_parser_state
*state
)
365 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->collection_idx
))
367 ERR( "HID parser stack overflow!\n" );
371 if (!array_reserve( &state
->collections
, &state
->collections_size
, state
->caps
.NumberLinkCollectionNodes
))
373 ERR( "HID parser collections overflow!\n" );
377 copy_collection_items( state
->stack
+ state
->collection_idx
, &state
->items
);
378 state
->collection_idx
++;
380 state
->collections
[state
->caps
.NumberLinkCollectionNodes
] = state
->items
;
381 state
->items
.link_collection
= state
->caps
.NumberLinkCollectionNodes
;
382 state
->items
.link_usage_page
= state
->items
.usage_page
;
383 state
->items
.link_usage
= state
->items
.usage_min
;
384 if (!state
->caps
.NumberLinkCollectionNodes
)
386 state
->caps
.UsagePage
= state
->items
.usage_page
;
387 state
->caps
.Usage
= state
->items
.usage_min
;
389 state
->caps
.NumberLinkCollectionNodes
++;
391 reset_local_items( state
);
395 static BOOL
parse_end_collection( struct hid_parser_state
*state
)
397 if (!state
->collection_idx
)
399 ERR( "HID parser collection stack underflow!\n" );
403 state
->collection_idx
--;
404 copy_collection_items( &state
->items
, state
->stack
+ state
->collection_idx
);
405 reset_local_items( state
);
409 static BOOL
parse_new_value_caps( struct hid_parser_state
*state
, HIDP_REPORT_TYPE type
, struct collection
*collection
)
411 struct feature
*feature
;
414 for (j
= 0; j
< state
->items
.report_count
; j
++)
416 if (!(feature
= calloc( 1, sizeof(*feature
) ))) return -1;
417 list_add_tail( &collection
->features
, &feature
->entry
);
418 feature
->type
= type
;
419 feature
->isData
= ((state
->items
.bit_field
& INPUT_DATA_CONST
) == 0);
420 if (j
< state
->usages_size
) state
->items
.usage_min
= state
->usages
[j
];
421 copy_hidp_value_caps( &feature
->caps
, &state
->items
);
422 feature
->caps
.ReportCount
= 1;
423 if (j
+ 1 >= state
->usages_size
)
425 feature
->caps
.ReportCount
+= state
->items
.report_count
- (j
+ 1);
430 reset_local_items( state
);
434 static void free_parser_state( struct hid_parser_state
*state
)
436 if (state
->global_idx
) ERR( "%u unpopped device caps on the stack\n", state
->global_idx
);
437 if (state
->collection_idx
) ERR( "%u unpopped device collection on the stack\n", state
->collection_idx
);
438 free( state
->stack
);
439 free( state
->collections
);
443 static void parse_collection(unsigned int bSize
, int itemVal
,
444 struct collection
*collection
)
448 collection
->type
= itemVal
;
450 if (itemVal
>= 0x07 && itemVal
<= 0x7F) {
451 ERR(" (Reserved 0x%x )\n", itemVal
);
453 else if (itemVal
>= 0x80 && itemVal
<= 0xFF) {
454 ERR(" (Vendor Defined 0x%x )\n", itemVal
);
459 static int parse_descriptor( BYTE
*descriptor
, unsigned int index
, unsigned int length
,
460 struct collection
*collection
, struct hid_parser_state
*state
)
466 for (i
= index
; i
< length
;)
468 BYTE item
= descriptor
[i
++];
469 int size
= item
& 0x03;
471 if (size
== 3) size
= 4;
472 if (length
- i
< size
)
474 ERR("Need %d bytes to read item value\n", size
);
478 if (size
== 0) signed_value
= value
= 0;
479 else if (size
== 1) signed_value
= (INT8
)(value
= *(UINT8
*)(descriptor
+ i
));
480 else if (size
== 2) signed_value
= (INT16
)(value
= *(UINT16
*)(descriptor
+ i
));
481 else if (size
== 4) signed_value
= (INT32
)(value
= *(UINT32
*)(descriptor
+ i
));
484 ERR("Unexpected item value size %d.\n", size
);
489 state
->items
.bit_field
= value
;
491 #define SHORT_ITEM(tag,type) (((tag)<<4)|((type)<<2))
492 switch (item
& SHORT_ITEM(0xf,0x3))
494 case SHORT_ITEM(TAG_MAIN_INPUT
, TAG_TYPE_MAIN
):
495 if (!parse_new_value_caps( state
, HidP_Input
, collection
)) return -1;
497 case SHORT_ITEM(TAG_MAIN_OUTPUT
, TAG_TYPE_MAIN
):
498 if (!parse_new_value_caps( state
, HidP_Output
, collection
)) return -1;
500 case SHORT_ITEM(TAG_MAIN_FEATURE
, TAG_TYPE_MAIN
):
501 if (!parse_new_value_caps( state
, HidP_Feature
, collection
)) return -1;
503 case SHORT_ITEM(TAG_MAIN_COLLECTION
, TAG_TYPE_MAIN
):
505 struct collection
*subcollection
;
506 if (!(subcollection
= calloc(1, sizeof(struct collection
)))) return -1;
507 list_add_tail(&collection
->collections
, &subcollection
->entry
);
508 subcollection
->parent
= collection
;
509 /* Only set our collection once...
510 We do not properly handle composite devices yet. */
511 if (state
->usages_size
) state
->items
.usage_min
= state
->usages
[state
->usages_size
- 1];
512 list_init(&subcollection
->features
);
513 list_init(&subcollection
->collections
);
514 parse_collection(size
, value
, subcollection
);
515 if (!parse_new_collection( state
)) return -1;
517 if ((i
= parse_descriptor( descriptor
, i
, length
, subcollection
, state
)) < 0) return i
;
520 case SHORT_ITEM(TAG_MAIN_END_COLLECTION
, TAG_TYPE_MAIN
):
521 if (!parse_end_collection( state
)) return -1;
524 case SHORT_ITEM(TAG_GLOBAL_USAGE_PAGE
, TAG_TYPE_GLOBAL
):
525 state
->items
.usage_page
= value
;
527 case SHORT_ITEM(TAG_GLOBAL_LOGICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
528 state
->items
.logical_min
= signed_value
;
530 case SHORT_ITEM(TAG_GLOBAL_LOGICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
531 state
->items
.logical_max
= signed_value
;
533 case SHORT_ITEM(TAG_GLOBAL_PHYSICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
534 state
->items
.physical_min
= signed_value
;
536 case SHORT_ITEM(TAG_GLOBAL_PHYSICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
537 state
->items
.physical_max
= signed_value
;
539 case SHORT_ITEM(TAG_GLOBAL_UNIT_EXPONENT
, TAG_TYPE_GLOBAL
):
540 state
->items
.units_exp
= signed_value
;
542 case SHORT_ITEM(TAG_GLOBAL_UNIT
, TAG_TYPE_GLOBAL
):
543 state
->items
.units
= signed_value
;
545 case SHORT_ITEM(TAG_GLOBAL_REPORT_SIZE
, TAG_TYPE_GLOBAL
):
546 state
->items
.bit_size
= value
;
548 case SHORT_ITEM(TAG_GLOBAL_REPORT_ID
, TAG_TYPE_GLOBAL
):
549 state
->items
.report_id
= value
;
551 case SHORT_ITEM(TAG_GLOBAL_REPORT_COUNT
, TAG_TYPE_GLOBAL
):
552 state
->items
.report_count
= value
;
554 case SHORT_ITEM(TAG_GLOBAL_PUSH
, TAG_TYPE_GLOBAL
):
555 if (!parse_global_push( state
)) return -1;
557 case SHORT_ITEM(TAG_GLOBAL_POP
, TAG_TYPE_GLOBAL
):
558 if (!parse_global_pop( state
)) return -1;
561 case SHORT_ITEM(TAG_LOCAL_USAGE
, TAG_TYPE_LOCAL
):
562 if (!parse_local_usage( state
, value
)) return -1;
564 case SHORT_ITEM(TAG_LOCAL_USAGE_MINIMUM
, TAG_TYPE_LOCAL
):
565 state
->items
.usage_min
= value
;
566 state
->items
.is_range
= TRUE
;
568 case SHORT_ITEM(TAG_LOCAL_USAGE_MAXIMUM
, TAG_TYPE_LOCAL
):
569 state
->items
.usage_max
= value
;
570 state
->items
.is_range
= TRUE
;
572 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_INDEX
, TAG_TYPE_LOCAL
):
573 state
->items
.designator_min
= state
->items
.designator_max
= value
;
574 state
->items
.is_designator_range
= FALSE
;
576 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_MINIMUM
, TAG_TYPE_LOCAL
):
577 state
->items
.designator_min
= value
;
578 state
->items
.is_designator_range
= TRUE
;
580 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_MAXIMUM
, TAG_TYPE_LOCAL
):
581 state
->items
.designator_max
= value
;
582 state
->items
.is_designator_range
= TRUE
;
584 case SHORT_ITEM(TAG_LOCAL_STRING_INDEX
, TAG_TYPE_LOCAL
):
585 state
->items
.string_min
= state
->items
.string_max
= value
;
586 state
->items
.is_string_range
= FALSE
;
588 case SHORT_ITEM(TAG_LOCAL_STRING_MINIMUM
, TAG_TYPE_LOCAL
):
589 state
->items
.string_min
= value
;
590 state
->items
.is_string_range
= TRUE
;
592 case SHORT_ITEM(TAG_LOCAL_STRING_MAXIMUM
, TAG_TYPE_LOCAL
):
593 state
->items
.string_max
= value
;
594 state
->items
.is_string_range
= TRUE
;
596 case SHORT_ITEM(TAG_LOCAL_DELIMITER
, TAG_TYPE_LOCAL
):
597 FIXME("delimiter %d not implemented!\n", value
);
601 FIXME("item type %x not implemented!\n", item
);
609 static void build_elements(WINE_HID_REPORT
*wine_report
, WINE_HID_ELEMENT
*elems
,
610 struct feature
* feature
, USHORT
*data_index
)
612 WINE_HID_ELEMENT
*wine_element
= elems
+ wine_report
->elementIdx
+ wine_report
->elementCount
;
615 if (!feature
->isData
)
617 wine_report
->bitSize
+= feature
->caps
.BitSize
* feature
->caps
.ReportCount
;
621 wine_element
->valueStartBit
= wine_report
->bitSize
;
623 wine_element
->bitCount
= (feature
->caps
.BitSize
* feature
->caps
.ReportCount
);
624 wine_report
->bitSize
+= wine_element
->bitCount
;
626 wine_element
->caps
= feature
->caps
;
628 if (wine_element
->caps
.IsRange
)
630 if (wine_element
->caps
.BitSize
== 1) index_count
= wine_element
->bitCount
- 1;
631 else index_count
= wine_element
->caps
.Range
.UsageMax
- wine_element
->caps
.Range
.UsageMin
;
632 wine_element
->caps
.Range
.DataIndexMin
= *data_index
;
633 wine_element
->caps
.Range
.DataIndexMax
= *data_index
+ index_count
;
634 *data_index
= *data_index
+ index_count
+ 1;
638 wine_element
->caps
.NotRange
.DataIndex
= *data_index
;
639 wine_element
->caps
.NotRange
.Reserved4
= *data_index
;
640 *data_index
= *data_index
+ 1;
643 wine_report
->elementCount
++;
646 static void count_elements(struct feature
* feature
, USHORT
*buttons
, USHORT
*values
)
648 if (!feature
->isData
)
651 if (feature
->caps
.BitSize
== 1)
661 int report_elem_count
[3][256];
664 BOOL report_created
[3][256];
667 static void create_preparse_ctx(const struct collection
*base
, struct preparse_ctx
*ctx
)
670 struct collection
*c
;
672 LIST_FOR_EACH_ENTRY(f
, &base
->features
, struct feature
, entry
)
675 ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
]++;
676 if (ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
] != 1)
678 ctx
->report_count
[f
->type
]++;
681 LIST_FOR_EACH_ENTRY(c
, &base
->collections
, struct collection
, entry
)
682 create_preparse_ctx(c
, ctx
);
685 static void preparse_collection(const struct collection
*root
, const struct collection
*base
,
686 WINE_HIDP_PREPARSED_DATA
*data
, struct preparse_ctx
*ctx
)
688 WINE_HID_ELEMENT
*elem
= HID_ELEMS(data
);
690 struct collection
*c
;
692 LIST_FOR_EACH_ENTRY(f
, &base
->features
, struct feature
, entry
)
694 WINE_HID_REPORT
*report
;
696 if (!ctx
->report_created
[f
->type
][f
->caps
.ReportID
])
698 ctx
->report_created
[f
->type
][f
->caps
.ReportID
] = TRUE
;
699 data
->reportIdx
[f
->type
][f
->caps
.ReportID
] = data
->reportCount
[f
->type
]++;
700 if (f
->type
> 0) data
->reportIdx
[f
->type
][f
->caps
.ReportID
] += ctx
->report_count
[0];
701 if (f
->type
> 1) data
->reportIdx
[f
->type
][f
->caps
.ReportID
] += ctx
->report_count
[1];
703 report
= &data
->reports
[data
->reportIdx
[f
->type
][f
->caps
.ReportID
]];
704 report
->reportID
= f
->caps
.ReportID
;
705 /* Room for the reportID */
707 report
->elementIdx
= ctx
->elem_alloc
;
708 ctx
->elem_alloc
+= ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
];
711 report
= &data
->reports
[data
->reportIdx
[f
->type
][f
->caps
.ReportID
]];
715 build_elements(report
, elem
, f
, &data
->caps
.NumberInputDataIndices
);
716 count_elements(f
, &data
->caps
.NumberInputButtonCaps
, &data
->caps
.NumberInputValueCaps
);
717 data
->caps
.InputReportByteLength
=
718 max(data
->caps
.InputReportByteLength
, (report
->bitSize
+ 7) / 8);
721 build_elements(report
, elem
, f
, &data
->caps
.NumberOutputDataIndices
);
722 count_elements(f
, &data
->caps
.NumberOutputButtonCaps
, &data
->caps
.NumberOutputValueCaps
);
723 data
->caps
.OutputReportByteLength
=
724 max(data
->caps
.OutputReportByteLength
, (report
->bitSize
+ 7) / 8);
727 build_elements(report
, elem
, f
, &data
->caps
.NumberFeatureDataIndices
);
728 count_elements(f
, &data
->caps
.NumberFeatureButtonCaps
, &data
->caps
.NumberFeatureValueCaps
);
729 data
->caps
.FeatureReportByteLength
=
730 max(data
->caps
.FeatureReportByteLength
, (report
->bitSize
+ 7) / 8);
735 LIST_FOR_EACH_ENTRY(c
, &base
->collections
, struct collection
, entry
)
736 preparse_collection(root
, c
, data
, ctx
);
739 static WINE_HIDP_PREPARSED_DATA
*build_preparsed_data( struct collection
*base_collection
,
740 struct hid_parser_state
*state
)
742 WINE_HID_LINK_COLLECTION_NODE
*nodes
;
743 WINE_HIDP_PREPARSED_DATA
*data
;
744 unsigned int report_count
;
748 struct preparse_ctx ctx
;
749 unsigned int element_off
;
750 unsigned int nodes_offset
;
752 memset(&ctx
, 0, sizeof(ctx
));
753 create_preparse_ctx(base_collection
, &ctx
);
755 report_count
= ctx
.report_count
[HidP_Input
] + ctx
.report_count
[HidP_Output
]
756 + ctx
.report_count
[HidP_Feature
];
757 element_off
= FIELD_OFFSET(WINE_HIDP_PREPARSED_DATA
, reports
[report_count
]);
758 size
= element_off
+ (ctx
.elem_count
* sizeof(WINE_HID_ELEMENT
));
761 size
+= state
->caps
.NumberLinkCollectionNodes
* sizeof(WINE_HID_LINK_COLLECTION_NODE
);
763 if (!(data
= calloc(1, size
))) return NULL
;
764 data
->magic
= HID_MAGIC
;
766 data
->caps
= state
->caps
;
767 data
->elementOffset
= element_off
;
768 data
->nodesOffset
= nodes_offset
;
770 preparse_collection(base_collection
, base_collection
, data
, &ctx
);
772 nodes
= HID_NODES( data
);
773 for (i
= 0; i
< data
->caps
.NumberLinkCollectionNodes
; ++i
)
775 nodes
[i
].LinkUsagePage
= state
->collections
[i
].usage_page
;
776 nodes
[i
].LinkUsage
= state
->collections
[i
].usage_min
;
777 nodes
[i
].Parent
= state
->collections
[i
].link_collection
;
778 nodes
[i
].CollectionType
= state
->collections
[i
].bit_field
;
779 nodes
[i
].IsAlias
= 0;
783 nodes
[i
].NextSibling
= nodes
[nodes
[i
].Parent
].FirstChild
;
784 nodes
[nodes
[i
].Parent
].FirstChild
= i
;
785 nodes
[nodes
[i
].Parent
].NumberOfChildren
++;
792 static void free_collection(struct collection
*collection
)
794 struct feature
*fentry
, *fnext
;
795 struct collection
*centry
, *cnext
;
796 LIST_FOR_EACH_ENTRY_SAFE(centry
, cnext
, &collection
->collections
, struct collection
, entry
)
798 list_remove(¢ry
->entry
);
799 free_collection(centry
);
801 LIST_FOR_EACH_ENTRY_SAFE(fentry
, fnext
, &collection
->features
, struct feature
, entry
)
803 list_remove(&fentry
->entry
);
809 WINE_HIDP_PREPARSED_DATA
* ParseDescriptor(BYTE
*descriptor
, unsigned int length
)
811 WINE_HIDP_PREPARSED_DATA
*data
= NULL
;
812 struct hid_parser_state
*state
;
813 struct collection
*base
;
818 TRACE("descriptor %p, length %u:\n", descriptor
, length
);
819 for (i
= 0; i
< length
;)
822 do { TRACE(" %02x", descriptor
[i
]); } while (++i
% 16 && i
< length
);
827 if (!(state
= calloc( 1, sizeof(*state
) ))) return NULL
;
828 if (!(base
= calloc( 1, sizeof(*base
) )))
833 list_init(&base
->features
);
834 list_init(&base
->collections
);
836 if (parse_descriptor( descriptor
, 0, length
, base
, state
) < 0)
838 free_collection(base
);
839 free_parser_state( state
);
843 debug_collection(base
);
845 if ((data
= build_preparsed_data( base
, state
)))
846 debug_print_preparsed(data
);
847 free_collection(base
);
849 free_parser_state( state
);