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
;
108 struct collection
*collection
;
111 static const char* const collection_string
[] = {
123 HIDP_VALUE_CAPS caps
;
126 struct collection
*parent
;
127 struct list features
;
128 struct list collections
;
131 static inline const char *debugstr_hidp_value_caps( HIDP_VALUE_CAPS
*caps
)
133 if (!caps
) return "(null)";
134 return wine_dbg_sprintf( "RId %d, Usg %02x:%02x-%02x Dat %02x-%02x (%d), Str %d-%d (%d), Des %d-%d (%d), "
135 "Bits %02x, Als %d, Abs %d, Nul %d, LCol %d LUsg %02x:%02x, BitSz %d, RCnt %d, "
136 "Unit %x E%+d, Log %+d-%+d, Phy %+d-%+d",
137 caps
->ReportID
, caps
->UsagePage
, caps
->Range
.UsageMin
, caps
->Range
.UsageMax
, caps
->Range
.DataIndexMin
, caps
->Range
.DataIndexMax
, caps
->IsRange
,
138 caps
->Range
.StringMin
, caps
->Range
.StringMax
, caps
->IsStringRange
, caps
->Range
.DesignatorMin
, caps
->Range
.DesignatorMax
, caps
->IsDesignatorRange
,
139 caps
->BitField
, caps
->IsAlias
, caps
->IsAbsolute
, caps
->HasNull
, caps
->LinkCollection
, caps
->LinkUsagePage
, caps
->LinkUsage
, caps
->BitSize
, caps
->ReportCount
,
140 caps
->Units
, caps
->UnitsExp
, caps
->LogicalMin
, caps
->LogicalMax
, caps
->PhysicalMin
, caps
->PhysicalMax
);
143 static void copy_hidp_value_caps( HIDP_VALUE_CAPS
*out
, const struct hid_value_caps
*in
)
145 out
->UsagePage
= in
->usage_page
;
146 out
->ReportID
= in
->report_id
;
147 out
->IsAlias
= FALSE
;
148 out
->BitSize
= in
->bit_size
;
149 out
->ReportCount
= in
->report_count
;
150 out
->UnitsExp
= in
->units_exp
;
151 out
->Units
= in
->units
;
152 out
->LogicalMin
= in
->logical_min
;
153 out
->LogicalMax
= in
->logical_max
;
154 out
->PhysicalMin
= in
->physical_min
;
155 out
->PhysicalMax
= in
->physical_max
;
156 if (!(out
->IsRange
= in
->is_range
))
157 out
->NotRange
.Usage
= in
->usage_min
;
160 out
->Range
.UsageMin
= in
->usage_min
;
161 out
->Range
.UsageMax
= in
->usage_max
;
163 if (!(out
->IsStringRange
= in
->is_string_range
))
164 out
->NotRange
.StringIndex
= in
->string_min
;
167 out
->Range
.StringMin
= in
->string_min
;
168 out
->Range
.StringMax
= in
->string_max
;
170 if ((out
->IsDesignatorRange
= in
->is_designator_range
))
171 out
->NotRange
.DesignatorIndex
= in
->designator_min
;
174 out
->Range
.DesignatorMin
= in
->designator_min
;
175 out
->Range
.DesignatorMax
= in
->designator_max
;
179 static void debug_feature(struct feature
*feature
)
183 TRACE("[Feature type %s [%i]; %s; %s; %s; %s; %s; %s; %s; %s; %s]\n",
184 feature_string
[feature
->type
],
186 (feature
->isData
)?"Data":"Const",
187 (feature
->isArray
)?"Array":"Var",
188 (feature
->IsAbsolute
)?"Abs":"Rel",
189 (feature
->Wrap
)?"Wrap":"NoWrap",
190 (feature
->Linear
)?"Linear":"NonLinear",
191 (feature
->prefState
)?"PrefStat":"NoPrefState",
192 (feature
->HasNull
)?"HasNull":"NoNull",
193 (feature
->Volatile
)?"Volatile":"NonVolatile",
194 (feature
->BitField
)?"BitField":"Buffered");
196 TRACE("Feature %s\n", debugstr_hidp_value_caps(&feature
->caps
));
199 static void debug_collection(struct collection
*collection
)
201 struct feature
*fentry
;
202 struct collection
*centry
;
205 TRACE("START Collection %i <<< %s, parent: %p, %i features, %i collections\n",
206 collection
->index
, collection_string
[collection
->type
], collection
->parent
,
207 list_count(&collection
->features
), list_count(&collection
->collections
));
208 TRACE("Collection %s\n", debugstr_hidp_value_caps(&collection
->caps
));
209 LIST_FOR_EACH_ENTRY(fentry
, &collection
->features
, struct feature
, entry
)
210 debug_feature(fentry
);
211 LIST_FOR_EACH_ENTRY(centry
, &collection
->collections
, struct collection
, entry
)
212 debug_collection(centry
);
213 TRACE(">>> END Collection %i\n", collection
->index
);
217 static void debug_print_report(const char* type
, WINE_HIDP_PREPARSED_DATA
*data
,
218 WINE_HID_REPORT
*report
)
220 WINE_HID_ELEMENT
*elems
= HID_ELEMS(data
);
222 TRACE("START Report %i <<< %s report : bitSize: %i elementCount: %i\n",
226 report
->elementCount
);
227 for (i
= 0; i
< report
->elementCount
; i
++)
229 WINE_HID_ELEMENT
*elem
= elems
+ report
->elementIdx
+ i
;
230 TRACE("%s: %s, StartBit %d, BitCount %d\n", type
, debugstr_hidp_value_caps(&elem
->caps
), elem
->valueStartBit
, elem
->bitCount
);
232 TRACE(">>> END Report %i\n",report
->reportID
);
235 static void debug_print_preparsed(WINE_HIDP_PREPARSED_DATA
*data
)
240 TRACE("START PREPARSED Data <<< dwSize: %i Usage: %i, UsagePage: %i, "
241 "InputReportByteLength: %i, tOutputReportByteLength: %i, "
242 "FeatureReportByteLength: %i, NumberLinkCollectionNodes: %i, "
243 "NumberInputButtonCaps: %i, NumberInputValueCaps: %i, "
244 "NumberInputDataIndices: %i, NumberOutputButtonCaps: %i, "
245 "NumberOutputValueCaps: %i, NumberOutputDataIndices: %i, "
246 "NumberFeatureButtonCaps: %i, NumberFeatureValueCaps: %i, "
247 "NumberFeatureDataIndices: %i, reportCount[HidP_Input]: %i, "
248 "reportCount[HidP_Output]: %i, reportCount[HidP_Feature]: %i, "
249 "elementOffset: %i\n",
252 data
->caps
.UsagePage
,
253 data
->caps
.InputReportByteLength
,
254 data
->caps
.OutputReportByteLength
,
255 data
->caps
.FeatureReportByteLength
,
256 data
->caps
.NumberLinkCollectionNodes
,
257 data
->caps
.NumberInputButtonCaps
,
258 data
->caps
.NumberInputValueCaps
,
259 data
->caps
.NumberInputDataIndices
,
260 data
->caps
.NumberOutputButtonCaps
,
261 data
->caps
.NumberOutputValueCaps
,
262 data
->caps
.NumberOutputDataIndices
,
263 data
->caps
.NumberFeatureButtonCaps
,
264 data
->caps
.NumberFeatureValueCaps
,
265 data
->caps
.NumberFeatureDataIndices
,
266 data
->reportCount
[HidP_Input
],
267 data
->reportCount
[HidP_Output
],
268 data
->reportCount
[HidP_Feature
],
269 data
->elementOffset
);
271 end
= data
->reportCount
[HidP_Input
];
272 for (i
= 0; i
< end
; i
++)
274 debug_print_report("INPUT", data
, &data
->reports
[i
]);
276 end
+= data
->reportCount
[HidP_Output
];
279 debug_print_report("OUTPUT", data
, &data
->reports
[i
]);
281 end
+= data
->reportCount
[HidP_Feature
];
284 debug_print_report("FEATURE", data
, &data
->reports
[i
]);
286 TRACE(">>> END Preparsed Data\n");
290 struct hid_parser_state
295 struct hid_value_caps items
;
297 struct hid_value_caps
*stack
;
302 static BOOL
array_reserve( struct hid_value_caps
**array
, DWORD
*array_size
, DWORD index
)
304 if (index
< *array_size
) return TRUE
;
305 if ((*array_size
= *array_size
? (*array_size
* 3 / 2) : 32) <= index
) return FALSE
;
306 if (!(*array
= realloc( *array
, *array_size
* sizeof(**array
) ))) return FALSE
;
310 static void copy_global_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
312 dst
->usage_page
= src
->usage_page
;
313 dst
->logical_min
= src
->logical_min
;
314 dst
->logical_max
= src
->logical_max
;
315 dst
->physical_min
= src
->physical_min
;
316 dst
->physical_max
= src
->physical_max
;
317 dst
->units_exp
= src
->units_exp
;
318 dst
->units
= src
->units
;
319 dst
->bit_size
= src
->bit_size
;
320 dst
->report_id
= src
->report_id
;
321 dst
->report_count
= src
->report_count
;
324 static void reset_local_items( struct hid_parser_state
*state
)
326 struct hid_value_caps tmp
;
327 copy_global_items( &tmp
, &state
->items
);
328 memset( &state
->items
, 0, sizeof(state
->items
) );
329 copy_global_items( &state
->items
, &tmp
);
330 state
->usages_size
= 0;
333 static BOOL
parse_global_push( struct hid_parser_state
*state
)
335 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->global_idx
))
337 ERR( "HID parser stack overflow!\n" );
341 copy_global_items( state
->stack
+ state
->global_idx
, &state
->items
);
346 static BOOL
parse_global_pop( struct hid_parser_state
*state
)
348 if (!state
->global_idx
)
350 ERR( "HID parser global stack underflow!\n" );
355 copy_global_items( &state
->items
, state
->stack
+ state
->global_idx
);
359 static BOOL
parse_local_usage( struct hid_parser_state
*state
, USAGE usage
)
361 state
->usages
[state
->usages_size
] = usage
;
362 state
->items
.is_range
= FALSE
;
363 if (state
->usages_size
++ == 255) ERR( "HID parser usages stack overflow!\n" );
364 return state
->usages_size
<= 255;
367 static void free_parser_state( struct hid_parser_state
*state
)
369 if (state
->global_idx
) ERR( "%u unpopped device caps on the stack\n", state
->global_idx
);
370 free( state
->stack
);
374 static void parse_io_feature(unsigned int bSize
, int itemVal
, int bTag
,
375 unsigned int *feature_index
,
376 struct feature
*feature
)
384 feature
->isData
= ((itemVal
& INPUT_DATA_CONST
) == 0);
385 feature
->isArray
= ((itemVal
& INPUT_ARRAY_VAR
) == 0);
386 feature
->IsAbsolute
= ((itemVal
& INPUT_ABS_REL
) == 0);
387 feature
->Wrap
= ((itemVal
& INPUT_WRAP
) != 0);
388 feature
->Linear
= ((itemVal
& INPUT_LINEAR
) == 0);
389 feature
->prefState
= ((itemVal
& INPUT_PREFSTATE
) == 0);
390 feature
->HasNull
= ((itemVal
& INPUT_NULL
) != 0);
392 if (bTag
!= TAG_MAIN_INPUT
)
394 feature
->Volatile
= ((itemVal
& INPUT_VOLATILE
) != 0);
398 feature
->BitField
= ((itemVal
& INPUT_BITFIELD
) == 0);
400 feature
->index
= *feature_index
;
401 *feature_index
= *feature_index
+ 1;
405 static void parse_collection(unsigned int bSize
, int itemVal
,
406 struct collection
*collection
)
410 collection
->type
= itemVal
;
412 if (itemVal
>= 0x07 && itemVal
<= 0x7F) {
413 ERR(" (Reserved 0x%x )\n", itemVal
);
415 else if (itemVal
>= 0x80 && itemVal
<= 0xFF) {
416 ERR(" (Vendor Defined 0x%x )\n", itemVal
);
421 static int parse_descriptor( BYTE
*descriptor
, unsigned int index
, unsigned int length
,
422 unsigned int *feature_index
, unsigned int *collection_index
,
423 struct collection
*collection
, struct hid_parser_state
*state
)
428 struct feature
*feature
;
430 for (i
= index
; i
< length
;)
432 BYTE item
= descriptor
[i
++];
433 BYTE tag
= item
>> 4;
434 int size
= item
& 0x03;
436 if (size
== 3) size
= 4;
437 if (length
- i
< size
)
439 ERR("Need %d bytes to read item value\n", size
);
443 if (size
== 0) signed_value
= value
= 0;
444 else if (size
== 1) signed_value
= (INT8
)(value
= *(UINT8
*)(descriptor
+ i
));
445 else if (size
== 2) signed_value
= (INT16
)(value
= *(UINT16
*)(descriptor
+ i
));
446 else if (size
== 4) signed_value
= (INT32
)(value
= *(UINT32
*)(descriptor
+ i
));
449 ERR("Unexpected item value size %d.\n", size
);
454 #define SHORT_ITEM(tag,type) (((tag)<<4)|((type)<<2))
455 switch (item
& SHORT_ITEM(0xf,0x3))
457 case SHORT_ITEM(TAG_MAIN_INPUT
, TAG_TYPE_MAIN
):
458 case SHORT_ITEM(TAG_MAIN_OUTPUT
, TAG_TYPE_MAIN
):
459 case SHORT_ITEM(TAG_MAIN_FEATURE
, TAG_TYPE_MAIN
):
460 for (j
= 0; j
< state
->items
.report_count
; j
++)
462 if (!(feature
= calloc(1, sizeof(*feature
)))) return -1;
463 list_add_tail(&collection
->features
, &feature
->entry
);
464 if (tag
== TAG_MAIN_INPUT
)
465 feature
->type
= HidP_Input
;
466 else if (tag
== TAG_MAIN_OUTPUT
)
467 feature
->type
= HidP_Output
;
469 feature
->type
= HidP_Feature
;
470 parse_io_feature(size
, value
, tag
, feature_index
, feature
);
471 if (j
< state
->usages_size
) state
->items
.usage_min
= state
->usages
[j
];
472 copy_hidp_value_caps( &feature
->caps
, &state
->items
);
473 feature
->caps
.ReportCount
= 1;
474 feature
->collection
= collection
;
475 if (j
+ 1 >= state
->usages_size
)
477 feature
->caps
.ReportCount
+= state
->items
.report_count
- (j
+ 1);
481 reset_local_items( state
);
483 case SHORT_ITEM(TAG_MAIN_COLLECTION
, TAG_TYPE_MAIN
):
485 struct collection
*subcollection
;
486 if (!(subcollection
= calloc(1, sizeof(struct collection
)))) return -1;
487 list_add_tail(&collection
->collections
, &subcollection
->entry
);
488 subcollection
->parent
= collection
;
489 /* Only set our collection once...
490 We do not properly handle composite devices yet. */
491 if (state
->usages_size
) state
->items
.usage_min
= state
->usages
[state
->usages_size
- 1];
492 if (*collection_index
== 0) copy_hidp_value_caps( &collection
->caps
, &state
->items
);
493 copy_hidp_value_caps( &subcollection
->caps
, &state
->items
);
494 subcollection
->index
= *collection_index
;
495 *collection_index
= *collection_index
+ 1;
496 list_init(&subcollection
->features
);
497 list_init(&subcollection
->collections
);
498 parse_collection(size
, value
, subcollection
);
499 reset_local_items( state
);
501 if ((i
= parse_descriptor( descriptor
, i
, length
, feature_index
, collection_index
,
502 subcollection
, state
)) < 0)
506 case SHORT_ITEM(TAG_MAIN_END_COLLECTION
, TAG_TYPE_MAIN
):
507 reset_local_items( state
);
510 case SHORT_ITEM(TAG_GLOBAL_USAGE_PAGE
, TAG_TYPE_GLOBAL
):
511 state
->items
.usage_page
= value
;
513 case SHORT_ITEM(TAG_GLOBAL_LOGICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
514 state
->items
.logical_min
= signed_value
;
516 case SHORT_ITEM(TAG_GLOBAL_LOGICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
517 state
->items
.logical_max
= signed_value
;
519 case SHORT_ITEM(TAG_GLOBAL_PHYSICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
520 state
->items
.physical_min
= signed_value
;
522 case SHORT_ITEM(TAG_GLOBAL_PHYSICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
523 state
->items
.physical_max
= signed_value
;
525 case SHORT_ITEM(TAG_GLOBAL_UNIT_EXPONENT
, TAG_TYPE_GLOBAL
):
526 state
->items
.units_exp
= signed_value
;
528 case SHORT_ITEM(TAG_GLOBAL_UNIT
, TAG_TYPE_GLOBAL
):
529 state
->items
.units
= signed_value
;
531 case SHORT_ITEM(TAG_GLOBAL_REPORT_SIZE
, TAG_TYPE_GLOBAL
):
532 state
->items
.bit_size
= value
;
534 case SHORT_ITEM(TAG_GLOBAL_REPORT_ID
, TAG_TYPE_GLOBAL
):
535 state
->items
.report_id
= value
;
537 case SHORT_ITEM(TAG_GLOBAL_REPORT_COUNT
, TAG_TYPE_GLOBAL
):
538 state
->items
.report_count
= value
;
540 case SHORT_ITEM(TAG_GLOBAL_PUSH
, TAG_TYPE_GLOBAL
):
541 if (!parse_global_push( state
)) return -1;
543 case SHORT_ITEM(TAG_GLOBAL_POP
, TAG_TYPE_GLOBAL
):
544 if (!parse_global_pop( state
)) return -1;
547 case SHORT_ITEM(TAG_LOCAL_USAGE
, TAG_TYPE_LOCAL
):
548 if (!parse_local_usage( state
, value
)) return -1;
550 case SHORT_ITEM(TAG_LOCAL_USAGE_MINIMUM
, TAG_TYPE_LOCAL
):
551 state
->items
.usage_min
= value
;
552 state
->items
.is_range
= TRUE
;
554 case SHORT_ITEM(TAG_LOCAL_USAGE_MAXIMUM
, TAG_TYPE_LOCAL
):
555 state
->items
.usage_max
= value
;
556 state
->items
.is_range
= TRUE
;
558 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_INDEX
, TAG_TYPE_LOCAL
):
559 state
->items
.designator_min
= state
->items
.designator_max
= value
;
560 state
->items
.is_designator_range
= FALSE
;
562 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_MINIMUM
, TAG_TYPE_LOCAL
):
563 state
->items
.designator_min
= value
;
564 state
->items
.is_designator_range
= TRUE
;
566 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_MAXIMUM
, TAG_TYPE_LOCAL
):
567 state
->items
.designator_max
= value
;
568 state
->items
.is_designator_range
= TRUE
;
570 case SHORT_ITEM(TAG_LOCAL_STRING_INDEX
, TAG_TYPE_LOCAL
):
571 state
->items
.string_min
= state
->items
.string_max
= value
;
572 state
->items
.is_string_range
= FALSE
;
574 case SHORT_ITEM(TAG_LOCAL_STRING_MINIMUM
, TAG_TYPE_LOCAL
):
575 state
->items
.string_min
= value
;
576 state
->items
.is_string_range
= TRUE
;
578 case SHORT_ITEM(TAG_LOCAL_STRING_MAXIMUM
, TAG_TYPE_LOCAL
):
579 state
->items
.string_max
= value
;
580 state
->items
.is_string_range
= TRUE
;
582 case SHORT_ITEM(TAG_LOCAL_DELIMITER
, TAG_TYPE_LOCAL
):
583 FIXME("delimiter %d not implemented!\n", value
);
587 FIXME("item type %x not implemented!\n", item
);
595 static void build_elements(WINE_HID_REPORT
*wine_report
, WINE_HID_ELEMENT
*elems
,
596 struct feature
* feature
, USHORT
*data_index
)
598 WINE_HID_ELEMENT
*wine_element
= elems
+ wine_report
->elementIdx
+ wine_report
->elementCount
;
601 if (!feature
->isData
)
603 wine_report
->bitSize
+= feature
->caps
.BitSize
* feature
->caps
.ReportCount
;
607 wine_element
->valueStartBit
= wine_report
->bitSize
;
609 wine_element
->bitCount
= (feature
->caps
.BitSize
* feature
->caps
.ReportCount
);
610 wine_report
->bitSize
+= wine_element
->bitCount
;
612 wine_element
->caps
= feature
->caps
;
613 wine_element
->caps
.BitField
= feature
->BitField
;
614 wine_element
->caps
.LinkCollection
= feature
->collection
->index
;
615 wine_element
->caps
.LinkUsage
= feature
->collection
->caps
.NotRange
.Usage
;
616 wine_element
->caps
.LinkUsagePage
= feature
->collection
->caps
.UsagePage
;
617 wine_element
->caps
.IsAbsolute
= feature
->IsAbsolute
;
618 wine_element
->caps
.HasNull
= feature
->HasNull
;
620 if (wine_element
->caps
.IsRange
)
622 if (wine_element
->caps
.BitSize
== 1) index_count
= wine_element
->bitCount
- 1;
623 else index_count
= wine_element
->caps
.Range
.UsageMax
- wine_element
->caps
.Range
.UsageMin
;
624 wine_element
->caps
.Range
.DataIndexMin
= *data_index
;
625 wine_element
->caps
.Range
.DataIndexMax
= *data_index
+ index_count
;
626 *data_index
= *data_index
+ index_count
+ 1;
630 wine_element
->caps
.NotRange
.DataIndex
= *data_index
;
631 wine_element
->caps
.NotRange
.Reserved4
= *data_index
;
632 *data_index
= *data_index
+ 1;
635 wine_report
->elementCount
++;
638 static void count_elements(struct feature
* feature
, USHORT
*buttons
, USHORT
*values
)
640 if (!feature
->isData
)
643 if (feature
->caps
.BitSize
== 1)
653 int report_elem_count
[3][256];
656 BOOL report_created
[3][256];
659 static void create_preparse_ctx(const struct collection
*base
, struct preparse_ctx
*ctx
)
662 struct collection
*c
;
664 LIST_FOR_EACH_ENTRY(f
, &base
->features
, struct feature
, entry
)
667 ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
]++;
668 if (ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
] != 1)
670 ctx
->report_count
[f
->type
]++;
673 LIST_FOR_EACH_ENTRY(c
, &base
->collections
, struct collection
, entry
)
674 create_preparse_ctx(c
, ctx
);
677 static void preparse_collection(const struct collection
*root
, const struct collection
*base
,
678 WINE_HIDP_PREPARSED_DATA
*data
, struct preparse_ctx
*ctx
)
680 WINE_HID_ELEMENT
*elem
= HID_ELEMS(data
);
681 WINE_HID_LINK_COLLECTION_NODE
*nodes
= HID_NODES(data
);
683 struct collection
*c
;
686 LIST_FOR_EACH_ENTRY(f
, &base
->features
, struct feature
, entry
)
688 WINE_HID_REPORT
*report
;
690 if (!ctx
->report_created
[f
->type
][f
->caps
.ReportID
])
692 ctx
->report_created
[f
->type
][f
->caps
.ReportID
] = TRUE
;
693 data
->reportIdx
[f
->type
][f
->caps
.ReportID
] = data
->reportCount
[f
->type
]++;
694 if (f
->type
> 0) data
->reportIdx
[f
->type
][f
->caps
.ReportID
] += ctx
->report_count
[0];
695 if (f
->type
> 1) data
->reportIdx
[f
->type
][f
->caps
.ReportID
] += ctx
->report_count
[1];
697 report
= &data
->reports
[data
->reportIdx
[f
->type
][f
->caps
.ReportID
]];
698 report
->reportID
= f
->caps
.ReportID
;
699 /* Room for the reportID */
701 report
->elementIdx
= ctx
->elem_alloc
;
702 ctx
->elem_alloc
+= ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
];
705 report
= &data
->reports
[data
->reportIdx
[f
->type
][f
->caps
.ReportID
]];
709 build_elements(report
, elem
, f
, &data
->caps
.NumberInputDataIndices
);
710 count_elements(f
, &data
->caps
.NumberInputButtonCaps
, &data
->caps
.NumberInputValueCaps
);
711 data
->caps
.InputReportByteLength
=
712 max(data
->caps
.InputReportByteLength
, (report
->bitSize
+ 7) / 8);
715 build_elements(report
, elem
, f
, &data
->caps
.NumberOutputDataIndices
);
716 count_elements(f
, &data
->caps
.NumberOutputButtonCaps
, &data
->caps
.NumberOutputValueCaps
);
717 data
->caps
.OutputReportByteLength
=
718 max(data
->caps
.OutputReportByteLength
, (report
->bitSize
+ 7) / 8);
721 build_elements(report
, elem
, f
, &data
->caps
.NumberFeatureDataIndices
);
722 count_elements(f
, &data
->caps
.NumberFeatureButtonCaps
, &data
->caps
.NumberFeatureValueCaps
);
723 data
->caps
.FeatureReportByteLength
=
724 max(data
->caps
.FeatureReportByteLength
, (report
->bitSize
+ 7) / 8);
731 nodes
[base
->index
].LinkUsagePage
= base
->caps
.UsagePage
;
732 nodes
[base
->index
].LinkUsage
= base
->caps
.NotRange
.Usage
;
733 nodes
[base
->index
].Parent
= base
->parent
== root
? 0 : base
->parent
->index
;
734 nodes
[base
->index
].CollectionType
= base
->type
;
735 nodes
[base
->index
].IsAlias
= 0;
737 if ((entry
= list_head(&base
->collections
)))
738 nodes
[base
->index
].FirstChild
= LIST_ENTRY(entry
, struct collection
, entry
)->index
;
741 LIST_FOR_EACH_ENTRY(c
, &base
->collections
, struct collection
, entry
)
743 preparse_collection(root
, c
, data
, ctx
);
745 if ((entry
= list_next(&base
->collections
, &c
->entry
)))
746 nodes
[c
->index
].NextSibling
= LIST_ENTRY(entry
, struct collection
, entry
)->index
;
747 if (root
!= base
) nodes
[base
->index
].NumberOfChildren
++;
751 static WINE_HIDP_PREPARSED_DATA
* build_PreparseData(struct collection
*base_collection
, unsigned int node_count
)
753 WINE_HIDP_PREPARSED_DATA
*data
;
754 unsigned int report_count
;
757 struct preparse_ctx ctx
;
758 unsigned int element_off
;
759 unsigned int nodes_offset
;
761 memset(&ctx
, 0, sizeof(ctx
));
762 create_preparse_ctx(base_collection
, &ctx
);
764 report_count
= ctx
.report_count
[HidP_Input
] + ctx
.report_count
[HidP_Output
]
765 + ctx
.report_count
[HidP_Feature
];
766 element_off
= FIELD_OFFSET(WINE_HIDP_PREPARSED_DATA
, reports
[report_count
]);
767 size
= element_off
+ (ctx
.elem_count
* sizeof(WINE_HID_ELEMENT
));
770 size
+= node_count
* sizeof(WINE_HID_LINK_COLLECTION_NODE
);
772 if (!(data
= calloc(1, size
))) return NULL
;
773 data
->magic
= HID_MAGIC
;
775 data
->caps
.Usage
= base_collection
->caps
.NotRange
.Usage
;
776 data
->caps
.UsagePage
= base_collection
->caps
.UsagePage
;
777 data
->caps
.NumberLinkCollectionNodes
= node_count
;
778 data
->elementOffset
= element_off
;
779 data
->nodesOffset
= nodes_offset
;
781 preparse_collection(base_collection
, base_collection
, data
, &ctx
);
785 static void free_collection(struct collection
*collection
)
787 struct feature
*fentry
, *fnext
;
788 struct collection
*centry
, *cnext
;
789 LIST_FOR_EACH_ENTRY_SAFE(centry
, cnext
, &collection
->collections
, struct collection
, entry
)
791 list_remove(¢ry
->entry
);
792 free_collection(centry
);
794 LIST_FOR_EACH_ENTRY_SAFE(fentry
, fnext
, &collection
->features
, struct feature
, entry
)
796 list_remove(&fentry
->entry
);
802 WINE_HIDP_PREPARSED_DATA
* ParseDescriptor(BYTE
*descriptor
, unsigned int length
)
804 WINE_HIDP_PREPARSED_DATA
*data
= NULL
;
805 struct hid_parser_state
*state
;
806 struct collection
*base
;
809 unsigned int feature_count
= 0;
814 TRACE("descriptor %p, length %u:\n", descriptor
, length
);
815 for (i
= 0; i
< length
;)
818 do { TRACE(" %02x", descriptor
[i
]); } while (++i
% 16 && i
< length
);
823 if (!(state
= calloc( 1, sizeof(*state
) ))) return NULL
;
824 if (!(base
= calloc( 1, sizeof(*base
) )))
830 list_init(&base
->features
);
831 list_init(&base
->collections
);
834 if (parse_descriptor( descriptor
, 0, length
, &feature_count
, &cidx
, base
, state
) < 0)
836 free_collection(base
);
837 free_parser_state( state
);
841 debug_collection(base
);
843 if ((data
= build_PreparseData(base
, cidx
)))
844 debug_print_preparsed(data
);
845 free_collection(base
);
847 free_parser_state( state
);